github.com/mfpierre/corectl@v0.5.6/load.go (about) 1 // Copyright 2015 - António Meireles <antonio.meireles@reformi.st> 2 // 3 // Licensed under the Apache License, Version 2.0 (the "License"); 4 // you may not use this file except in compliance with the License. 5 // You may obtain a copy of the License at 6 // 7 // http://www.apache.org/licenses/LICENSE-2.0 8 // 9 // Unless required by applicable law or agreed to in writing, software 10 // distributed under the License is distributed on an "AS IS" BASIS, 11 // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 12 // See the License for the specific language governing permissions and 13 // limitations under the License. 14 // 15 16 package main 17 18 import ( 19 "bytes" 20 "fmt" 21 "io/ioutil" 22 "reflect" 23 "sort" 24 "strings" 25 26 "github.com/spf13/cobra" 27 "github.com/spf13/pflag" 28 "github.com/spf13/viper" 29 ) 30 31 var ( 32 loadFCmd = &cobra.Command{ 33 Use: "load path/to/yourProfile", 34 Short: "Loads CoreOS instances defined in an instrumentation file.", 35 Long: "Loads CoreOS instances defined in an instrumentation file " + 36 "(either in TOML, JSON or YAML format).\n" + "VMs are always launched " + 37 "by alphabetical order relative to their names.", 38 PreRunE: func(cmd *cobra.Command, args []string) (err error) { 39 if len(args) != 1 { 40 return fmt.Errorf("Incorrect usage: " + 41 "This command requires one argument (a file path)") 42 } 43 engine.rawArgs.BindPFlags(cmd.Flags()) 44 return engine.allowedToRun() 45 }, 46 RunE: loadCommand, 47 Example: ` corectl load profiles/demo.toml`, 48 } 49 ) 50 51 func loadCommand(cmd *cobra.Command, args []string) (err error) { 52 var ( 53 vmDefs = make(map[string]*viper.Viper) 54 ordered []string 55 f []byte 56 def = args[0] 57 setup = viper.New() 58 ) 59 60 if f, err = ioutil.ReadFile(def); err != nil { 61 return 62 } 63 64 if strings.HasSuffix(def, ".toml") { 65 setup.SetConfigType("toml") 66 } else if strings.HasSuffix(def, ".json") { 67 setup.SetConfigType("json") 68 } else if strings.HasSuffix(def, ".yaml") || 69 strings.HasSuffix(def, ".yml") { 70 setup.SetConfigType("yaml") 71 } else { 72 return fmt.Errorf("%s unable to guess format via suffix", def) 73 } 74 75 if err = setup.ReadConfig(bytes.NewBuffer(f)); err != nil { 76 return 77 } 78 79 for name, def := range setup.AllSettings() { 80 if reflect.ValueOf(def).Kind() == reflect.Map { 81 lf := pflag.NewFlagSet(name, 0) 82 runFlagsDefaults(lf) 83 vmDefs[name] = viper.New() 84 vmDefs[name].BindPFlags(lf) 85 86 for x, xx := range setup.AllSettings() { 87 if reflect.ValueOf(x).Kind() != reflect.Map { 88 vmDefs[name].Set(x, xx) 89 } 90 } 91 for x, xx := range def.(map[string]interface{}) { 92 vmDefs[name].Set(x, xx) 93 } 94 vmDefs[name].Set("name", name) 95 vmDefs[name].Set("detached", true) 96 } 97 } 98 // (re)order alphabeticaly order to ensure cheap deterministic boot ordering 99 for name := range vmDefs { 100 ordered = append(ordered, name) 101 } 102 sort.Strings(ordered) 103 for slot, name := range ordered { 104 fmt.Println("> booting", name) 105 engine.VMs = append(engine.VMs, vmContext{}) 106 if err = engine.boot(slot, vmDefs[name]); err != nil { 107 return 108 } 109 } 110 return 111 } 112 113 func init() { 114 RootCmd.AddCommand(loadFCmd) 115 }