func cmdCreateOuter(c CommandLine, api libmachine.API) error { const ( flagLookupMachineName = "flag-lookup" ) // We didn't recognize the driver name. driverName := flagHackLookup("--driver") if driverName == "" { c.ShowHelp() return nil // ? } // TODO: Fix hacky JSON solution rawDriver, err := json.Marshal(&drivers.BaseDriver{ MachineName: flagLookupMachineName, }) if err != nil { return fmt.Errorf("Error attempting to marshal bare driver data: %s", err) } driver, err := api.NewPluginDriver(driverName, rawDriver) if err != nil { return fmt.Errorf("Error loading driver %q: %s", driverName, err) } if _, ok := driver.(*errdriver.Driver); ok { return errdriver.NotLoadable{Name: driverName} } // TODO: So much flag manipulation and voodoo here, it seems to be // asking for trouble. // // mcnFlags is the data we get back over the wire (type mcnflag.Flag) // to indicate which parameters are available. mcnFlags := driver.GetCreateFlags() // This bit will actually make "create" display the correct flags based // on the requested driver. cliFlags, err := convertMcnFlagsToCliFlags(mcnFlags) if err != nil { return fmt.Errorf("Error trying to convert provided driver flags to cli flags: %s", err) } for i := range c.Application().Commands { cmd := &c.Application().Commands[i] if cmd.HasName("create") { cmd = addDriverFlagsToCommand(cliFlags, cmd) } } if serialDriver, ok := driver.(*drivers.SerialDriver); ok { driver = serialDriver.Driver } return c.Application().Run(os.Args) }
func cmdCreateInner(c CommandLine, api libmachine.API) error { if len(c.Args()) > 1 { return fmt.Errorf("Invalid command line. Found extra arguments %v", c.Args()[1:]) } name := c.Args().First() if name == "" { c.ShowHelp() return errNoMachineName } validName := host.ValidateHostName(name) if !validName { return fmt.Errorf("Error creating machine: %s", mcnerror.ErrInvalidHostname) } if err := validateSwarmDiscovery(c.String("swarm-discovery")); err != nil { return fmt.Errorf("Error parsing swarm discovery: %s", err) } // TODO: Fix hacky JSON solution rawDriver, err := json.Marshal(&drivers.BaseDriver{ MachineName: name, StorePath: c.GlobalString("storage-path"), }) if err != nil { return fmt.Errorf("Error attempting to marshal bare driver data: %s", err) } driverName := c.String("driver") driver, err := api.NewPluginDriver(driverName, rawDriver) if err != nil { return fmt.Errorf("Error loading driver %q: %s", driverName, err) } h, err := api.NewHost(driver) if err != nil { return fmt.Errorf("Error getting new host: %s", err) } certInfo := getCertPathInfoFromCommandLine(c) h.HostOptions = &host.Options{ AuthOptions: &auth.Options{ 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), ServerCertSANs: c.StringSlice("tls-san"), }, EngineOptions: &engine.Options{ 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.Options{ 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 := api.Exists(h.Name) if err != nil { return fmt.Errorf("Error checking if host exists: %s", err) } if exists { return 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 { return fmt.Errorf("Error setting machine configuration from flags provided: %s", err) } if err := api.Create(h); err != nil { return fmt.Errorf("Error creating machine: %s", err) } if err := api.Save(h); err != nil { return fmt.Errorf("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)) return nil }