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() {
|
func ensureDirs() {
|
||||||
for _, d := range []string{imageDir, vmDirBase} {
|
for _, d := range []string{imageDir, vmDirBase} {
|
||||||
if err := os.MkdirAll(d, 0755); err != nil {
|
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) {
|
func createVM(name, osName, pubKeyPath string) {
|
||||||
if _, ok := osImages[osName]; !ok {
|
if _, ok := osImages[osName]; !ok {
|
||||||
panic("unsupported OS: " + osName)
|
panic("unsupported OS: " + osName)
|
||||||
|
|
@ -298,9 +363,16 @@ func vmRunning(name string) bool {
|
||||||
func listVMs() {
|
func listVMs() {
|
||||||
entries, _ := os.ReadDir(vmDirBase)
|
entries, _ := os.ReadDir(vmDirBase)
|
||||||
|
|
||||||
fmt.Printf("%-12s %-8s %-8s %-16s %-16s %s\n",
|
headers := []string{
|
||||||
"NAME", "STATE", "OS", "SSH", "VNC", "PUBKEY")
|
"NAME",
|
||||||
fmt.Println(strings.Repeat("-", 90))
|
"STATE",
|
||||||
|
"OS",
|
||||||
|
"SSH",
|
||||||
|
"VNC",
|
||||||
|
"PUBKEY",
|
||||||
|
}
|
||||||
|
|
||||||
|
rows := [][]string{}
|
||||||
|
|
||||||
for _, e := range entries {
|
for _, e := range entries {
|
||||||
name := e.Name()
|
name := e.Name()
|
||||||
|
|
@ -312,6 +384,7 @@ func listVMs() {
|
||||||
}
|
}
|
||||||
|
|
||||||
osName := readFileTrim(filepath.Join(dir, "os.name"))
|
osName := readFileTrim(filepath.Join(dir, "os.name"))
|
||||||
|
|
||||||
sshPort := readFileTrim(filepath.Join(dir, "ssh.port"))
|
sshPort := readFileTrim(filepath.Join(dir, "ssh.port"))
|
||||||
vncPort := readFileTrim(filepath.Join(dir, "vnc.port"))
|
vncPort := readFileTrim(filepath.Join(dir, "vnc.port"))
|
||||||
|
|
||||||
|
|
@ -325,12 +398,27 @@ func listVMs() {
|
||||||
vnc = "0.0.0.0:" + vncPort
|
vnc = "0.0.0.0:" + vncPort
|
||||||
}
|
}
|
||||||
|
|
||||||
fmt.Printf("%-12s %-8s %-8s %-16s %-16s %s\n",
|
rows = append(rows, []string{
|
||||||
name, state, osName, ssh, vnc, vmPubKeyPath(name))
|
name,
|
||||||
}
|
state,
|
||||||
|
osName,
|
||||||
|
ssh,
|
||||||
|
vnc,
|
||||||
|
vmPubKeyPath(name),
|
||||||
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if len(rows) == 0 {
|
||||||
|
fmt.Println("No VMs found.")
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
renderBoxTable(headers, rows)
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
func main() {
|
func main() {
|
||||||
|
requireRoot()
|
||||||
if len(os.Args) < 2 {
|
if len(os.Args) < 2 {
|
||||||
usage()
|
usage()
|
||||||
}
|
}
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue