func removeImage(d *schema.ResourceData, client *dc.Client) error { var data Data if keepLocally := d.Get("keep_locally").(bool); keepLocally { return nil } if err := fetchLocalImages(&data, client); err != nil { return err } imageName := d.Get("name").(string) if imageName == "" { return fmt.Errorf("Empty image name is not allowed") } foundImage := searchLocalImages(data, imageName) if foundImage != nil { err := client.RemoveImage(foundImage.ID) if err != nil { return err } } return nil }
func syncImages(client *dockerclient.Client, imageRoot string) error { logrus.Debugf("Syncing images from %s", imageRoot) f, err := os.Open(filepath.Join(imageRoot, "images.json")) if err != nil { return fmt.Errorf("error opening image json file: %v", err) } defer f.Close() var m tagMap if err := json.NewDecoder(f).Decode(&m); err != nil { return fmt.Errorf("error decoding images json: %v", err) } allTags := map[string]struct{}{} neededImages := map[string]struct{}{} for imageID, tags := range m { neededImages[imageID] = struct{}{} for _, t := range tags { allTags[t] = struct{}{} } } images, err := client.ListImages(dockerclient.ListImagesOptions{}) if err != nil { return fmt.Errorf("error listing images: %v", err) } for _, img := range images { expectedTags, ok := m[img.ID] if ok { delete(neededImages, img.ID) repoTags := filterRepoTags(img.RepoTags) logrus.Debugf("Tags for %s: %#v", img.ID, repoTags) // Sync tags for image ID removedTags, addedTags := listDiff(repoTags, expectedTags) for _, t := range addedTags { if err := tagImage(client, img.ID, t); err != nil { return err } } for _, t := range removedTags { // Check if this image tag conflicts with an expected // tag, in which case force tag will update if _, ok := allTags[t]; !ok { logrus.Debugf("Removing tag %s", t) if err := client.RemoveImage(t); err != nil { return fmt.Errorf("error removing tag %s: %v", t, err) } } } } else { removeOptions := dockerclient.RemoveImageOptions{ Force: true, } if err := client.RemoveImageExtended(img.ID, removeOptions); err != nil { return fmt.Errorf("error moving image %s: %v", img.ID, err) } } } for imageID := range neededImages { tags, ok := m[imageID] if !ok { return fmt.Errorf("missing image %s in tag map", imageID) } _, err := client.InspectImage(imageID) if err != nil { tf, err := os.Open(filepath.Join(imageRoot, imageID+".tar")) if err != nil { return fmt.Errorf("error opening image tar %s: %v", imageID, err) } defer tf.Close() loadOptions := dockerclient.LoadImageOptions{ InputStream: tf, } if err := client.LoadImage(loadOptions); err != nil { return fmt.Errorf("error loading image %s: %v", imageID, err) } } for _, t := range tags { if err := tagImage(client, imageID, t); err != nil { return err } } } return nil }
func cleanUp(client *docker.Client, container *docker.Container) { client.RemoveContainer(docker.RemoveContainerOptions{ID: container.ID}) client.RemoveImage(BattenDockerRepository) }
func cleanImages(client *docker.Client) { defer wg.Done() log.Printf("Img Cleanup: the following images will be locked: %s", *pImageLocked) log.Println("Img Cleanup: starting image cleanup ...") for { // imageIdMap[imageID] = isRemovable imageIdMap := make(map[string]bool) // Get the image ID list before the cleanup images, err := client.ListImages(docker.ListImagesOptions{All: false}) if err != nil { log.Println("Img Cleanup: cannot get images list", err) time.Sleep(time.Duration(*pImageCleanInterval+*pImageCleanDelayed) * time.Second) continue } for _, image := range images { imageIdMap[image.ID] = true } // Get the image IDs used by all the containers containers, err := client.ListContainers(docker.ListContainersOptions{All: true}) if err != nil { log.Println("Img Cleanup: cannot get container list", err) time.Sleep(time.Duration(*pImageCleanInterval+*pImageCleanDelayed) * time.Second) continue } else { inspect_error := false for _, container := range containers { containerInspect, err := client.InspectContainer(container.ID) if err != nil { inspect_error = true log.Println("Img Cleanup: cannot get container inspect", err) break } delete(imageIdMap, containerInspect.Image) } if inspect_error { time.Sleep(time.Duration(*pImageCleanInterval+*pImageCleanDelayed) * time.Second) continue } } // Get all the locked image ID if *pImageLocked != "" { lockedImages := strings.Split(*pImageLocked, ",") for _, lockedImage := range lockedImages { imageInspect, err := client.InspectImage(strings.Trim(lockedImage, " ")) if err == nil { delete(imageIdMap, imageInspect.ID) } } } // Sleep for the delay time log.Printf("Img Cleanup: wait %d seconds for the cleaning", *pImageCleanDelayed) time.Sleep(time.Duration(*pImageCleanDelayed) * time.Second) // Get the image IDs used by all the containers again after the delay time containersDelayed, err := client.ListContainers(docker.ListContainersOptions{All: true}) if err != nil { log.Println("Img Cleanup: cannot get container list", err) time.Sleep(time.Duration(*pImageCleanInterval) * time.Second) continue } else { inspect_error := false for _, container := range containersDelayed { containerInspect, err := client.InspectContainer(container.ID) if err != nil { inspect_error = true log.Println("Img Cleanup: cannot get container inspect", err) break } delete(imageIdMap, containerInspect.Image) } if inspect_error { time.Sleep(time.Duration(*pImageCleanInterval) * time.Second) continue } } // Remove the unused images counter := 0 for id, removable := range imageIdMap { if removable { log.Printf("Img Cleanup: removing image %s", id) err := client.RemoveImage(id) if err != nil { log.Printf("Img Cleanup: %s", err) } counter += 1 } } log.Printf("Img Cleanup: %d images have been removed", counter) // Sleep again log.Printf("Img Cleanup: next cleanup will be start in %d seconds", *pImageCleanInterval) time.Sleep(time.Duration(*pImageCleanInterval) * time.Second) } }