Exemple #1
0
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)
			}
		}
	}
}
Exemple #2
0
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),
		},
	})
}
Exemple #3
0
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)
	}
}
Exemple #7
0
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))
}
Exemple #9
0
// 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)
}
Exemple #12
0
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)
	}
}
Exemple #13
0
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
}
Exemple #14
0
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
}