// newContainer creates a new container in Docker and stores it in the database. func newContainer(app provision.App, imageId string, cmds []string) (container, error) { contName := containerName() cont := container{ AppName: app.GetName(), Type: app.GetPlatform(), Name: contName, Status: "created", } coll := collection() defer coll.Close() if err := coll.Insert(cont); err != nil { log.Errorf("error on inserting container into database %s - %s", cont.Name, err) return container{}, err } port, err := getPort() if err != nil { log.Errorf("error on getting port for container %s - %s", cont.AppName, port) return container{}, err } user, _ := config.GetString("docker:ssh:user") exposedPorts := make(map[docker.Port]struct{}, 1) p := docker.Port(fmt.Sprintf("%s/tcp", port)) exposedPorts[p] = struct{}{} config := docker.Config{ Image: imageId, Cmd: cmds, User: user, ExposedPorts: exposedPorts, AttachStdin: false, AttachStdout: false, AttachStderr: false, } opts := dclient.CreateContainerOptions{Name: contName} hostID, c, err := dockerCluster().CreateContainer(opts, &config) if err == dclient.ErrNoSuchImage { var buf bytes.Buffer pullOpts := dclient.PullImageOptions{Repository: imageId} dockerCluster().PullImage(pullOpts, &buf) hostID, c, err = dockerCluster().CreateContainer(opts, &config) } if err != nil { log.Errorf("error on creating container in docker %s - %s", cont.AppName, err) return container{}, err } cont.ID = c.ID cont.Port = port cont.HostAddr = getHostAddr(hostID) err = coll.Update(bson.M{"name": cont.Name}, cont) if err != nil { log.Errorf("error on updating container into database %s - %s", cont.ID, err) return container{}, err } return cont, nil }
func (c *container) start() error { port, err := getPort() if err != nil { return err } config := docker.HostConfig{} bindings := make(map[docker.Port][]docker.PortBinding) bindings[docker.Port(fmt.Sprintf("%s/tcp", port))] = []docker.PortBinding{ { HostIp: "", HostPort: "", }, } config.PortBindings = bindings return dockerCluster().StartContainer(c.ID, &config) }
func (s *S) newContainer(opts *newContainerOpts) (*container, error) { appName := "container" if opts != nil { appName = opts.AppName } container := container{ AppName: appName, ID: "id", IP: "10.10.10.10", HostPort: "3333", Port: "8888", HostAddr: "127.0.0.1", } rtesting.FakeRouter.AddBackend(container.AppName) rtesting.FakeRouter.AddRoute(container.AppName, container.getAddress()) client, err := dockerClient.NewClient(s.server.URL()) if err != nil { return nil, err } port, err := getPort() if err != nil { return nil, err } ports := make(map[docker.Port]struct{}) ports[docker.Port(fmt.Sprintf("%s/tcp", port))] = struct{}{} config := docker.Config{ Image: "tsuru/python", Cmd: []string{"ps"}, ExposedPorts: ports, } c, err := client.CreateContainer(dockerClient.CreateContainerOptions{}, &config) if err != nil { return nil, err } container.ID = c.ID container.Image = "tsuru/python" conn, err := db.Conn() if err != nil { return nil, err } defer conn.Close() err = conn.Collection(s.collName).Insert(&container) if err != nil { return nil, err } return &container, err }
// networkInfo returns the IP and the host port for the container. func (c *container) networkInfo() (string, string, error) { if c.Port == "" { return "", "", errors.New("Container does not contain any mapped port") } dockerContainer, err := dockerCluster().InspectContainer(c.ID) if err != nil { return "", "", err } if dockerContainer.NetworkSettings != nil { ip := dockerContainer.NetworkSettings.IPAddress p := docker.Port(fmt.Sprintf("%s/tcp", c.Port)) for _, port := range dockerContainer.NetworkSettings.Ports[p] { if port.HostPort != "" && port.HostIp != "" { return ip, port.HostPort, nil } } } return "", "", fmt.Errorf("Container port %s is not mapped to any host port", c.Port) }
func startEchoServerContainer(t *testing.T, proto string) (*docker.Runtime, *docker.Container, string) { var ( err error id string strPort string eng = NewTestEngine(t) runtime = mkRuntimeFromEngine(eng, t) port = 5554 p docker.Port ) defer func() { if err != nil { runtime.Nuke() } }() for { port += 1 strPort = strconv.Itoa(port) var cmd string if proto == "tcp" { cmd = "socat TCP-LISTEN:" + strPort + ",reuseaddr,fork EXEC:/bin/cat" } else if proto == "udp" { cmd = "socat UDP-RECVFROM:" + strPort + ",fork EXEC:/bin/cat" } else { t.Fatal(fmt.Errorf("Unknown protocol %v", proto)) } ep := make(map[docker.Port]struct{}, 1) p = docker.Port(fmt.Sprintf("%s/%s", strPort, proto)) ep[p] = struct{}{} jobCreate := eng.Job("create") jobCreate.Setenv("Image", unitTestImageID) jobCreate.SetenvList("Cmd", []string{"sh", "-c", cmd}) jobCreate.SetenvList("PortSpecs", []string{fmt.Sprintf("%s/%s", strPort, proto)}) jobCreate.SetenvJson("ExposedPorts", ep) jobCreate.Stdout.AddString(&id) if err := jobCreate.Run(); err != nil { t.Fatal(err) } // FIXME: this relies on the undocumented behavior of runtime.Create // which will return a nil error AND container if the exposed ports // are invalid. That behavior should be fixed! if id != "" { break } t.Logf("Port %v already in use, trying another one", strPort) } jobStart := eng.Job("start", id) portBindings := make(map[docker.Port][]docker.PortBinding) portBindings[p] = []docker.PortBinding{ {}, } if err := jobStart.SetenvJson("PortsBindings", portBindings); err != nil { t.Fatal(err) } if err := jobStart.Run(); err != nil { t.Fatal(err) } container := runtime.Get(id) if container == nil { t.Fatalf("Couldn't fetch test container %s", id) } setTimeout(t, "Waiting for the container to be started timed out", 2*time.Second, func() { for !container.State.IsRunning() { time.Sleep(10 * time.Millisecond) } }) // Even if the state is running, lets give some time to lxc to spawn the process container.WaitTimeout(500 * time.Millisecond) strPort = container.NetworkSettings.Ports[p][0].HostPort return runtime, container, strPort }