Example #1
0
// AttachToContainers attaches to all containers that specified to be running
func (client *DockerClient) AttachToContainers(containers []*Container) error {
	running := []*Container{}
	for _, c := range containers {
		if c.State.Running {
			running = append(running, c)
		}
	}

	// Listen to events of all containers and re-attach if necessary
	go client.listenReAttach(containers)

	wg := util.NewErrorWaitGroup(len(running))

	for _, container := range running {
		if container.Io == nil {
			if err := client.AttachToContainer(container); err != nil {
				return err
			}
		}

		go func(container *Container) {
			wg.Done(container.Io.Wait())
		}(container)
	}

	return wg.Wait()
}
Example #2
0
// FetchImages fetches the missing images for all containers in the manifest
func (client *DockerClient) FetchImages(containers []*Container) error {
	type message struct {
		container *Container
		result    chan error
	}

	wg := util.NewErrorWaitGroup(len(containers))
	chPullImages := make(chan message)
	done := make(chan struct{}, 1)
	checkedImages := map[string]struct{}{}

	// Pull worker
	// We do not want to pull images in parallel
	// instead, we use an actor to pull images sequentially
	//
	// TODO: WAAAT? we can simplify it by going though a list of images sequentially
	// 			 and pull those images which are missing.
	go func() {
		for {
			select {
			case msg := <-chPullImages:
				msg.result <- client.pullImageForContainer(msg.container)
			case <-done:
				return
			}
		}
	}()

	defer func() {
		done <- struct{}{}
	}()

	for _, container := range containers {
		if container.Image == nil {
			return fmt.Errorf("Image is not specified for container %s", container.Name)
		}
		if _, ok := checkedImages[container.Image.String()]; ok {
			wg.Done(nil)
			continue
		}
		checkedImages[container.Image.String()] = struct{}{}

		go func(container *Container) {
			image, err := client.Docker.InspectImage(container.Image.String())
			if err == docker.ErrNoSuchImage {
				msg := message{container, make(chan error)}
				chPullImages <- msg
				wg.Done(<-msg.result)
				return
			} else if err != nil {
				wg.Done(err)
				return
			}
			container.ImageID = image.ID
			wg.Done(nil)
		}(container)
	}

	return wg.Wait()
}