func getDriverOpts(c *cli.Context, mcnflags []mcnflag.Flag) drivers.DriverOptions { // TODO: This function is pretty damn YOLO and would benefit from some // sanity checking around types and assertions. // // But, we need it so that we can actually send the flags for creating // a machine over the wire (cli.Context is a no go since there is so // much stuff in it). driverOpts := rpcdriver.RpcFlags{ Values: make(map[string]interface{}), } for _, f := range mcnflags { driverOpts.Values[f.String()] = f.Default() // Hardcoded logic for boolean... :( if f.Default() == nil { driverOpts.Values[f.String()] = false } } for _, name := range c.FlagNames() { getter, ok := c.Generic(name).(flag.Getter) if !ok { // TODO: This is pretty hacky. StringSlice is the only // type so far we have to worry about which is not a // Getter, though. driverOpts.Values[name] = c.StringSlice(name) continue } driverOpts.Values[name] = getter.Get() } return driverOpts }
func cmdCreateInner(c *cli.Context) { if len(c.Args()) > 1 { fatalf("Invalid command line. Found extra arguments %v", c.Args()[1:]) } name := c.Args().First() driverName := c.String("driver") certInfo := getCertPathInfoFromContext(c) storePath := c.GlobalString("storage-path") store := &persist.Filestore{ Path: storePath, CaCertPath: certInfo.CaCertPath, CaPrivateKeyPath: certInfo.CaPrivateKeyPath, } if name == "" { cli.ShowCommandHelp(c, "create") fatal("Error: No machine name specified.") } validName := host.ValidateHostName(name) if !validName { fatal("Error creating machine: ", mcnerror.ErrInvalidHostname) } if err := validateSwarmDiscovery(c.String("swarm-discovery")); err != nil { fatalf("Error parsing swarm discovery: %s", err) } // TODO: Fix hacky JSON solution bareDriverData, err := json.Marshal(&drivers.BaseDriver{ MachineName: name, StorePath: c.GlobalString("storage-path"), }) if err != nil { fatalf("Error attempting to marshal bare driver data: %s", err) } driver, err := newPluginDriver(driverName, bareDriverData) if err != nil { fatalf("Error loading driver %q: %s", driverName, err) } h, err := store.NewHost(driver) if err != nil { fatalf("Error getting new host: %s", err) } h.HostOptions = &host.HostOptions{ AuthOptions: &auth.AuthOptions{ CertDir: mcndirs.GetMachineCertDir(), CaCertPath: certInfo.CaCertPath, CaPrivateKeyPath: certInfo.CaPrivateKeyPath, ClientCertPath: certInfo.ClientCertPath, ClientKeyPath: certInfo.ClientKeyPath, ServerCertPath: filepath.Join(mcndirs.GetMachineDir(), name, "server.pem"), ServerKeyPath: filepath.Join(mcndirs.GetMachineDir(), name, "server-key.pem"), StorePath: filepath.Join(mcndirs.GetMachineDir(), name), }, EngineOptions: &engine.EngineOptions{ ArbitraryFlags: c.StringSlice("engine-opt"), Env: c.StringSlice("engine-env"), InsecureRegistry: c.StringSlice("engine-insecure-registry"), Labels: c.StringSlice("engine-label"), RegistryMirror: c.StringSlice("engine-registry-mirror"), StorageDriver: c.String("engine-storage-driver"), TlsVerify: true, InstallURL: c.String("engine-install-url"), }, SwarmOptions: &swarm.SwarmOptions{ IsSwarm: c.Bool("swarm"), Image: c.String("swarm-image"), Master: c.Bool("swarm-master"), Discovery: c.String("swarm-discovery"), Address: c.String("swarm-addr"), Host: c.String("swarm-host"), Strategy: c.String("swarm-strategy"), ArbitraryFlags: c.StringSlice("swarm-opt"), }, } exists, err := store.Exists(h.Name) if err != nil { fatalf("Error checking if host exists: %s", err) } if exists { fatal(mcnerror.ErrHostAlreadyExists{ Name: h.Name, }) } // driverOpts is the actual data we send over the wire to set the // driver parameters (an interface fulfilling drivers.DriverOptions, // concrete type rpcdriver.RpcFlags). mcnFlags := driver.GetCreateFlags() driverOpts := getDriverOpts(c, mcnFlags) if err := h.Driver.SetConfigFromFlags(driverOpts); err != nil { fatalf("Error setting machine configuration from flags provided: %s", err) } if err := libmachine.Create(store, h); err != nil { fatalf("Error creating machine: %s", err) } if err := saveHost(store, h); err != nil { fatalf("Error attempting to save store: %s", err) } log.Infof("To see how to connect Docker to this machine, run: %s", fmt.Sprintf("%s env %s", os.Args[0], name)) }
func cmdLs(c *cli.Context) { quiet := c.Bool("quiet") filters, err := parseFilters(c.StringSlice("filter")) if err != nil { fatal(err) } store := getStore(c) hostList, err := listHosts(store) if err != nil { fatal(err) } hostList = filterHosts(hostList, filters) // Just print out the names if we're being quiet if quiet { for _, host := range hostList { fmt.Println(host.Name) } return } swarmMasters := make(map[string]string) swarmInfo := make(map[string]string) w := tabwriter.NewWriter(os.Stdout, 5, 1, 3, ' ', 0) fmt.Fprintln(w, "NAME\tACTIVE\tDRIVER\tSTATE\tURL\tSWARM") for _, host := range hostList { swarmOptions := host.HostOptions.SwarmOptions if swarmOptions.Master { swarmMasters[swarmOptions.Discovery] = host.Name } if swarmOptions.Discovery != "" { swarmInfo[host.Name] = swarmOptions.Discovery } } items := getHostListItems(hostList) sortHostListItemsByName(items) for _, item := range items { activeString := "-" if item.Active { activeString = "*" } swarmInfo := "" if item.SwarmOptions.Discovery != "" { swarmInfo = swarmMasters[item.SwarmOptions.Discovery] if item.SwarmOptions.Master { swarmInfo = fmt.Sprintf("%s (master)", swarmInfo) } } fmt.Fprintf(w, "%s\t%s\t%s\t%s\t%s\t%s\n", item.Name, activeString, item.DriverName, item.State, item.URL, swarmInfo) } w.Flush() }