func fatalOnError(command func(commandLine CommandLine, api libmachine.API) error) func(context *cli.Context) { return func(context *cli.Context) { api := libmachine.NewClient(mcndirs.GetBaseDir(), mcndirs.GetMachineCertDir()) defer api.Close() if context.GlobalBool("native-ssh") { api.SSHClientType = ssh.Native } api.GithubAPIToken = context.GlobalString("github-api-token") api.Filestore.Path = context.GlobalString("storage-path") // TODO (nathanleclaire): These should ultimately be accessed // through the libmachine client by the rest of the code and // not through their respective modules. For now, however, // they are also being set the way that they originally were // set to preserve backwards compatibility. mcndirs.BaseDir = api.Filestore.Path mcnutils.GithubAPIToken = api.GithubAPIToken ssh.SetDefaultClient(api.SSHClientType) if err := command(&contextCommandLine{context}, api); err != nil { log.Fatal(err) if crashErr, ok := err.(crashreport.CrashError); ok { crashReporter := crashreport.NewCrashReporter(mcndirs.GetBaseDir(), context.GlobalString("bugsnag-api-token")) crashReporter.Send(crashErr) } } } }
func run() error { machineName := flag.String("machine", "default", "Docker machine name") addr := flag.String("addr", "localhost:2375", "Address of the proxy") help := flag.Bool("help", false, "Show help") flag.Parse() if *help { flag.Usage() return nil } api := libmachine.NewClient(mcndirs.GetBaseDir(), mcndirs.GetMachineCertDir()) defer api.Close() machine, err := api.Load(*machineName) if err != nil { return err } url, err := machine.URL() if err != nil { return err } return http.ListenAndServe(*addr, &proxy.DockerMachineProxy{ Machine: &mcn.DockerMachine{ Url: url, CertPath: filepath.Join(mcndirs.GetBaseDir(), "machines", *machineName), }, }) }
func NewHost(create bool, force bool) (*Host, error) { // Create a Virtualbox host if an existing host doesn't already exist. client := libmachine.NewClient(mcndirs.GetBaseDir()) existing, err := client.Load(DEFAULT_NAME) if err != nil { switch err.(type) { case mcnerror.ErrHostDoesNotExist: default: log.Fatal(err) } } if existing != nil && create && !force { return nil, errors.New("Host already exists.") } else if existing != nil && !create { log.Debug("Existing host found.") return &Host{ Host: existing, Client: client, }, nil } if create { driver := virtualbox.NewDriver(DEFAULT_NAME, mcndirs.GetBaseDir()) driver.CPU = DEFAULT_CPU driver.Memory = DEFAULT_MEMORY // Disable the '/Users' mount, we handle that ourselves via // `docker-unisync`. driver.NoShare = true data, err := json.Marshal(driver) if err != nil { log.Fatal(err) } pluginDriver, err := client.NewPluginDriver("virtualbox", data) if err != nil { log.Fatal(err) } h, err := client.NewHost(pluginDriver) if err != nil { log.Fatal(err) } if err := client.Create(h); err != nil { log.Fatal(err) } return &Host{ Host: h, Client: client, }, nil } return nil, errors.New(fmt.Sprintf("The %v host doesn't exist and create was not specified.", DEFAULT_NAME)) }
func noReportFileExist() bool { optOutFilePath := filepath.Join(mcndirs.GetBaseDir(), "no-error-report") if _, err := os.Stat(optOutFilePath); os.IsNotExist(err) { return false } return true }
func saveConfig(key string, value string) { api := &client{ targetSettingName: defaultConfigName, Filestore: persist.NewFilestore(mcndirs.GetBaseDir()), } conf := api.CreateNewConfig(defaultConfigName) conf.Set(key, value) api.Filestore.Save(conf) }
func WithApi(handler Handler, args map[string]string, form map[string][]string) func() (interface{}, error) { return func() (interface{}, error) { globalMutex.Lock() defer globalMutex.Unlock() api := libmachine.NewClient(mcndirs.GetBaseDir(), mcndirs.GetMachineCertDir()) defer api.Close() return handler.Handle(api, args, form) } }
func (provisioner *Boot2DockerProvisioner) upgradeIso() error { // TODO: Ideally, we should not read from mcndirs directory at all. // The driver should be able to communicate how and where to place the // relevant files. b2dutils := mcnutils.NewB2dUtils(mcndirs.GetBaseDir()) // Check if the driver has specified a custom b2d url jsonDriver, err := json.Marshal(provisioner.GetDriver()) if err != nil { return err } var d struct { Boot2DockerURL string } json.Unmarshal(jsonDriver, &d) log.Info("Downloading latest boot2docker iso...") // Usually we call this implicitly, but call it here explicitly to get // the latest default boot2docker ISO. if d.Boot2DockerURL == "" { if err := b2dutils.DownloadLatestBoot2Docker(d.Boot2DockerURL); err != nil { return err } } log.Info("Stopping machine to do the upgrade...") if err := provisioner.Driver.Stop(); err != nil { return err } if err := mcnutils.WaitFor(drivers.MachineInState(provisioner.Driver, state.Stopped)); err != nil { return err } machineName := provisioner.GetDriver().GetMachineName() log.Infof("Upgrading machine %q...", machineName) // Either download the latest version of the b2d url that was explicitly // specified when creating the VM or copy the (updated) default ISO if err := b2dutils.CopyIsoToMachineDir(d.Boot2DockerURL, machineName); err != nil { return err } log.Infof("Starting machine back up...") if err := provisioner.Driver.Start(); err != nil { return err } return mcnutils.WaitFor(drivers.MachineInState(provisioner.Driver, state.Running)) }
func (provisioner *RancherProvisioner) upgradeIso() error { // Largely copied from Boot2Docker provisioner, we should find a way to share this code log.Info("Stopping machine to do the upgrade...") if err := provisioner.Driver.Stop(); err != nil { return err } if err := mcnutils.WaitFor(drivers.MachineInState(provisioner.Driver, state.Stopped)); err != nil { return err } machineName := provisioner.GetDriver().GetMachineName() log.Infof("Upgrading machine %s...", machineName) // TODO: Ideally, we should not read from mcndirs directory at all. // The driver should be able to communicate how and where to place the // relevant files. b2dutils := mcnutils.NewB2dUtils(mcndirs.GetBaseDir()) url, err := provisioner.getLatestISOURL() if err != nil { return err } if err := b2dutils.DownloadISOFromURL(url); err != nil { return err } // Copy the latest version of boot2docker ISO to the machine's directory if err := b2dutils.CopyIsoToMachineDir("", machineName); err != nil { return err } log.Infof("Starting machine back up...") if err := provisioner.Driver.Start(); err != nil { return err } return mcnutils.WaitFor(drivers.MachineInState(provisioner.Driver, state.Running)) }
// findIP finds the IP address of a Docker Machine host given its name. func findIP(name string) (net.IP, error) { log.Println("Looking for virtualbox machine", name) api := libmachine.NewClient(mcndirs.GetBaseDir(), mcndirs.GetMachineCertDir()) defer api.Close() machine, err := api.Load(name) if err != nil { return nil, err } driver := machine.Driver.DriverName() ip, err := machine.Driver.GetIP() if err != nil { return nil, err } log.Printf("Found %s(%s) with IP %s\n", name, driver, ip) return net.ParseIP(ip), nil }
func (provisioner *Boot2DockerProvisioner) upgradeIso() error { log.Info("Stopping machine to do the upgrade...") if err := provisioner.Driver.Stop(); err != nil { return err } if err := mcnutils.WaitFor(drivers.MachineInState(provisioner.Driver, state.Stopped)); err != nil { return err } machineName := provisioner.GetDriver().GetMachineName() log.Infof("Upgrading machine %s...", machineName) // TODO: Ideally, we should not read from mcndirs directory at all. // The driver should be able to communicate how and where to place the // relevant files. b2dutils := mcnutils.NewB2dUtils("", "", mcndirs.GetBaseDir()) // Usually we call this implicitly, but call it here explicitly to get // the latest boot2docker ISO. if err := b2dutils.DownloadLatestBoot2Docker(); err != nil { return err } // Copy the latest version of boot2docker ISO to the machine's directory if err := b2dutils.CopyIsoToMachineDir("", machineName); err != nil { return err } log.Infof("Starting machine back up...") if err := provisioner.Driver.Start(); err != nil { return err } return mcnutils.WaitFor(drivers.MachineInState(provisioner.Driver, state.Running)) }
func (d *DockerMachineFsNotify) NotifyVm(event FsEvent) error { api := libmachine.NewClient(mcndirs.GetBaseDir(), mcndirs.GetMachineCertDir()) host, err := api.Load(d.DockerMachineName) if err != nil { return err } currentState, err := host.Driver.GetState() if err != nil { return err } if currentState != state.Running { return errors.New("Docker Machine " + host.Name + " is not running") } client, err := host.CreateSSHClient() if err != nil { return err } return client.Shell("touch -t " + event.ModTime.UTC().Format(touchTimeFormat) + " -m -c " + event.File) }
func main() { if os.Getenv(localbinary.PluginEnvKey) == localbinary.PluginEnvVal { driverName := os.Getenv(localbinary.PluginEnvDriverName) runDriver(driverName) return } localbinary.CurrentBinaryIsDockerMachine = true setDebugOutputLevel() cli.AppHelpTemplate = AppHelpTemplate cli.CommandHelpTemplate = CommandHelpTemplate app := cli.NewApp() app.Name = filepath.Base(os.Args[0]) app.Author = "Docker Machine Contributors" app.Email = "https://github.com/docker/machine" app.Commands = commands.Commands app.CommandNotFound = cmdNotFound app.Usage = "Create and manage machines running Docker." app.Version = version.FullVersion() log.Debug("Docker Machine Version: ", app.Version) app.Flags = []cli.Flag{ cli.BoolFlag{ Name: "debug, D", Usage: "Enable debug mode", }, cli.StringFlag{ EnvVar: "MACHINE_STORAGE_PATH", Name: "s, storage-path", Value: mcndirs.GetBaseDir(), Usage: "Configures storage path", }, cli.StringFlag{ EnvVar: "MACHINE_TLS_CA_CERT", Name: "tls-ca-cert", Usage: "CA to verify remotes against", Value: "", }, cli.StringFlag{ EnvVar: "MACHINE_TLS_CA_KEY", Name: "tls-ca-key", Usage: "Private key to generate certificates", Value: "", }, cli.StringFlag{ EnvVar: "MACHINE_TLS_CLIENT_CERT", Name: "tls-client-cert", Usage: "Client cert to use for TLS", Value: "", }, cli.StringFlag{ EnvVar: "MACHINE_TLS_CLIENT_KEY", Name: "tls-client-key", Usage: "Private key used in client TLS auth", Value: "", }, cli.StringFlag{ EnvVar: "MACHINE_GITHUB_API_TOKEN", Name: "github-api-token", Usage: "Token to use for requests to the Github API", Value: "", }, cli.BoolFlag{ EnvVar: "MACHINE_NATIVE_SSH", Name: "native-ssh", Usage: "Use the native (Go-based) SSH implementation.", }, cli.StringFlag{ EnvVar: "MACHINE_BUGSNAG_API_TOKEN", Name: "bugsnag-api-token", Usage: "BugSnag API token for crash reporting", Value: "", }, } if err := app.Run(os.Args); err != nil { log.Error(err) } }
func main() { setDebugOutputLevel() cli.AppHelpTemplate = AppHelpTemplate cli.CommandHelpTemplate = CommandHelpTemplate app := cli.NewApp() app.Name = path.Base(os.Args[0]) app.Author = "Docker Machine Contributors" app.Email = "https://github.com/docker/machine" app.Before = func(c *cli.Context) error { // TODO: Need better handling of config, everything is too // complected together right now. if c.GlobalBool("native-ssh") { ssh.SetDefaultClient(ssh.Native) } mcnutils.GithubApiToken = c.GlobalString("github-api-token") mcndirs.BaseDir = c.GlobalString("storage-path") return nil } app.Commands = commands.Commands app.CommandNotFound = cmdNotFound app.Usage = "Create and manage machines running Docker." app.Version = version.Version + " (" + version.GitCommit + ")" log.Debug("Docker Machine Version: ", app.Version) app.Flags = []cli.Flag{ cli.BoolFlag{ Name: "debug, D", Usage: "Enable debug mode", }, cli.StringFlag{ EnvVar: "MACHINE_STORAGE_PATH", Name: "s, storage-path", Value: mcndirs.GetBaseDir(), Usage: "Configures storage path", }, cli.StringFlag{ EnvVar: "MACHINE_TLS_CA_CERT", Name: "tls-ca-cert", Usage: "CA to verify remotes against", Value: "", }, cli.StringFlag{ EnvVar: "MACHINE_TLS_CA_KEY", Name: "tls-ca-key", Usage: "Private key to generate certificates", Value: "", }, cli.StringFlag{ EnvVar: "MACHINE_TLS_CLIENT_CERT", Name: "tls-client-cert", Usage: "Client cert to use for TLS", Value: "", }, cli.StringFlag{ EnvVar: "MACHINE_TLS_CLIENT_KEY", Name: "tls-client-key", Usage: "Private key used in client TLS auth", Value: "", }, cli.StringFlag{ EnvVar: "MACHINE_GITHUB_API_TOKEN", Name: "github-api-token", Usage: "Token to use for requests to the Github API", Value: "", }, cli.BoolFlag{ EnvVar: "MACHINE_NATIVE_SSH", Name: "native-ssh", Usage: "Use the native (Go-based) SSH implementation.", }, } go commands.DeferClosePluginServers() // Cleanup to run in case the user sends an interrupt (CTRL+C) to the // Machine program. Ensure that we do not leave dangling OS processes. signalCh := make(chan os.Signal, 1) signal.Notify(signalCh, os.Interrupt) // Atypical exit condition -- write to the cleanup done channel after // ensuring that we have closed all exec-ed plugin servers. go func() { for range signalCh { log.Info("\nReceieved an interrupt, performing cleanup work...") close(commands.RpcClientDriversCh) <-commands.RpcDriversClosedCh os.Exit(1) } }() // TODO: Close plugin servers in case of client panic. if err := app.Run(os.Args); err != nil { log.Error(err) } close(commands.RpcClientDriversCh) <-commands.RpcDriversClosedCh }
func main() { setDebugOutputLevel() cli.AppHelpTemplate = AppHelpTemplate cli.CommandHelpTemplate = CommandHelpTemplate app := cli.NewApp() app.Name = path.Base(os.Args[0]) app.Author = "Docker Machine Contributors" app.Email = "https://github.com/docker/machine" app.Before = func(c *cli.Context) error { // TODO: Need better handling of config, everything is too // complected together right now. if c.GlobalBool("native-ssh") { ssh.SetDefaultClient(ssh.Native) } mcnutils.GithubAPIToken = c.GlobalString("github-api-token") mcndirs.BaseDir = c.GlobalString("storage-path") return nil } app.Commands = commands.Commands app.CommandNotFound = cmdNotFound app.Usage = "Create and manage machines running Docker." app.Version = version.Version + " (" + version.GitCommit + ")" log.Debug("Docker Machine Version: ", app.Version) app.Flags = []cli.Flag{ cli.BoolFlag{ Name: "debug, D", Usage: "Enable debug mode", }, cli.StringFlag{ EnvVar: "MACHINE_STORAGE_PATH", Name: "s, storage-path", Value: mcndirs.GetBaseDir(), Usage: "Configures storage path", }, cli.StringFlag{ EnvVar: "MACHINE_TLS_CA_CERT", Name: "tls-ca-cert", Usage: "CA to verify remotes against", Value: "", }, cli.StringFlag{ EnvVar: "MACHINE_TLS_CA_KEY", Name: "tls-ca-key", Usage: "Private key to generate certificates", Value: "", }, cli.StringFlag{ EnvVar: "MACHINE_TLS_CLIENT_CERT", Name: "tls-client-cert", Usage: "Client cert to use for TLS", Value: "", }, cli.StringFlag{ EnvVar: "MACHINE_TLS_CLIENT_KEY", Name: "tls-client-key", Usage: "Private key used in client TLS auth", Value: "", }, cli.StringFlag{ EnvVar: "MACHINE_GITHUB_API_TOKEN", Name: "github-api-token", Usage: "Token to use for requests to the Github API", Value: "", }, cli.BoolFlag{ EnvVar: "MACHINE_NATIVE_SSH", Name: "native-ssh", Usage: "Use the native (Go-based) SSH implementation.", }, } // TODO: Close plugin servers in case of client panic. if err := app.Run(os.Args); err != nil { log.Error(err) } }
// NewClient create CliOptions instance func NewClient() API { return &client{ targetSettingName: defaultConfigName, Filestore: persist.NewFilestore(mcndirs.GetBaseDir()), } }
func createMachine(api libmachine.API, name string, driver string, form map[string][]string) error { validName := host.ValidateHostName(name) if !validName { return fmt.Errorf("Error creating machine: %s", mcnerror.ErrInvalidHostname) } exists, err := api.Exists(name) if err != nil { return fmt.Errorf("Error checking if host exists: %s", err) } if exists { return mcnerror.ErrHostAlreadyExists{ Name: name, } } rawDriver, err := json.Marshal(&drivers.BaseDriver{ MachineName: name, StorePath: mcndirs.GetBaseDir(), }) if err != nil { return fmt.Errorf("Error attempting to marshal bare driver data: %s", err) } h, err := api.NewHost(driver, rawDriver) if err != nil { return err } globalOpts := globalFlags{ flags: form, } h.HostOptions = &host.Options{ AuthOptions: &auth.Options{ CertDir: mcndirs.GetMachineCertDir(), CaCertPath: filepath.Join(mcndirs.GetMachineCertDir(), "ca.pem"), CaPrivateKeyPath: filepath.Join(mcndirs.GetMachineCertDir(), "ca-key.pem"), ClientCertPath: filepath.Join(mcndirs.GetMachineCertDir(), "cert.pem"), ClientKeyPath: filepath.Join(mcndirs.GetMachineCertDir(), "key.pem"), ServerCertPath: filepath.Join(mcndirs.GetMachineDir(), name, "server.pem"), ServerKeyPath: filepath.Join(mcndirs.GetMachineDir(), name, "server-key.pem"), StorePath: filepath.Join(mcndirs.GetMachineDir(), name), ServerCertSANs: globalOpts.StringSlice("tls-san"), }, EngineOptions: &engine.Options{ ArbitraryFlags: globalOpts.StringSlice("engine-opt"), Env: globalOpts.StringSlice("engine-env"), InsecureRegistry: globalOpts.StringSlice("engine-insecure-registry"), Labels: globalOpts.StringSlice("engine-label"), RegistryMirror: globalOpts.StringSlice("engine-registry-mirror"), StorageDriver: globalOpts.String("engine-storage-driver"), TLSVerify: true, InstallURL: globalOpts.String("engine-install-url"), }, SwarmOptions: &swarm.Options{ IsSwarm: globalOpts.Bool("swarm"), Image: globalOpts.String("swarm-image"), Master: globalOpts.Bool("swarm-master"), Discovery: globalOpts.String("swarm-discovery"), Address: globalOpts.String("swarm-addr"), Host: globalOpts.String("swarm-host"), Strategy: globalOpts.String("swarm-strategy"), ArbitraryFlags: globalOpts.StringSlice("swarm-opt"), IsExperimental: globalOpts.Bool("swarm-experimental"), }, } mcnFlags := h.Driver.GetCreateFlags() opts, err := parseFlags(form, mcnFlags, commands.SharedCreateFlags) if err != nil { return err } if err := h.Driver.SetConfigFromFlags(opts); err != nil { return fmt.Errorf("Error setting machine configuration from flags provided: %s", err) } if err := api.Create(h); err != nil { return err } if err := api.Save(h); err != nil { return fmt.Errorf("Error attempting to save store: %s", err) } return nil }