Beispiel #1
0
func TestStoreRemove(t *testing.T) {
	defer cleanup()

	store, err := getTestStore()
	if err != nil {
		t.Fatal(err)
	}

	host, err := getDefaultTestHost()
	if err != nil {
		t.Fatal(err)
	}

	if err := store.Save(host); err != nil {
		t.Fatal(err)
	}
	path := filepath.Join(utils.GetMachineDir(), host.Name)
	if _, err := os.Stat(path); os.IsNotExist(err) {
		t.Fatalf("Host path doesn't exist: %s", path)
	}
	err = store.Remove(host.Name, false)
	if err != nil {
		t.Fatal(err)
	}
	if _, err := os.Stat(path); err == nil {
		t.Fatalf("Host path still exists after remove: %s", path)
	}
}
Beispiel #2
0
func (c *Cluster) Create(name, driverName string, d *MachineOptions) (*Machine, error) {
	if _, ok := c.machines[name]; ok {
		return nil, fmt.Errorf("machine name '%s' exists, remove it first or provide another name.")
	}
	d.Options.Apply("engine-label", d.Options.String("engine-label")+" group="+d.Options.String("group"))

	if err := options.RefreshOptions(driverName, d.Options); err != nil {
		return nil, err
	}

	eo := getEngineOptions(d.Options)

	eopts := engine.EngineOptions(*eo)
	hostOptions := &libmachine.HostOptions{
		AuthOptions: &auth.AuthOptions{
			CaCertPath:     c.authOptions.CaCertPath,
			PrivateKeyPath: c.authOptions.CaKeyPath,
			ClientCertPath: c.authOptions.ClientCertPath,
			ClientKeyPath:  c.authOptions.ClientKeyPath,
			ServerCertPath: filepath.Join(utils.GetMachineDir(), name, "server.pem"),
			ServerKeyPath:  filepath.Join(utils.GetMachineDir(), name, "server-key.pem"),
		},
		EngineOptions: &eopts,
		SwarmOptions: &swarm.SwarmOptions{
			IsSwarm: false,
		},
	}

	host, err := c.provider.Create(name, driverName, hostOptions, d.Options)
	if err != nil {
		return nil, err
	}
	m := &Machine{
		Host:     host,
		StopTime: time.Now(),
	}
	c.Lock()
	m.setCachedState(state.Running)
	m.LoadIp()
	c.machines[name] = m
	c.Unlock()
	return m, nil
}
Beispiel #3
0
func (s Filestore) Exists(name string) (bool, error) {
	_, err := os.Stat(filepath.Join(utils.GetMachineDir(), name))

	if os.IsNotExist(err) {
		return false, nil
	} else if err == nil {
		return true, nil
	}

	return false, err
}
Beispiel #4
0
func getMachineConfig(c *cli.Context) (*machineConfig, error) {
	name := c.Args().First()
	certInfo := getCertPathInfo(c)
	defaultStore, err := getDefaultStore(
		c.GlobalString("storage-path"),
		certInfo.CaCertPath,
		certInfo.CaKeyPath,
	)
	if err != nil {
		log.Fatal(err)
	}

	provider, err := newProvider(defaultStore)
	if err != nil {
		log.Fatal(err)
	}

	m, err := provider.Get(name)
	if err != nil {
		return nil, err
	}

	machineDir := filepath.Join(utils.GetMachineDir(), m.Name)
	caCert := filepath.Join(machineDir, "ca.pem")
	caKey := filepath.Join(utils.GetMachineCertDir(), "ca-key.pem")
	clientCert := filepath.Join(machineDir, "cert.pem")
	clientKey := filepath.Join(machineDir, "key.pem")
	serverCert := filepath.Join(machineDir, "server.pem")
	serverKey := filepath.Join(machineDir, "server-key.pem")
	machineUrl, err := m.GetURL()
	if err != nil {
		if err == drivers.ErrHostIsNotRunning {
			machineUrl = ""
		} else {
			return nil, fmt.Errorf("Unexpected error getting machine url: %s", err)
		}
	}
	return &machineConfig{
		machineName:    name,
		machineDir:     machineDir,
		machineUrl:     machineUrl,
		clientKeyPath:  clientKey,
		clientCertPath: clientCert,
		serverCertPath: serverCert,
		caKeyPath:      caKey,
		caCertPath:     caCert,
		serverKeyPath:  serverKey,
		AuthOptions:    *m.HostOptions.AuthOptions,
		SwarmOptions:   *m.HostOptions.SwarmOptions,
	}, nil
}
func (s Filestore) loadHost(name string) (*Host, error) {
	hostPath := filepath.Join(utils.GetMachineDir(), name)
	if _, err := os.Stat(hostPath); os.IsNotExist(err) {
		return nil, ErrHostDoesNotExist
	}

	host := &Host{Name: name, StorePath: hostPath}
	if err := host.LoadConfig(); err != nil {
		return nil, err
	}

	h := validateHost(host)
	return h, nil
}
Beispiel #6
0
func NewHost(name, driverName string, hostOptions *HostOptions) (*Host, error) {
	authOptions := hostOptions.AuthOptions
	storePath := filepath.Join(utils.GetMachineDir(), name)
	driver, err := drivers.NewDriver(driverName, name, storePath, authOptions.CaCertPath, authOptions.PrivateKeyPath)
	if err != nil {
		return nil, err
	}
	return &Host{
		Name:        name,
		DriverName:  driverName,
		Driver:      driver,
		StorePath:   storePath,
		HostOptions: hostOptions,
	}, nil
}
Beispiel #7
0
func (m *Machine) Create(name string, driverName string, hostOptions *HostOptions, driverConfig drivers.DriverOptions) (*Host, error) {
	validName := ValidateHostName(name)
	if !validName {
		return nil, ErrInvalidHostname
	}
	exists, err := m.store.Exists(name)
	if err != nil {
		return nil, err
	}
	if exists {
		return nil, fmt.Errorf("Machine %s already exists", name)
	}

	hostPath := filepath.Join(utils.GetMachineDir(), name)

	host, err := NewHost(name, driverName, hostOptions)
	if err != nil {
		return host, err
	}
	if driverConfig != nil {
		if err := host.Driver.SetConfigFromFlags(driverConfig); err != nil {
			return host, err
		}
	}

	if err := host.Driver.PreCreateCheck(); err != nil {
		return nil, err
	}

	if err := os.MkdirAll(hostPath, 0700); err != nil {
		return nil, err
	}

	if err := host.SaveConfig(); err != nil {
		return host, err
	}

	if err := host.Create(name); err != nil {
		return host, err
	}

	if err := m.store.SetActive(host); err != nil {
		return nil, err
	}

	return host, nil
}
Beispiel #8
0
func (s Filestore) Save(host *Host) error {
	data, err := json.Marshal(host)
	if err != nil {
		return err
	}

	hostPath := filepath.Join(utils.GetMachineDir(), host.Name)

	if err := os.MkdirAll(hostPath, 0700); err != nil {
		return err
	}

	if err := ioutil.WriteFile(filepath.Join(hostPath, "config.json"), data, 0600); err != nil {
		return err
	}

	return nil
}
Beispiel #9
0
func (s Filestore) List() ([]*Host, error) {
	dir, err := ioutil.ReadDir(utils.GetMachineDir())
	if err != nil && !os.IsNotExist(err) {
		return nil, err
	}

	hosts := []*Host{}

	for _, file := range dir {
		// don't load hidden dirs; used for configs
		if file.IsDir() && strings.Index(file.Name(), ".") != 0 {
			host, err := s.Get(file.Name())
			if err != nil {
				log.Errorf("error loading host %q: %s", file.Name(), err)
				continue
			}
			hosts = append(hosts, host)
		}
	}
	return hosts, nil
}
Beispiel #10
0
func cmdCreate(c *cli.Context) {
	driver := c.String("driver")
	if driver != "aiyara" {
		cmdCreate0(c)
		return
	}

	baseName := c.Args().First()
	if baseName == "" {
		cli.ShowCommandHelp(c, "create")
		log.Fatal("You must specify a machine name")
	}

	certInfo := getCertPathInfo(c)

	if err := setupCertificates(
		certInfo.CaCertPath,
		certInfo.CaKeyPath,
		certInfo.ClientCertPath,
		certInfo.ClientKeyPath); err != nil {
		log.Fatalf("Error generating certificates: %s", err)
	}

	defaultStore, err := getDefaultStore(
		c.GlobalString("storage-path"),
		certInfo.CaCertPath,
		certInfo.CaKeyPath,
	)
	if err != nil {
		log.Fatal(err)
	}

	mcn, err := newMcn(defaultStore)
	if err != nil {
		log.Fatal(err)
	}

	ipPattern := c.String("aiyara-host-range")
	if ipPattern == "" {
		log.Fatal("Host range must be specified")
	}

	for _, ip := range generate(ipPattern) {
		parts := strings.Split(ip, ".")
		name := fmt.Sprintf("rack-%s-%s-%s", parts[2], baseName, parts[3])

		hostOptions := &libmachine.HostOptions{
			AuthOptions: &auth.AuthOptions{
				CaCertPath:     certInfo.CaCertPath,
				PrivateKeyPath: certInfo.CaKeyPath,
				ClientCertPath: certInfo.ClientCertPath,
				ClientKeyPath:  certInfo.ClientKeyPath,
				ServerCertPath: filepath.Join(utils.GetMachineDir(), name, "server.pem"),
				ServerKeyPath:  filepath.Join(utils.GetMachineDir(), name, "server-key.pem"),
			},
			EngineOptions: &engine.EngineOptions{},
			SwarmOptions: &swarm.SwarmOptions{
				IsSwarm:   c.Bool("swarm"),
				Master:    c.Bool("swarm-master"),
				Discovery: c.String("swarm-discovery"),
				Address:   c.String("swarm-addr"),
				Host:      c.String("swarm-host"),
			},
		}

		ext := map[string]string{"aiyara-host-ip": ip}
		_, err := mcn.Create(name, driver, hostOptions, &ExtensibleDriverOptions{c, ext})
		if err != nil {
			log.Errorf("Error creating machine: %s", err)
			log.Warn("You will want to check the provider to make sure the machine and associated resources were properly removed.")
			log.Fatal("Error creating machine")
		}

		info := ""
		userShell := filepath.Base(os.Getenv("SHELL"))

		switch userShell {
		case "fish":
			info = fmt.Sprintf("%s env %s | source", c.App.Name, name)
		default:
			info = fmt.Sprintf(`eval "$(%s env %s)"`, c.App.Name, name)
		}

		log.Infof("%q has been created and is now the active machine.", name)

		if info != "" {
			log.Infof("To point your Docker client at it, run this in your shell: %s", info)
		}

	} // for

}
Beispiel #11
0
func ConfigureAuth(p Provisioner) error {
	var (
		err error
	)

	machineName := p.GetDriver().GetMachineName()
	authOptions := p.GetAuthOptions()
	org := machineName
	bits := 2048

	ip, err := p.GetDriver().GetIP()
	if err != nil {
		return err
	}

	// copy certs to client dir for docker client
	machineDir := filepath.Join(utils.GetMachineDir(), machineName)

	if err := utils.CopyFile(authOptions.CaCertPath, filepath.Join(machineDir, "ca.pem")); err != nil {
		log.Fatalf("Error copying ca.pem to machine dir: %s", err)
	}

	if err := utils.CopyFile(authOptions.ClientCertPath, filepath.Join(machineDir, "cert.pem")); err != nil {
		log.Fatalf("Error copying cert.pem to machine dir: %s", err)
	}

	if err := utils.CopyFile(authOptions.ClientKeyPath, filepath.Join(machineDir, "key.pem")); err != nil {
		log.Fatalf("Error copying key.pem to machine dir: %s", err)
	}

	log.Debugf("generating server cert: %s ca-key=%s private-key=%s org=%s",
		authOptions.ServerCertPath,
		authOptions.CaCertPath,
		authOptions.PrivateKeyPath,
		org,
	)

	// TODO: Switch to passing just authOptions to this func
	// instead of all these individual fields
	err = utils.GenerateCert(
		[]string{ip},
		authOptions.ServerCertPath,
		authOptions.ServerKeyPath,
		authOptions.CaCertPath,
		authOptions.PrivateKeyPath,
		org,
		bits,
	)

	if err != nil {
		return fmt.Errorf("error generating server cert: %s", err)
	}

	if err := p.Service("docker", pkgaction.Stop); err != nil {
		return err
	}

	// upload certs and configure TLS auth
	caCert, err := ioutil.ReadFile(authOptions.CaCertPath)
	if err != nil {
		return err
	}

	serverCert, err := ioutil.ReadFile(authOptions.ServerCertPath)
	if err != nil {
		return err
	}
	serverKey, err := ioutil.ReadFile(authOptions.ServerKeyPath)
	if err != nil {
		return err
	}

	// printf will choke if we don't pass a format string because of the
	// dashes, so that's the reason for the '%%s'
	certTransferCmdFmt := "printf '%%s' '%s' | sudo tee %s"

	// These ones are for Jessie and Mike <3 <3 <3
	if _, err := p.SSHCommand(fmt.Sprintf(certTransferCmdFmt, string(caCert), authOptions.CaCertRemotePath)); err != nil {
		return err
	}

	if _, err := p.SSHCommand(fmt.Sprintf(certTransferCmdFmt, string(serverCert), authOptions.ServerCertRemotePath)); err != nil {
		return err
	}

	if _, err := p.SSHCommand(fmt.Sprintf(certTransferCmdFmt, string(serverKey), authOptions.ServerKeyRemotePath)); err != nil {
		return err
	}

	dockerUrl, err := p.GetDriver().GetURL()
	if err != nil {
		return err
	}
	u, err := url.Parse(dockerUrl)
	if err != nil {
		return err
	}
	dockerPort := 2376
	parts := strings.Split(u.Host, ":")
	if len(parts) == 2 {
		dPort, err := strconv.Atoi(parts[1])
		if err != nil {
			return err
		}
		dockerPort = dPort
	}

	dkrcfg, err := p.GenerateDockerOptions(dockerPort)
	if err != nil {
		return err
	}

	if _, err = p.SSHCommand(fmt.Sprintf("printf \"%s\" | sudo tee %s", dkrcfg.EngineOptions, dkrcfg.EngineOptionsPath)); err != nil {
		return err
	}

	if err := p.Service("docker", pkgaction.Start); err != nil {
		return err
	}

	// TODO: Do not hardcode daemon port, ask the driver
	if err := utils.WaitForDocker(ip, dockerPort); err != nil {
		return err
	}

	return nil
}
Beispiel #12
0
func (m *Machine) Create(name string, driverName string, options *HostOptions) (*Host, error) {
	driverOptions := options.DriverOptions
	engineOptions := options.EngineOptions
	swarmOptions := options.SwarmOptions

	exists, err := m.store.Exists(name)
	if err != nil {
		return nil, err
	}
	if exists {
		return nil, fmt.Errorf("Machine %s already exists", name)
	}

	hostPath := filepath.Join(utils.GetMachineDir(), name)

	caCert, err := m.store.GetCACertificatePath()
	if err != nil {
		return nil, err
	}

	privateKey, err := m.store.GetPrivateKeyPath()
	if err != nil {
		return nil, err
	}

	host, err := NewHost(name, driverName, hostPath, caCert, privateKey, engineOptions, swarmOptions)
	if err != nil {
		return host, err
	}
	if driverOptions != nil {
		if err := host.Driver.SetConfigFromFlags(driverOptions); err != nil {
			return host, err
		}
	}

	if err := host.Driver.PreCreateCheck(); err != nil {
		return nil, err
	}

	if err := os.MkdirAll(hostPath, 0700); err != nil {
		return nil, err
	}

	if err := host.SaveConfig(); err != nil {
		return host, err
	}

	if err := host.Create(name); err != nil {
		return host, err
	}

	if err := host.ConfigureAuth(); err != nil {
		return host, err
	}

	if swarmOptions.Host != "" {
		log.Info("Configuring Swarm...")

		discovery := swarmOptions.Discovery
		master := swarmOptions.Master
		swarmHost := swarmOptions.Host
		addr := swarmOptions.Address
		if err := host.ConfigureSwarm(discovery, master, swarmHost, addr); err != nil {
			log.Errorf("Error configuring Swarm: %s", err)
		}
	}

	if err := m.store.SetActive(host); err != nil {
		return nil, err
	}

	return host, nil
}
Beispiel #13
0
// activePath returns the path to the file that stores the name of the
// active host
func (s Filestore) activePath() string {
	return filepath.Join(utils.GetMachineDir(), ".active")
}
Beispiel #14
0
func ConfigureAuth(p Provisioner, authOptions auth.AuthOptions) error {
	var (
		err error
	)

	machineName := p.GetDriver().GetMachineName()
	org := machineName
	bits := 2048

	ip, err := p.GetDriver().GetIP()
	if err != nil {
		return err
	}

	// copy certs to client dir for docker client
	machineDir := filepath.Join(utils.GetMachineDir(), machineName)

	if err := utils.CopyFile(authOptions.CaCertPath, filepath.Join(machineDir, "ca.pem")); err != nil {
		log.Fatalf("Error copying ca.pem to machine dir: %s", err)
	}

	if err := utils.CopyFile(authOptions.ClientCertPath, filepath.Join(machineDir, "cert.pem")); err != nil {
		log.Fatalf("Error copying cert.pem to machine dir: %s", err)
	}

	if err := utils.CopyFile(authOptions.ClientKeyPath, filepath.Join(machineDir, "key.pem")); err != nil {
		log.Fatalf("Error copying key.pem to machine dir: %s", err)
	}

	log.Debugf("generating server cert: %s ca-key=%s private-key=%s org=%s",
		authOptions.ServerCertPath,
		authOptions.CaCertPath,
		authOptions.PrivateKeyPath,
		org,
	)

	// TODO: Switch to passing just authOptions to this func
	// instead of all these individual fields
	err = utils.GenerateCert(
		[]string{ip},
		authOptions.ServerCertPath,
		authOptions.ServerKeyPath,
		authOptions.CaCertPath,
		authOptions.PrivateKeyPath,
		org,
		bits,
	)
	if err != nil {
		return fmt.Errorf("error generating server cert: %s", err)
	}

	if err := p.Service("docker", pkgaction.Stop); err != nil {
		return err
	}

	dockerDir := p.GetDockerOptionsDir()

	cmd, err := p.SSHCommand(fmt.Sprintf("sudo mkdir -p %s", dockerDir))
	if err != nil {
		return err
	}
	if err := cmd.Run(); err != nil {
		return err
	}

	// upload certs and configure TLS auth
	caCert, err := ioutil.ReadFile(authOptions.CaCertPath)
	if err != nil {
		return err
	}

	// due to windows clients, we cannot use filepath.Join as the paths
	// will be mucked on the linux hosts
	machineCaCertPath := path.Join(dockerDir, "ca.pem")
	authOptions.CaCertRemotePath = machineCaCertPath

	serverCert, err := ioutil.ReadFile(authOptions.ServerCertPath)
	if err != nil {
		return err
	}
	machineServerCertPath := path.Join(dockerDir, "server.pem")
	authOptions.ServerCertRemotePath = machineServerCertPath

	serverKey, err := ioutil.ReadFile(authOptions.ServerKeyPath)
	if err != nil {
		return err
	}
	machineServerKeyPath := path.Join(dockerDir, "server-key.pem")
	authOptions.ServerKeyRemotePath = machineServerKeyPath

	cmd, err = p.SSHCommand(fmt.Sprintf("echo \"%s\" | sudo tee %s", string(caCert), machineCaCertPath))
	if err != nil {
		return err
	}
	if err := cmd.Run(); err != nil {
		return err
	}

	cmd, err = p.SSHCommand(fmt.Sprintf("echo \"%s\" | sudo tee %s", string(serverKey), machineServerKeyPath))
	if err != nil {
		return err
	}
	if err := cmd.Run(); err != nil {
		return err
	}

	cmd, err = p.SSHCommand(fmt.Sprintf("echo \"%s\" | sudo tee %s", string(serverCert), machineServerCertPath))
	if err != nil {
		return err
	}
	if err := cmd.Run(); err != nil {
		return err
	}

	dockerUrl, err := p.GetDriver().GetURL()
	if err != nil {
		return err
	}
	u, err := url.Parse(dockerUrl)
	if err != nil {
		return err
	}
	dockerPort := 2376
	parts := strings.Split(u.Host, ":")
	if len(parts) == 2 {
		dPort, err := strconv.Atoi(parts[1])
		if err != nil {
			return err
		}
		dockerPort = dPort
	}

	dkrcfg, err := p.GenerateDockerOptions(dockerPort, authOptions)
	if err != nil {
		return err
	}

	cmd, err = p.SSHCommand(fmt.Sprintf("echo \"%s\" | sudo tee -a %s", dkrcfg.EngineOptions, dkrcfg.EngineOptionsPath))
	if err != nil {
		return err
	}
	if err := cmd.Run(); err != nil {
		return err
	}

	if err := p.Service("docker", pkgaction.Start); err != nil {
		return err
	}

	return nil
}
Beispiel #15
0
func cmdCreate0(c *cli.Context) {
	var (
		err error
	)
	driver := c.String("driver")
	name := c.Args().First()

	// TODO: Not really a fan of "none" as the default driver...
	if driver != "none" {
		c.App.Commands, err = trimDriverFlags(driver, c.App.Commands)
		if err != nil {
			log.Fatal(err)
		}
	}

	if name == "" {
		cli.ShowCommandHelp(c, "create")
		log.Fatal("You must specify a machine name")
	}

	certInfo := getCertPathInfo(c)

	if err := setupCertificates(
		certInfo.CaCertPath,
		certInfo.CaKeyPath,
		certInfo.ClientCertPath,
		certInfo.ClientKeyPath); err != nil {
		log.Fatalf("Error generating certificates: %s", err)
	}

	defaultStore, err := getDefaultStore(
		c.GlobalString("storage-path"),
		certInfo.CaCertPath,
		certInfo.CaKeyPath,
	)
	if err != nil {
		log.Fatal(err)
	}

	mcn, err := newMcn(defaultStore)
	if err != nil {
		log.Fatal(err)
	}

	hostOptions := &libmachine.HostOptions{
		AuthOptions: &auth.AuthOptions{
			CaCertPath:     certInfo.CaCertPath,
			PrivateKeyPath: certInfo.CaKeyPath,
			ClientCertPath: certInfo.ClientCertPath,
			ClientKeyPath:  certInfo.ClientKeyPath,
			ServerCertPath: filepath.Join(utils.GetMachineDir(), name, "server.pem"),
			ServerKeyPath:  filepath.Join(utils.GetMachineDir(), name, "server-key.pem"),
		},
		EngineOptions: &engine.EngineOptions{},
		SwarmOptions: &swarm.SwarmOptions{
			IsSwarm:   c.Bool("swarm"),
			Master:    c.Bool("swarm-master"),
			Discovery: c.String("swarm-discovery"),
			Address:   c.String("swarm-addr"),
			Host:      c.String("swarm-host"),
		},
	}

	host, err := mcn.Create(name, driver, hostOptions, c)
	if err != nil {
		log.Errorf("Error creating machine: %s", err)
		log.Warn("You will want to check the provider to make sure the machine and associated resources were properly removed.")
		log.Fatal("Error creating machine")
	}
	if err := mcn.SetActive(host); err != nil {
		log.Fatalf("error setting active host: %v", err)
	}

	info := ""
	userShell := filepath.Base(os.Getenv("SHELL"))

	switch userShell {
	case "fish":
		info = fmt.Sprintf("%s env %s | source", c.App.Name, name)
	default:
		info = fmt.Sprintf(`eval "$(%s env %s)"`, c.App.Name, name)
	}

	log.Infof("%q has been created and is now the active machine.", name)

	if info != "" {
		log.Infof("To point your Docker client at it, run this in your shell: %s", info)
	}
}
Beispiel #16
0
func cmdCreate(c *cli.Context) {
	var (
		err error
	)
	driver := c.String("driver")
	name := c.Args().First()

	// TODO: Not really a fan of "none" as the default driver...
	if driver != "none" {
		c.App.Commands, err = trimDriverFlags(driver, c.App.Commands)
		if err != nil {
			log.Fatal(err)
		}
	}

	if name == "" {
		cli.ShowCommandHelp(c, "create")
		log.Fatal("You must specify a machine name")
	}

	if err := validateSwarmDiscovery(c.String("swarm-discovery")); err != nil {
		log.Fatalf("Error parsing swarm discovery: %s", err)
	}

	certInfo := getCertPathInfo(c)

	if err := setupCertificates(
		certInfo.CaCertPath,
		certInfo.CaKeyPath,
		certInfo.ClientCertPath,
		certInfo.ClientKeyPath); err != nil {
		log.Fatalf("Error generating certificates: %s", err)
	}

	defaultStore, err := getDefaultStore(
		c.GlobalString("storage-path"),
		certInfo.CaCertPath,
		certInfo.CaKeyPath,
	)
	if err != nil {
		log.Fatal(err)
	}

	provider, err := newProvider(defaultStore)
	if err != nil {
		log.Fatal(err)
	}

	hostOptions := &libmachine.HostOptions{
		AuthOptions: &auth.AuthOptions{
			CaCertPath:     certInfo.CaCertPath,
			PrivateKeyPath: certInfo.CaKeyPath,
			ClientCertPath: certInfo.ClientCertPath,
			ClientKeyPath:  certInfo.ClientKeyPath,
			ServerCertPath: filepath.Join(utils.GetMachineDir(), name, "server.pem"),
			ServerKeyPath:  filepath.Join(utils.GetMachineDir(), name, "server-key.pem"),
		},
		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"),
		},
	}

	_, err = provider.Create(name, driver, hostOptions, c)
	if err != nil {
		log.Errorf("Error creating machine: %s", err)
		log.Fatal("You will want to check the provider to make sure the machine and associated resources were properly removed.")
	}

	info := fmt.Sprintf("%s env %s", c.App.Name, name)
	log.Infof("To see how to connect Docker to this machine, run: %s", info)
}
Beispiel #17
0
func (s Filestore) Remove(name string, force bool) error {
	hostPath := filepath.Join(utils.GetMachineDir(), name)
	return os.RemoveAll(hostPath)
}
Beispiel #18
0
func (h *Host) ConfigureAuth() error {
	d := h.Driver

	if d.DriverName() == "none" {
		return nil
	}

	// copy certs to client dir for docker client
	machineDir := filepath.Join(utils.GetMachineDir(), h.Name)
	if err := utils.CopyFile(h.CaCertPath, filepath.Join(machineDir, "ca.pem")); err != nil {
		log.Fatalf("Error copying ca.pem to machine dir: %s", err)
	}

	clientCertPath := filepath.Join(utils.GetMachineCertDir(), "cert.pem")
	if err := utils.CopyFile(clientCertPath, filepath.Join(machineDir, "cert.pem")); err != nil {
		log.Fatalf("Error copying cert.pem to machine dir: %s", err)
	}

	clientKeyPath := filepath.Join(utils.GetMachineCertDir(), "key.pem")
	if err := utils.CopyFile(clientKeyPath, filepath.Join(machineDir, "key.pem")); err != nil {
		log.Fatalf("Error copying key.pem to machine dir: %s", err)
	}

	var (
		ip         = ""
		ipErr      error
		maxRetries = 4
	)

	for i := 0; i < maxRetries; i++ {
		ip, ipErr = h.Driver.GetIP()
		if ip != "" {
			break
		}
		log.Debugf("waiting for ip: %s", ipErr)
		time.Sleep(5 * time.Second)
	}

	if ipErr != nil {
		return ipErr
	}

	if ip == "" {
		return fmt.Errorf("unable to get machine IP")
	}

	serverCertPath := filepath.Join(h.StorePath, "server.pem")
	serverKeyPath := filepath.Join(h.StorePath, "server-key.pem")

	org := h.Name
	bits := 2048

	log.Debugf("generating server cert: %s ca-key=%s private-key=%s org=%s",
		serverCertPath,
		h.CaCertPath,
		h.PrivateKeyPath,
		org,
	)

	if err := utils.GenerateCert([]string{ip}, serverCertPath, serverKeyPath, h.CaCertPath, h.PrivateKeyPath, org, bits); err != nil {
		return fmt.Errorf("error generating server cert: %s", err)
	}

	if err := h.StopDocker(); err != nil {
		return err
	}

	dockerDir, err := h.GetDockerConfigDir()
	if err != nil {
		return err
	}

	cmd, err := h.GetSSHCommand(fmt.Sprintf("sudo mkdir -p %s", dockerDir))
	if err != nil {
		return err
	}
	if err := cmd.Run(); err != nil {
		return err
	}

	// upload certs and configure TLS auth
	caCert, err := ioutil.ReadFile(h.CaCertPath)
	if err != nil {
		return err
	}

	// due to windows clients, we cannot use filepath.Join as the paths
	// will be mucked on the linux hosts
	machineCaCertPath := path.Join(dockerDir, "ca.pem")

	serverCert, err := ioutil.ReadFile(serverCertPath)
	if err != nil {
		return err
	}
	machineServerCertPath := path.Join(dockerDir, "server.pem")

	serverKey, err := ioutil.ReadFile(serverKeyPath)
	if err != nil {
		return err
	}
	machineServerKeyPath := path.Join(dockerDir, "server-key.pem")

	cmd, err = h.GetSSHCommand(fmt.Sprintf("echo \"%s\" | sudo tee %s", string(caCert), machineCaCertPath))
	if err != nil {
		return err
	}
	if err := cmd.Run(); err != nil {
		return err
	}

	cmd, err = h.GetSSHCommand(fmt.Sprintf("echo \"%s\" | sudo tee %s", string(serverKey), machineServerKeyPath))
	if err != nil {
		return err
	}
	if err := cmd.Run(); err != nil {
		return err
	}

	cmd, err = h.GetSSHCommand(fmt.Sprintf("echo \"%s\" | sudo tee %s", string(serverCert), machineServerCertPath))
	if err != nil {
		return err
	}
	if err := cmd.Run(); err != nil {
		return err
	}

	dockerUrl, err := h.Driver.GetURL()
	if err != nil {
		return err
	}
	u, err := url.Parse(dockerUrl)
	if err != nil {
		return err
	}
	dockerPort := 2376
	parts := strings.Split(u.Host, ":")
	if len(parts) == 2 {
		dPort, err := strconv.Atoi(parts[1])
		if err != nil {
			return err
		}
		dockerPort = dPort
	}

	cfg, err := h.generateDockerConfig(dockerPort, machineCaCertPath, machineServerKeyPath, machineServerCertPath)
	if err != nil {
		return err
	}

	cmd, err = h.GetSSHCommand(fmt.Sprintf("echo \"%s\" | sudo tee -a %s", cfg.EngineConfig, cfg.EngineConfigPath))
	if err != nil {
		return err
	}
	if err := cmd.Run(); err != nil {
		return err
	}

	if err := h.StartDocker(); err != nil {
		return err
	}

	return nil
}