Beispiel #1
0
func CreateContainer(containerName, image, domain string, portsToMap []Port, environmentVars map[string]string) (*docker.Container, error) {
	cfg := &docker.Config{}
	cfg.Image = image
	cfg.Hostname = containerName
	cfg.Domainname = domain

	var e struct{}
	exposedPorts := make(map[docker.Port]struct{})
	for _, p := range portsToMap {
		prt := strconv.FormatUint(p.Private, 10) + "/" + p.Type
		exposedPorts[docker.Port(prt)] = e
		fmt.Printf("Exposing %s\n", prt)
	}
	cfg.ExposedPorts = exposedPorts

	envStrs := make([]string, 0, 10)
	for k, v := range environmentVars {
		envStrs = append(envStrs, k+"="+v)
	}
	cfg.Env = envStrs

	hostCfg := &docker.HostConfig{}
	hostCfg.PublishAllPorts = false
	hostCfg.Privileged = false

	hostPorts := make(map[docker.Port][]docker.PortBinding)
	for _, p := range portsToMap {
		prt := strconv.FormatUint(p.Private, 10) + "/" + p.Type
		bindings := make([]docker.PortBinding, 0, 4)
		bindings = append(bindings, docker.PortBinding{HostIP: "", HostPort: strconv.FormatUint(p.Public, 10)})
		fmt.Printf("Binding %s to %s\n", prt, bindings[0])
		hostPorts[docker.Port(prt)] = bindings
	}
	hostCfg.PortBindings = hostPorts

	opts := docker.CreateContainerOptions{}
	opts.Config = cfg
	opts.Name = containerName
	opts.HostConfig = hostCfg

	json, _ := data.PrettyPrint(opts)
	fmt.Printf("create options: %s\n", string(json))

	container, err := client.CreateContainer(opts)

	if err != nil {
		fmt.Fprintf(os.Stderr, "Error creating container: %s\n", err.Error())
	} else {
		fmt.Printf("Container created: %s\n", container.ID)
	}

	return container, err
}
// DockerRun perform a docker run
func DockerRun(req *DockerRunRequest) (DockerRunResponse, error) {
	response := DockerRunResponse{}
	//logit.Info.Println("DockerRun called")
	swarmURL := os.Getenv("SWARM_MANAGER_URL")
	if swarmURL == "" {
		logit.Error.Println("SWARM_MANAGER_URL not set")
		return response, errors.New("SWARM_MANAGER_URL not set")
	}

	var envvars []string
	var i = 0
	if req.EnvVars != nil {
		envvars = make([]string, len(req.EnvVars)+1)
		for k, v := range req.EnvVars {
			envvars[i] = k + "=" + v
			i++
		}
	} else {
		envvars = make([]string, 1)
	}

	if req.Profile == "" {
		return response, errors.New("Profile was empty and should not be")
	}

	//typical case is to always add the profile constraint env var
	//like SM, MED, LG, however in the case of a restore job, we
	//use a hard constraint of the host ipaddress to pin
	//the restored container to the same host as where the backup
	//is stored
	if req.IPAddress != "" {
		envvars[i] = "constraint:host==~" + req.IPAddress
	} else {
		envvars[i] = "constraint:profile==~" + req.Profile
	}

	docker, err := dockerapi.NewClient(swarmURL)
	if err != nil {
		logit.Error.Println(err.Error())
		return response, err
	}

	options := dockerapi.CreateContainerOptions{}
	config := dockerapi.Config{}
	config.Hostname = req.ContainerName
	options.Config = &config
	hostConfig := dockerapi.HostConfig{}
	options.HostConfig = &hostConfig
	options.Name = req.ContainerName
	options.Config.Env = envvars
	options.Config.Image = "crunchydata/" + req.Image
	//logit.Info.Println("swarmapi using " + options.Config.Image + " as the image name")
	options.Config.Volumes = make(map[string]struct{})

	//TODO figure out cpu shares and memory settings, these are different
	//than what I was using before due to me using the docker api directly
	//with this swarm implementation...use the defaults for now

	//options.HostConfig.CPUShares, err = strconv.ParseInt(req.CPU, 0, 64)
	//if err != nil {
	//logit.Error.Println(err.Error())
	//return response, err
	//}
	//options.HostConfig.Memory = req.MEM

	options.HostConfig.Binds = make([]string, 3)
	options.HostConfig.Binds[0] = req.PGDataPath + ":/pgdata"
	options.HostConfig.Binds[1] = "/var/cpm/data/keys:/keys"
	options.HostConfig.Binds[2] = "/var/cpm/config:/syslogconfig"

	container, err3 := docker.CreateContainer(options)
	if err3 != nil {
		logit.Error.Println(err3.Error())
		return response, err3
	}

	var startResponse DockerStartResponse
	startRequest := DockerStartRequest{}
	startRequest.ContainerName = req.ContainerName
	startResponse, err = DockerStart(&startRequest)
	if err != nil {
		logit.Error.Println(err.Error())
		return response, err
	}
	logit.Info.Println(startResponse.Output)
	//cmd := exec.Command(req.CommandPath, req.PGDataPath, req.ContainerName,
	//req.Image, req.CPU, req.MEM, allEnvVars)

	response.ID = container.ID
	return response, nil
}
Beispiel #3
0
//
// Start a docker container, and create a connection to /attach to it and send
// and receive RPC commands.
//
func (d *Client) Start() (err error) {

	path := os.Getenv("DOCKER_CERT_PATH")
	if path != "" {
		ca := fmt.Sprintf("%s/ca.pem", path)
		cert := fmt.Sprintf("%s/cert.pem", path)
		key := fmt.Sprintf("%s/key.pem", path)
		d.dockerClient, err = docker.NewTLSClient(d.endpoint, cert, key, ca)
	} else {
		d.dockerClient, err = docker.NewClient(d.endpoint)
	}

	if err != nil {
		return err
	}

	defaultConfig := &docker.Config{
		OpenStdin: true,
		Image:     d.dockerImage,
	}

	defaultHostConfig := &docker.HostConfig{}

	opts := docker.CreateContainerOptions{
		Config:     defaultConfig,
		HostConfig: defaultHostConfig,
	}

	if d.name != "" {
		opts.Name = d.name
	}

	c, err := d.dockerClient.CreateContainer(opts)

	if err != nil {
		return err
	}

	d.ID = c.ID
	err = d.dockerClient.StartContainer(c.ID, defaultHostConfig)

	if err != nil {
		return err
	}

	attachOpts := docker.AttachToContainerOptions{
		Container: d.ID,
		Stdout:    true,
		Stdin:     true,
		Stderr:    true,
		Stream:    true,
	}

	err = d.AttachStreamingContainer(attachOpts)

	if err != nil {
		return err
	}

	pipes := &dockerPipes{
		d.clientConn,
		&d.stdErrBuf,
		0,
		0,
	}

	d.rpcClient = rpc.NewClientWithCodec(jsonrpc.NewClientCodec(pipes))

	return nil
}