Add root check and prettier tables
This commit is contained in:
parent
010d78a1cc
commit
d404c25219
1 changed files with 93 additions and 5 deletions
100
main.go
100
main.go
|
|
@ -54,6 +54,13 @@ var osImages = map[string]OSImage{
|
|||
},
|
||||
}
|
||||
|
||||
func requireRoot() {
|
||||
if os.Geteuid() != 0 {
|
||||
fmt.Fprintln(os.Stderr, "mnmivm must be run as root. Try: `sudo mnmivm` or login as the root user")
|
||||
os.Exit(1)
|
||||
}
|
||||
}
|
||||
|
||||
func ensureDirs() {
|
||||
for _, d := range []string{imageDir, vmDirBase} {
|
||||
if err := os.MkdirAll(d, 0755); err != nil {
|
||||
|
|
@ -176,6 +183,64 @@ disable_root: true
|
|||
}
|
||||
}
|
||||
|
||||
func renderBoxTable(headers []string, rows [][]string) {
|
||||
colWidths := make([]int, len(headers))
|
||||
|
||||
// compute column widths
|
||||
for i, h := range headers {
|
||||
colWidths[i] = len(h)
|
||||
}
|
||||
for _, row := range rows {
|
||||
for i, cell := range row {
|
||||
if len(cell) > colWidths[i] {
|
||||
colWidths[i] = len(cell)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// helpers
|
||||
repeat := func(s string, n int) string {
|
||||
return strings.Repeat(s, n)
|
||||
}
|
||||
|
||||
drawRow := func(left, mid, right string) {
|
||||
fmt.Print(left)
|
||||
for i, w := range colWidths {
|
||||
fmt.Print(repeat("─", w+2))
|
||||
if i < len(colWidths)-1 {
|
||||
fmt.Print(mid)
|
||||
}
|
||||
}
|
||||
fmt.Println(right)
|
||||
}
|
||||
|
||||
// top border
|
||||
drawRow("┌", "┬", "┐")
|
||||
|
||||
// header row
|
||||
fmt.Print("│")
|
||||
for i, h := range headers {
|
||||
fmt.Printf(" %-*s │", colWidths[i], h)
|
||||
}
|
||||
fmt.Println()
|
||||
|
||||
// header separator
|
||||
drawRow("├", "┼", "┤")
|
||||
|
||||
// data rows
|
||||
for _, row := range rows {
|
||||
fmt.Print("│")
|
||||
for i, cell := range row {
|
||||
fmt.Printf(" %-*s │", colWidths[i], cell)
|
||||
}
|
||||
fmt.Println()
|
||||
}
|
||||
|
||||
// bottom border
|
||||
drawRow("└", "┴", "┘")
|
||||
}
|
||||
|
||||
|
||||
func createVM(name, osName, pubKeyPath string) {
|
||||
if _, ok := osImages[osName]; !ok {
|
||||
panic("unsupported OS: " + osName)
|
||||
|
|
@ -298,9 +363,16 @@ func vmRunning(name string) bool {
|
|||
func listVMs() {
|
||||
entries, _ := os.ReadDir(vmDirBase)
|
||||
|
||||
fmt.Printf("%-12s %-8s %-8s %-16s %-16s %s\n",
|
||||
"NAME", "STATE", "OS", "SSH", "VNC", "PUBKEY")
|
||||
fmt.Println(strings.Repeat("-", 90))
|
||||
headers := []string{
|
||||
"NAME",
|
||||
"STATE",
|
||||
"OS",
|
||||
"SSH",
|
||||
"VNC",
|
||||
"PUBKEY",
|
||||
}
|
||||
|
||||
rows := [][]string{}
|
||||
|
||||
for _, e := range entries {
|
||||
name := e.Name()
|
||||
|
|
@ -312,6 +384,7 @@ func listVMs() {
|
|||
}
|
||||
|
||||
osName := readFileTrim(filepath.Join(dir, "os.name"))
|
||||
|
||||
sshPort := readFileTrim(filepath.Join(dir, "ssh.port"))
|
||||
vncPort := readFileTrim(filepath.Join(dir, "vnc.port"))
|
||||
|
||||
|
|
@ -325,12 +398,27 @@ func listVMs() {
|
|||
vnc = "0.0.0.0:" + vncPort
|
||||
}
|
||||
|
||||
fmt.Printf("%-12s %-8s %-8s %-16s %-16s %s\n",
|
||||
name, state, osName, ssh, vnc, vmPubKeyPath(name))
|
||||
}
|
||||
rows = append(rows, []string{
|
||||
name,
|
||||
state,
|
||||
osName,
|
||||
ssh,
|
||||
vnc,
|
||||
vmPubKeyPath(name),
|
||||
})
|
||||
}
|
||||
|
||||
if len(rows) == 0 {
|
||||
fmt.Println("No VMs found.")
|
||||
return
|
||||
}
|
||||
|
||||
renderBoxTable(headers, rows)
|
||||
}
|
||||
|
||||
|
||||
func main() {
|
||||
requireRoot()
|
||||
if len(os.Args) < 2 {
|
||||
usage()
|
||||
}
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue