func ContainerDockerCfgs(c *types.Container) (*docker.Config, *docker.HostConfig) { // get env cfg envs := []string{ "ATLANTIS=true", fmt.Sprintf("CONTAINER_ID=%s", c.ID), fmt.Sprintf("CONTAINER_HOST=%s", c.Host), fmt.Sprintf("CONTAINER_ENV=%s", c.Env), fmt.Sprintf("HTTP_PORT=%d", c.PrimaryPort), fmt.Sprintf("SSHD_PORT=%d", c.SSHPort), } // get port cfg exposedPorts := map[docker.Port]struct{}{} portBindings := map[docker.Port][]docker.PortBinding{} sPrimaryPort := fmt.Sprintf("%d", c.PrimaryPort) dPrimaryPort := NewDockerPort(sPrimaryPort, "tcp") exposedPorts[dPrimaryPort] = struct{}{} portBindings[dPrimaryPort] = []docker.PortBinding{docker.PortBinding{ HostIP: "", HostPort: sPrimaryPort, }} sSSHPort := fmt.Sprintf("%d", c.SSHPort) dSSHPort := NewDockerPort(sSSHPort, "tcp") exposedPorts[dSSHPort] = struct{}{} portBindings[dSSHPort] = []docker.PortBinding{docker.PortBinding{ HostIP: "", HostPort: sSSHPort, }} for i, port := range c.SecondaryPorts { sPort := fmt.Sprintf("%d", port) dPort := NewDockerPort(sPort, "tcp") exposedPorts[dPort] = struct{}{} portBindings[dPort] = []docker.PortBinding{docker.PortBinding{ HostIP: "", HostPort: sPort, }} envs = append(envs, fmt.Sprintf("SECONDARY_PORT%d=%d", i, port)) } // setup actual cfg dCfg := &docker.Config{ Tty: true, // allocate pseudo-tty OpenStdin: true, // keep stdin open even if we're not attached CPUShares: int64(c.Manifest.CPUShares), Memory: int64(c.Manifest.MemoryLimit) * int64(1024*1024), // this is in bytes MemorySwap: int64(-1), // -1 turns swap off ExposedPorts: exposedPorts, Env: envs, Cmd: []string{ "runsvdir", "/etc/service", }, Image: fmt.Sprintf("%s/%s/%s-%s", RegistryHost, c.GetDockerRepo(), c.App, c.Sha), Volumes: map[string]struct{}{ ContainerLogDir: struct{}{}, atypes.ContainerConfigDir: struct{}{}, }, } dHostCfg := &docker.HostConfig{ PortBindings: portBindings, Binds: []string{ fmt.Sprintf("%s:%s", helper.HostLogDir(c.ID), ContainerLogDir), fmt.Sprintf("%s:%s", helper.HostConfigDir(c.ID), atypes.ContainerConfigDir), }, RestartPolicy: docker.AlwaysRestart(), // We added this so that we could reference the veth after it was created. However, docker no longer // uses lxc as the default driver (and neither do we) disable this configuration for now, investigate // later. // LxcConf: []docker.KeyValuePair{ // docker.KeyValuePair{ // Key: "lxc.network.veth.pair", // Value: "veth" + c.RandomID(), // }, // }, } return dCfg, dHostCfg }
func Deploy(c types.GenericContainer) error { dRepo := fmt.Sprintf("%s/%s/%s-%s", RegistryHost, c.GetDockerRepo(), c.GetApp(), c.GetSha()) // Pull docker container if pretending() { log.Printf("[%s][pretend] deploy with %s @ %s...", c.GetID(), c.GetApp(), c.GetSha()) log.Printf("[%s][pretend] docker pull %s", c.GetID(), dRepo) log.Printf("[%s][pretend] docker run %s", c.GetID(), dRepo) c.SetDockerID(fmt.Sprintf("pretend-docker-id-%s", c.GetID())) } else { log.Printf("[%s] deploy with %s @ %s...", c.GetID(), c.GetApp(), c.GetSha()) log.Printf("[%s] docker pull %s", c.GetID(), dRepo) dockerLock.Lock() err := dockerClient.PullImage(docker.PullImageOptions{Repository: dRepo}, docker.AuthConfiguration{}) dockerLock.Unlock() if err != nil { log.Printf("[%s] ERROR: failed to pull %s", c.GetID(), dRepo) return err } // make log dir for volume err = os.MkdirAll(helper.HostLogDir(c.GetID()), 0755) if err != nil { return err } // make config dir for volume err = os.MkdirAll(helper.HostConfigDir(c.GetID()), 0755) if err != nil { return err } // put config in config dir appCfg, err := AppCfgs(c) if err != nil { return err } if err := appCfg.Save(helper.HostConfigFile(c.GetID())); err != nil { RemoveConfigDir(c) return err } log.Printf("[%s] docker run %s", c.GetID(), dRepo) // create docker container dCfg, dHostCfg := DockerCfgs(c) dockerLock.Lock() dCont, err := dockerClient.CreateContainer(docker.CreateContainerOptions{Name: c.GetID(), Config: dCfg}) dockerLock.Unlock() if err != nil { log.Printf("[%s] ERROR: failed to create container: %s", c.GetID(), err.Error()) return err } c.SetDockerID(dCont.ID) // start docker container dockerLock.Lock() err = dockerClient.StartContainer(c.GetDockerID(), dHostCfg) dockerLock.Unlock() if err != nil { log.Printf("[%s] ERROR: failed to start container: %s", c.GetID(), err.Error()) log.Printf("[%s] -- full create response:\n%+v", c.GetID(), dCont) log.Printf("[%s] inspecting container for more information...", c.GetID()) dockerLock.Lock() inspCont, ierr := dockerClient.InspectContainer(c.GetDockerID()) dockerLock.Unlock() if ierr != nil { log.Printf("[%s] ERROR: failed to inspect container: %s", c.GetID(), ierr.Error()) return ierr } log.Printf("[%s] -- inspected container:\n%+v", c.GetID(), inspCont) return err } dockerLock.Lock() inspCont, err := dockerClient.InspectContainer(c.GetDockerID()) dockerLock.Unlock() if err != nil { log.Printf("[%s] ERROR: failed to inspect container: %s", c.GetID(), err.Error()) return err } if inspCont.NetworkSettings == nil { log.Printf("[%s] ERROR: failed to get container network settings.") return errors.New("Could not get NetworkSettings from docker") } c.SetIP(inspCont.NetworkSettings.IPAddress) c.SetPid(inspCont.State.Pid) } return nil }