Example #1
0
// 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
}
Example #2
0
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)
}
Example #3
0
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
}
Example #4
0
// 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)
}
Example #5
0
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
}