<commit_before>// Copyright 2016 tsuru-client authors. All rights reserved.
// Use of this source code is governed by a BSD-style
// license that can be found in the LICENSE file.

package installer

import (
	"encoding/json"
	"fmt"
	"os/exec"

	"github.com/docker/machine/drivers/amazonec2"
	"github.com/docker/machine/drivers/azure"
	"github.com/docker/machine/drivers/digitalocean"
	"github.com/docker/machine/drivers/exoscale"
	"github.com/docker/machine/drivers/generic"
	"github.com/docker/machine/drivers/google"
	"github.com/docker/machine/drivers/hyperv"
	"github.com/docker/machine/drivers/none"
	"github.com/docker/machine/drivers/openstack"
	"github.com/docker/machine/drivers/rackspace"
	"github.com/docker/machine/drivers/softlayer"
	"github.com/docker/machine/drivers/virtualbox"
	"github.com/docker/machine/drivers/vmwarefusion"
	"github.com/docker/machine/drivers/vmwarevcloudair"
	"github.com/docker/machine/drivers/vmwarevsphere"
	"github.com/docker/machine/libmachine"
	"github.com/docker/machine/libmachine/drivers"
	"github.com/docker/machine/libmachine/drivers/plugin"
	"github.com/docker/machine/libmachine/drivers/rpc"
	"github.com/docker/machine/libmachine/host"
	"github.com/fsouza/go-dockerclient"
	"github.com/tsuru/config"
)

var (
	dockerHTTPPort  = 2375
	dockerHTTPSPort = 2376
)

type Machine struct {
	IP      string
	Config  map[string]string
	TLS     bool
	Address string
}

func (m *Machine) dockerClient() (*docker.Client, error) {
	if m.TLS {
		return docker.NewTLSClient(m.Address, "cert.pem", "key.pem", "ca.pem")
	}
	return docker.NewClient(m.Address)
}

type DockerMachine struct {
	driverOpts map[string]interface{}
	rawDriver  []byte
	driverName string
	storePath  string
	certsPath  string
	tlsSupport bool
}

func NewDockerMachine() (*DockerMachine, error) {
	driverName, err := config.GetString("driver:name")
	if err != nil {
		return nil, err
	}
	driverOpts := make(map[string]interface{})
	opts, _ := config.Get("driver:options")
	if opts != nil {
		for k, v := range opts.(map[interface{}]interface{}) {
			switch k := k.(type) {
			case string:
				driverOpts[k] = v
			}
		}
	}
	storePath := "/tmp/automatic"
	certsPath := "/tmp/automatic/certs"
	rawDriver, err := json.Marshal(&drivers.BaseDriver{
		MachineName: "tsuru",
		StorePath:   storePath,
	})
	if err != nil {
		return nil, fmt.Errorf("Error creating docker-machine driver: %s", err)
	}

	dm := &DockerMachine{
		driverOpts: driverOpts,
		rawDriver:  rawDriver,
		driverName: driverName,
		storePath:  storePath,
		certsPath:  certsPath,
		tlsSupport: driverName != "virtualbox" && driverName != "none",
		Name:       "tsuru",
	}
	return dm, nil
}

func (d *DockerMachine) CreateMachine() (*Machine, error) {
	client := libmachine.NewClient(d.storePath, d.certsPath)
	defer client.Close()
	host, err := client.NewHost(d.driverName, d.rawDriver)
	if err != nil {
		return nil, err
	}
	configureDriver(host.Driver, d.driverOpts)
	d.configureHost(host)
	err = client.Create(host)
	if err != nil {
		fmt.Printf("Ignoring error on machine creation: %s", err)
	}
	ip, err := host.Driver.GetIP()
	if err != nil {
		return nil, err
	}
	config := map[string]string{}
	m := Machine{
		IP:     ip,
		Config: config,
		TLS:    d.tlsSupport,
	}
	if m.TLS {
		m.Address = fmt.Sprintf("https://%s:%d", m.IP, dockerHTTPSPort)
	} else {
		m.Address = fmt.Sprintf("http://%s:%d", m.IP, dockerHTTPPort)
	}
	return &m, nil
}

func (d *DockerMachine) CreateRegistryCertificate() error {
	client := libmachine.NewClient(d.storePath, d.certsPath)
	defer client.Close()
	host, err := client.Load(d.Name)
	if err != nil {
		return err
	}
	ip, err := host.Driver.GetIP()
	if err != nil {
		return err
	}
	_, err = host.RunSSHCommand("mkdir -p /home/docker/certs")
	if err != nil {
		return err
	}
	scp := exec.Cmd{
		Args: []string{
			"scp",
			"-i",
			fmt.Sprintf("%s/machines/%s/id_rsa", d.storePath, d.Name),
			fmt.Sprintf("%s/*", d.certsPath),
			fmt.Sprintf("docker@%s:/home/docker/certs/", ip),
		},
	}
	err = scp.Run()
	if err != nil {
		return err
	}
	// generate keys with http://docker-saigon.github.io/post/Private-Registry-Setup/
	_, err = host.RunSSHCommand(fmt.Sprintf("openssl req -new -x509 -extensions v3_ca -key /home/docker/.docker/key.pem -out /home/docker/.docker/ca.crt -days 3650 -subj '/CN=%s'", ip))
	return err
}

func configureDriver(driver drivers.Driver, driverOpts map[string]interface{}) error {
	opts := &rpcdriver.RPCFlags{Values: driverOpts}
	for _, c := range driver.GetCreateFlags() {
		_, ok := opts.Values[c.String()]
		if ok == false {
			opts.Values[c.String()] = c.Default()
			if c.Default() == nil {
				opts.Values[c.String()] = false
			}
		}
	}
	if err := driver.SetConfigFromFlags(opts); err != nil {
		return fmt.Errorf("Error setting driver configurations: %s", err)
	}
	return nil
}

func (d *DockerMachine) configureHost(host *host.Host) {
	if d.tlsSupport == false {
		host.HostOptions.EngineOptions.Env = []string{"DOCKER_TLS=no"}
		host.HostOptions.EngineOptions.ArbitraryFlags = []string{fmt.Sprintf("host=tcp://0.0.0.0:%d", dockerHTTPPort)}
	}
}

func (d *DockerMachine) DeleteMachine(m *Machine) error {
	client := libmachine.NewClient(d.storePath, d.certsPath)
	defer client.Close()
	h, err := client.Load("tsuru")
	if err != nil {
		return err
	}
	err = h.Driver.Remove()
	if err != nil {
		return err
	}
	return client.Remove("tsuru")
}

func RunDriver(driverName string) error {
	switch driverName {
	case "amazonec2":
		plugin.RegisterDriver(amazonec2.NewDriver("", ""))
	case "azure":
		plugin.RegisterDriver(azure.NewDriver("", ""))
	case "digitalocean":
		plugin.RegisterDriver(digitalocean.NewDriver("", ""))
	case "exoscale":
		plugin.RegisterDriver(exoscale.NewDriver("", ""))
	case "generic":
		plugin.RegisterDriver(generic.NewDriver("", ""))
	case "google":
		plugin.RegisterDriver(google.NewDriver("", ""))
	case "hyperv":
		plugin.RegisterDriver(hyperv.NewDriver("", ""))
	case "none":
		plugin.RegisterDriver(none.NewDriver("", ""))
	case "openstack":
		plugin.RegisterDriver(openstack.NewDriver("", ""))
	case "rackspace":
		plugin.RegisterDriver(rackspace.NewDriver("", ""))
	case "softlayer":
		plugin.RegisterDriver(softlayer.NewDriver("", ""))
	case "virtualbox":
		plugin.RegisterDriver(virtualbox.NewDriver("", ""))
	case "vmwarefusion":
		plugin.RegisterDriver(vmwarefusion.NewDriver("", ""))
	case "vmwarevcloudair":
		plugin.RegisterDriver(vmwarevcloudair.NewDriver("", ""))
	case "vmwarevsphere":
		plugin.RegisterDriver(vmwarevsphere.NewDriver("", ""))
	default:
		return fmt.Errorf("Unsupported driver: %s\n", driverName)
	}
	return nil
}
<commit_msg>fix certificate creation to registry.<commit_after>// Copyright 2016 tsuru-client authors. All rights reserved.
// Use of this source code is governed by a BSD-style
// license that can be found in the LICENSE file.

package installer

import (
	"encoding/json"
	"fmt"
	"os/exec"

	"github.com/docker/machine/drivers/amazonec2"
	"github.com/docker/machine/drivers/azure"
	"github.com/docker/machine/drivers/digitalocean"
	"github.com/docker/machine/drivers/exoscale"
	"github.com/docker/machine/drivers/generic"
	"github.com/docker/machine/drivers/google"
	"github.com/docker/machine/drivers/hyperv"
	"github.com/docker/machine/drivers/none"
	"github.com/docker/machine/drivers/openstack"
	"github.com/docker/machine/drivers/rackspace"
	"github.com/docker/machine/drivers/softlayer"
	"github.com/docker/machine/drivers/virtualbox"
	"github.com/docker/machine/drivers/vmwarefusion"
	"github.com/docker/machine/drivers/vmwarevcloudair"
	"github.com/docker/machine/drivers/vmwarevsphere"
	"github.com/docker/machine/libmachine"
	"github.com/docker/machine/libmachine/drivers"
	"github.com/docker/machine/libmachine/drivers/plugin"
	"github.com/docker/machine/libmachine/drivers/rpc"
	"github.com/docker/machine/libmachine/host"
	"github.com/fsouza/go-dockerclient"
	"github.com/tsuru/config"
)

var (
	dockerHTTPPort  = 2375
	dockerHTTPSPort = 2376
)

type Machine struct {
	IP      string
	Config  map[string]string
	TLS     bool
	Address string
}

func (m *Machine) dockerClient() (*docker.Client, error) {
	if m.TLS {
		return docker.NewTLSClient(m.Address, "cert.pem", "key.pem", "ca.pem")
	}
	return docker.NewClient(m.Address)
}

type DockerMachine struct {
	driverOpts map[string]interface{}
	rawDriver  []byte
	driverName string
	storePath  string
	certsPath  string
	tlsSupport bool
	Name       string
}

func NewDockerMachine() (*DockerMachine, error) {
	driverName, err := config.GetString("driver:name")
	if err != nil {
		return nil, err
	}
	driverOpts := make(map[string]interface{})
	opts, _ := config.Get("driver:options")
	if opts != nil {
		for k, v := range opts.(map[interface{}]interface{}) {
			switch k := k.(type) {
			case string:
				driverOpts[k] = v
			}
		}
	}
	storePath := "/tmp/automatic"
	certsPath := "/tmp/automatic/certs"
	rawDriver, err := json.Marshal(&drivers.BaseDriver{
		MachineName: "tsuru",
		StorePath:   storePath,
	})
	if err != nil {
		return nil, fmt.Errorf("Error creating docker-machine driver: %s", err)
	}

	dm := &DockerMachine{
		driverOpts: driverOpts,
		rawDriver:  rawDriver,
		driverName: driverName,
		storePath:  storePath,
		certsPath:  certsPath,
		tlsSupport: driverName != "virtualbox" && driverName != "none",
		Name:       "tsuru",
	}
	return dm, nil
}

func (d *DockerMachine) CreateMachine() (*Machine, error) {
	client := libmachine.NewClient(d.storePath, d.certsPath)
	defer client.Close()
	host, err := client.NewHost(d.driverName, d.rawDriver)
	if err != nil {
		return nil, err
	}
	configureDriver(host.Driver, d.driverOpts)
	d.configureHost(host)
	err = client.Create(host)
	if err != nil {
		fmt.Printf("Ignoring error on machine creation: %s", err)
	}
	ip, err := host.Driver.GetIP()
	if err != nil {
		return nil, err
	}
	config := map[string]string{}
	m := Machine{
		IP:     ip,
		Config: config,
		TLS:    d.tlsSupport,
	}
	if m.TLS {
		m.Address = fmt.Sprintf("https://%s:%d", m.IP, dockerHTTPSPort)
	} else {
		m.Address = fmt.Sprintf("http://%s:%d", m.IP, dockerHTTPPort)
	}
	return &m, nil
}

func (d *DockerMachine) CreateRegistryCertificate() error {
	client := libmachine.NewClient(d.storePath, d.certsPath)
	defer client.Close()
	host, err := client.Load(d.Name)
	if err != nil {
		return err
	}
	ip, err := host.Driver.GetIP()
	if err != nil {
		return err
	}
	args := []string{
		"-o StrictHostKeyChecking=no",
		"-i",
		fmt.Sprintf("%s/machines/%s/id_rsa", d.storePath, d.Name),
		"-r",
		fmt.Sprintf("%s/", d.certsPath),
		fmt.Sprintf("docker@%s:/home/docker/", ip),
	}
	comm := exec.Command("scp", args...)
	stdout, err := comm.CombinedOutput()
	if err != nil {
		return fmt.Errorf("Command: %s. Error:%s", string(stdout), err.Error())
	}
	registryCAConf := fmt.Sprintf(`
[req]
req_extensions = v3_req
distinguished_name = req_distinguished_name
[req_distinguished_name]
[ v3_req ]
basicConstraints = CA:FALSE
keyUsage = nonRepudiation, digitalSignature, keyEncipherment
subjectAltName = @alt_names
[alt_names]
DNS.1 = %s.localdomain
DNS.2 = %s
IP.1 = %s
	`, d.Name, d.Name, ip)

	certsBasePath := "/home/docker/certs"
	_, err = host.RunSSHCommand(fmt.Sprintf("openssl genrsa -out %s/registry-key.pem 2048", certsBasePath))
	if err != nil {
		return err
	}
	registryCAConfPath := "/home/docker/certs/registry_ca.conf"
	_, err = host.RunSSHCommand(fmt.Sprintf("echo -e '%s' >> %s", registryCAConf, registryCAConfPath))
	if err != nil {
		return err
	}
	_, err = host.RunSSHCommand(fmt.Sprintf("openssl req -new -key %s/registry-key.pem -out %s/registry.csr -subj '/CN=%s.localdomain' -config %s", certsBasePath, certsBasePath, d.Name, registryCAConfPath))
	if err != nil {
		return err
	}
	_, err = host.RunSSHCommand(fmt.Sprintf("openssl x509 -req -in %s/registry.csr -CA '%s/ca.pem' -CAkey '%s/ca-key.pem' -CAcreateserial -out '%s/registry.pem' -days 365 -extensions v3_req -extfile %s", certsBasePath, certsBasePath, certsBasePath, certsBasePath, registryCAConfPath))
	if err != nil {
		return err
	}
	_, err = host.RunSSHCommand(fmt.Sprintf("sudo mkdir -p /var/lib/boot2docker/certs/"))
	if err != nil {
		return err
	}
	_, err = host.RunSSHCommand(fmt.Sprintf("sudo cp %s/ca.pem /var/lib/boot2docker/certs/", certsBasePath))
	return err
}

func configureDriver(driver drivers.Driver, driverOpts map[string]interface{}) error {
	opts := &rpcdriver.RPCFlags{Values: driverOpts}
	for _, c := range driver.GetCreateFlags() {
		_, ok := opts.Values[c.String()]
		if ok == false {
			opts.Values[c.String()] = c.Default()
			if c.Default() == nil {
				opts.Values[c.String()] = false
			}
		}
	}
	if err := driver.SetConfigFromFlags(opts); err != nil {
		return fmt.Errorf("Error setting driver configurations: %s", err)
	}
	return nil
}

func (d *DockerMachine) configureHost(host *host.Host) {
	if d.tlsSupport == false {
		host.HostOptions.EngineOptions.Env = []string{"DOCKER_TLS=no"}
		host.HostOptions.EngineOptions.ArbitraryFlags = []string{fmt.Sprintf("host=tcp://0.0.0.0:%d", dockerHTTPPort)}
	}
}

func (d *DockerMachine) DeleteMachine(m *Machine) error {
	client := libmachine.NewClient(d.storePath, d.certsPath)
	defer client.Close()
	h, err := client.Load("tsuru")
	if err != nil {
		return err
	}
	err = h.Driver.Remove()
	if err != nil {
		return err
	}
	return client.Remove("tsuru")
}

func RunDriver(driverName string) error {
	switch driverName {
	case "amazonec2":
		plugin.RegisterDriver(amazonec2.NewDriver("", ""))
	case "azure":
		plugin.RegisterDriver(azure.NewDriver("", ""))
	case "digitalocean":
		plugin.RegisterDriver(digitalocean.NewDriver("", ""))
	case "exoscale":
		plugin.RegisterDriver(exoscale.NewDriver("", ""))
	case "generic":
		plugin.RegisterDriver(generic.NewDriver("", ""))
	case "google":
		plugin.RegisterDriver(google.NewDriver("", ""))
	case "hyperv":
		plugin.RegisterDriver(hyperv.NewDriver("", ""))
	case "none":
		plugin.RegisterDriver(none.NewDriver("", ""))
	case "openstack":
		plugin.RegisterDriver(openstack.NewDriver("", ""))
	case "rackspace":
		plugin.RegisterDriver(rackspace.NewDriver("", ""))
	case "softlayer":
		plugin.RegisterDriver(softlayer.NewDriver("", ""))
	case "virtualbox":
		plugin.RegisterDriver(virtualbox.NewDriver("", ""))
	case "vmwarefusion":
		plugin.RegisterDriver(vmwarefusion.NewDriver("", ""))
	case "vmwarevcloudair":
		plugin.RegisterDriver(vmwarevcloudair.NewDriver("", ""))
	case "vmwarevsphere":
		plugin.RegisterDriver(vmwarevsphere.NewDriver("", ""))
	default:
		return fmt.Errorf("Unsupported driver: %s\n", driverName)
	}
	return nil
}

{'fraction_non_alphanumeric': 0.15958762886597938, 'fraction_numerical': 0.004398625429553264, 'mean_word_length': 4.40728353771832, 'pattern_counts': {'":': 30, '<': 3, '<?xml version=': 0, '>': 5, 'https://': 2, 'lorem ipsum': 0, 'www.': 0, 'xml': 0}, 'pii_count': 2, 'substrings_counts': 0, 'word_list_counts': {'cursed_substrings.json': 0, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'dir': 'git-commits-cleaned', 'id': '6938510', 'n_tokens_mistral': 5579, 'n_tokens_neox': 5262, 'n_words': 1030}