diff --git a/cmd/list.go b/cmd/list.go index 127acfd..a6113e1 100644 --- a/cmd/list.go +++ b/cmd/list.go @@ -13,9 +13,8 @@ import ( ) -var gJails []Jail - - +// Recurse into structure, returning reflect.Value of wanted field. +// Nested fields are named with a dot (ex "MyStruct.MyField") func getStructField(parentStruct interface{}, fieldName string) (reflect.Value, string) { v := reflect.ValueOf(parentStruct) @@ -42,19 +41,10 @@ func getStructField(parentStruct interface{}, fieldName string) (reflect.Value, } } - if false { - if v.FieldByName(fieldName).IsValid() { - log.Println(fmt.Sprintf("%s value: %s", fieldName, v.FieldByName(fieldName).Interface())) - } else { - log.Println(fmt.Sprintf("%s is invalid", fieldName)) - } - } - return v, fieldName } - /* Pretty display of jails field Fields to show are given in a string array parameter Ex. : displayJails(["Name", "JID", "RootPath"]) @@ -152,8 +142,11 @@ func displayStructFields(jails []Jail, valsToDisplay []string) { if i == 0 { fmt.Printf("|") } + /* Use vlsToDisplay to get real name (with "Config.") fmt.Printf(" %s", f.Name) - for i := len(f.Name)+1 ; i < f.MaxLen+1 ; i++ { + for i := len(f.Name)+1 ; i < f.MaxLen+1 ; i++ { */ + fmt.Printf(" %s", valsToDisplay[i]) + for i := len(valsToDisplay[i])+1 ; i < f.MaxLen+1 ; i++ { fmt.Printf(" ") } fmt.Printf(" |") @@ -184,12 +177,31 @@ func displayStructFields(jails []Jail, valsToDisplay []string) { fmt.Printf("\n") } -func listJails(args []string) { + +/* Get Jails from datastores. Store config and running metadata into gJails global var */ +func listJails(args []string, display bool) { + fields := []string{"JID", "Name", "Config.Release", "Config.Ip4_addr", "RootPath", "Running", "Config.Jail_zfs", "Config.Jail_zfs_dataset"} + for _, d := range viper.GetStringSlice("datastore") { listJailsFromDatastore(d) } - displayStructFields(gJails, []string{"JID", "Name", "Config.Release", "Config.Ip4_addr", "RootPath"}) + if display { + if len(args) > 0 { + var js []Jail + for _, a := range args { + for _, j := range gJails { + if j.Name == a { + js = append(js, j) + break + } + } + } + displayStructFields(js, fields) + } else { + displayStructFields(gJails, fields) + } + } } diff --git a/cmd/root.go b/cmd/root.go index af03cb1..802fd4d 100644 --- a/cmd/root.go +++ b/cmd/root.go @@ -14,6 +14,10 @@ const ( ) var ( + gJails []Jail + + gUseSudo bool + gConfigFile string rootCmd = & cobra.Command{ @@ -39,9 +43,22 @@ It support iocage jails and can coexist with iocage.`, listCmd = &cobra.Command{ Use: "list", Short: "Print jails", - Long: `Display jails, their IP and OS`, + Long: `Display jails, their IP and OS. +Jail list can be restricted by adding name on command line +ex: gocage list srv-db srv-web`, Run: func(cmd *cobra.Command, args []string) { - listJails(args) + listJails(args, true) + }, + } + + stopCmd = &cobra.Command{ + Use: "stop", + Short: "stop jail", + Long: `shutdown jail`, + Run: func(cmd *cobra.Command, args []string) { + // Get the inventory + listJails(args, false) + stopJail(args) }, } ) @@ -52,7 +69,8 @@ func init() { cobra.OnInitialize(initConfig) // Global switches - rootCmd.PersistentFlags().StringVarP(&gConfigFile, "config", "c", "/etc/gocage/gocage.conf", "GoCage configuration file") + rootCmd.PersistentFlags().StringVarP(&gConfigFile, "config", "c", "/usr/local/etc/gocage.conf.yml", "GoCage configuration file") + rootCmd.PersistentFlags().BoolVarP(&gUseSudo, "sudo", "s", false, "Use sudo to run commands") // Command dependant switches /* listComputerCmd.PersistentFlags().BoolVarP(&gDisplayAsCSV, "csv-format", "v", false, "Show results in CSV (separator = ';')") @@ -63,12 +81,13 @@ func init() { // Now declare commands rootCmd.AddCommand(versionCmd) rootCmd.AddCommand(listCmd) + rootCmd.AddCommand(stopCmd) } func initConfig() { if gConfigFile == "" { fmt.Println("No config file!") - return + os.Exit(1) } // fmt.Printf("We are in initConfig(), with config file %s\n", gConfigFile) @@ -77,12 +96,13 @@ func initConfig() { if err := viper.ReadInConfig(); err != nil { fmt.Printf("ERROR reading config file %s : %s\n", gConfigFile, err.Error()) - return + os.Exit(1) } // fmt.Println("Using config file:", viper.ConfigFileUsed()) // fmt.Printf("datastore in config : %s\n", viper.GetStringSlice("datastore")) // fmt.Printf("datastore.0 in config : %s\n", viper.GetStringSlice("datastore.0")) + gUseSudo = viper.GetBool("sudo") } func Execute() {