// imageFSMetadata creates a container and reads the filesystem metadata out of the archive. func imageFSMetadata(c *docker.Client, name string) (map[string]*tar.Header, error) { container, err := c.CreateContainer(docker.CreateContainerOptions{Name: name + "-export", Config: &docker.Config{Image: name}}) if err != nil { return nil, err } defer c.RemoveContainer(docker.RemoveContainerOptions{ID: container.ID, RemoveVolumes: true, Force: true}) ch := make(chan struct{}) result := make(map[string]*tar.Header) r, w := io.Pipe() go func() { defer close(ch) out := tar.NewReader(r) for { h, err := out.Next() if err != nil { if err == io.EOF { w.Close() } else { w.CloseWithError(err) } break } result[h.Name] = h } }() if err := c.ExportContainer(docker.ExportContainerOptions{ID: container.ID, OutputStream: w}); err != nil { return nil, err } <-ch return result, nil }
func destroyContainer(client *docker.Client, id string) error { return client.RemoveContainer(docker.RemoveContainerOptions{ ID: id, RemoveVolumes: true, Force: true, }) }
func cleanDuplicateContainer(client *docker.Client, project Project) error { containers, err := client.ListContainers(docker.ListContainersOptions{All: true}) if err != nil { return err } for _, container := range containers { names := container.Names if len(names) > 0 && project.Name == strings.TrimLeft(names[0], "/") { if strings.Contains(container.Status, "Up") { fmt.Println("stopping", project.Name) if err := client.KillContainer(docker.KillContainerOptions{ID: container.ID}); err != nil { fmt.Println("could not stop container") return err } } if err := client.RemoveContainer(docker.RemoveContainerOptions{ ID: container.ID, }); err != nil { fmt.Println("could not remove container", err.Error()) return err } fmt.Println("removed duplicate container") break } } return nil }
// cleanUp stops and removes the deployed router func cleanUp(dockerCli *dockerClient.Client, routerId string) { dockerCli.StopContainer(routerId, 5) dockerCli.RemoveContainer(dockerClient.RemoveContainerOptions{ ID: routerId, Force: true, }) }
// RemoveContainers removes all the containers in ids slice func RemoveContainers(client *docker.Client, ids []string) { for _, id := range ids { removeOpts := docker.RemoveContainerOptions{ ID: id, } if err := client.RemoveContainer(removeOpts); err != nil { panic(fmt.Sprintf("Error remove containers: %v", err)) } } }
func Remove(client *docker.Client, container *docker.Container) error { log.Debugf("Removing container %s", container.ID) err := client.RemoveContainer(docker.RemoveContainerOptions{ ID: container.ID, Force: true, }) log.Debugf("Removed container %s", container.ID) if err != nil { log.Error(err) } return err }
// RemoveDockerContainer removes a Docker container which has stopped. func RemoveDockerContainer(docker *dockerapi.Client, containerID string) error { if DisableRemoveContainerFlag.Get() { logger.Warning( "disableRemoveContainer flag is true. " + "YOU SHOULD NEVER SEE THIS IN PRODUCTION!") return nil } return docker.RemoveContainer(dockerapi.RemoveContainerOptions{ ID: containerID, Force: true, RemoveVolumes: true, }) }
// Run runs cmd in the given image using the docker client cl. It mounts cwd into containerMount in the running container and sends on the following channels: // // - rmContainerCh: a function closure that the receiver should call, after they receive on errCh or exitCodeCh, to remove the container. this is commonly done with a 'defer' // - stdOut: all logs from STDOUT in the container. this may never receive // - stdErr: all logs from STDERR in the container. this may never receive // - exitCodeCh: the exit code of the container // - errCh: any error in setting up or running the container. if errCh receives, exitCodeCh may not receive func Run( cl *docker.Client, image *Image, taskName, cwd, containerMount, cmd string, env []string, rmContainerCh chan<- func(), stdOut chan<- Log, stdErr chan<- Log, exitCodeCh chan<- int, errCh chan<- error, ) { mounts := []docker.Mount{ {Name: "pwd", Source: cwd, Destination: containerMount, Mode: "rxw"}, } cmdSpl := strings.Split(cmd, " ") containerName := NewContainerName(taskName, cwd) createContainerOpts, hostConfig := CreateAndStartContainerOpts(image.String(), containerName, cmdSpl, env, mounts, containerMount) if err := EnsureImage(cl, image.String(), func() (io.Writer, error) { return os.Stdout, nil }); err != nil { errCh <- err return } container, err := cl.CreateContainer(createContainerOpts) if err != nil { errCh <- err } rmContainerCh <- func() { if err := cl.RemoveContainer(docker.RemoveContainerOptions{ID: container.ID, Force: true}); err != nil { log.Warn("Error removing container %s (%s)", container.ID, err) } } log.Debug(CmdStr(createContainerOpts, hostConfig)) attachOpts := AttachToContainerOpts(container.ID, NewChanWriter(stdOut), NewChanWriter(stdErr)) // attach before the container starts, so we get all the logs etc... go AttachAndWait(cl, container.ID, attachOpts, exitCodeCh, errCh) if startErr := cl.StartContainer(container.ID, &hostConfig); startErr != nil { errCh <- err return } }
// cleanUp stops and removes the deployed router func cleanUp(t *testing.T, dockerCli *dockerClient.Client, routerId string) { dockerCli.StopContainer(routerId, 5) if t.Failed() { dockerCli.Logs(dockerClient.LogsOptions{ Container: routerId, OutputStream: os.Stdout, ErrorStream: os.Stderr, Stdout: true, Stderr: true, }) } dockerCli.RemoveContainer(dockerClient.RemoveContainerOptions{ ID: routerId, Force: true, }) }
func CreateAndRemoveContainers(client *docker.Client) string { name := newContainerName() dockerOpts := docker.CreateContainerOptions{ Name: name, Config: &docker.Config{ Image: "ubuntu", }, } container, err := client.CreateContainer(dockerOpts) if err != nil { panic(fmt.Sprintf("Error create containers: %v", err)) } removeOpts := docker.RemoveContainerOptions{ ID: container.ID, } if err := client.RemoveContainer(removeOpts); err != nil { panic(fmt.Sprintf("Error remove containers: %v", err)) } return container.ID }
// removeContainer kills and removes a container func removeContainer(client *docker.Client, containerID string) { client.KillContainer(docker.KillContainerOptions{ID: containerID}) client.RemoveContainer(docker.RemoveContainerOptions{ID: containerID, RemoveVolumes: true, Force: true}) }
func cleanUp(client *docker.Client, container *docker.Container) { client.RemoveContainer(docker.RemoveContainerOptions{ID: container.ID}) client.RemoveImage(BattenDockerRepository) }
// createAndExtractImage creates a docker container based on the option's image with containerName. // It will then insepct the container and image and then attempt to extract the image to // option's destination path. If the destination path is empty it will write to a temp directory // and update the option's destination path with a /var/tmp directory. /var/tmp is used to // try and ensure it is a non-in-memory tmpfs. func (i *defaultImageInspector) createAndExtractImage(client *docker.Client, containerName string) (*docker.Image, error) { container, err := client.CreateContainer(docker.CreateContainerOptions{ Name: containerName, Config: &docker.Config{ Image: i.opts.Image, // For security purpose we don't define any entrypoint and command Entrypoint: []string{""}, Cmd: []string{""}, }, }) if err != nil { return nil, fmt.Errorf("Unable to create docker container: %v\n", err) } // delete the container when we are done extracting it defer func() { client.RemoveContainer(docker.RemoveContainerOptions{ ID: container.ID, }) }() containerMetadata, err := client.InspectContainer(container.ID) if err != nil { return nil, fmt.Errorf("Unable to get docker container information: %v\n", err) } imageMetadata, err := client.InspectImage(containerMetadata.Image) if err != nil { return imageMetadata, fmt.Errorf("Unable to get docker image information: %v\n", err) } if i.opts.DstPath, err = createOutputDir(i.opts.DstPath, "image-inspector-"); err != nil { return imageMetadata, err } reader, writer := io.Pipe() // handle closing the reader/writer in the method that creates them defer writer.Close() defer reader.Close() log.Printf("Extracting image %s to %s", i.opts.Image, i.opts.DstPath) // start the copy function first which will block after the first write while waiting for // the reader to read. errorChannel := make(chan error) go func() { errorChannel <- client.CopyFromContainer(docker.CopyFromContainerOptions{ Container: container.ID, OutputStream: writer, Resource: "/", }) }() // block on handling the reads here so we ensure both the write and the reader are finished // (read waits until an EOF or error occurs). handleTarStream(reader, i.opts.DstPath) // capture any error from the copy, ensures both the handleTarStream and CopyFromContainer // are done. err = <-errorChannel if err != nil { return imageMetadata, fmt.Errorf("Unable to extract container: %v\n", err) } return imageMetadata, nil }