func ListImagesDetailed(dockerClient *dockerclient.DockerClient, all bool) ([]*DetailedImageInfo, error) { images, err := dockerClient.ListImages(all) if err != nil { return nil, err } var result = make([]*DetailedImageInfo, len(images)) for i, image := range images { imagesDetails, _ := InspectImage(dockerClient, image.Id) detailedImageInfo := DetailedImageInfo{ Created: image.Created, Id: image.Id, ParentId: image.ParentId, RepoTags: image.RepoTags, Size: image.Size, VirtualSize: image.VirtualSize, Architecture: imagesDetails.Architecture, Author: imagesDetails.Author, Comment: imagesDetails.Comment, Container: imagesDetails.Container, DockerVersion: imagesDetails.Container, Os: imagesDetails.Os} result[i] = &detailedImageInfo } return result, nil }
func (n *Node) GetImages(do *dockerclient.DockerClient) ([]*dockerclient.Image, error) { images, err := do.ListImages(false) if err != nil { log.Fatal(err) } return images, err }
func runGC(dockerClient *dockerclient.DockerClient, filters ...string) (bool, error) { done := true images, err := dockerClient.ListImages(true) if err != nil { return true, err } imagesToSave := make(map[string]bool) for _, image := range images { for _, repoTag := range image.RepoTags { for _, regexFilter := range filters { if match, _ := regexp.MatchString(regexFilter, repoTag); match { log.Printf("Image %v matches regexp /%s/ to keep\n", image.Id, regexFilter) imagesToSave[image.Id] = true } } } } for _, i := range images { if i.ParentId != "" { log.Printf("Image %s has children\n", i.ParentId) imagesToSave[i.ParentId] = true } } containers, err := dockerClient.ListContainers(true, false, "") if err != nil { return true, err } for _, c := range containers { info, _ := dockerClient.InspectContainer(c.Id) log.Printf("Image %s in use by container %v\n", info.Image, c.Id) imagesToSave[info.Image] = true } for _, image := range images { if !imagesToSave[image.Id] { log.Printf("Deleting image with image id %s %v\n", image.Id, image.RepoTags) done = false _, err = dockerClient.RemoveImage(image.Id) if err != nil { log.Println("Failed to delete image: ", err) } } } log.Println("Done with images GC") return done, nil }
func requiredImageAvailable(docker *dockerclient.DockerClient, name string) bool { images, err := docker.ListImages(true) if err != nil { log.Fatal(err) } for _, i := range images { for _, t := range i.RepoTags { if strings.Index(t, name) == 0 { return true } } } return false }
func loadImages(client *dockerclient.DockerClient, db *sql.DB) error { images, err := client.ListImages() if err != nil { return err } if _, err := db.Exec( "CREATE TABLE images (id, parent_id, size, virtual_size, tag, created)"); err != nil { return err } for _, i := range images { created := time.Unix(i.Created, 0) if _, err := db.Exec( "INSERT INTO images (id, parent_id, size, virtual_size, tag, created) VALUES (?, ?, ?, ?, ?, ?)", i.Id, i.ParentId, i.Size, i.VirtualSize, i.RepoTags[0], created); err != nil { return err } } return nil }
func getExpired(client *dockerclient.DockerClient) (expiredContainers []*dockerclient.ContainerInfo, expiredImages []*dockerclient.Image, err error) { now := time.Now() // Containers containers, err := client.ListContainers(true, false, "") // true = all containers if err != nil { return nil, nil, err } usedVolumeContainers := map[string]int{} usedImages := map[string]int{} oldContainers := []*dockerclient.ContainerInfo{} for _, c := range containers { debug("< container: %s", c.Id) container, err := client.InspectContainer(c.Id) if err != nil { debug(" + Couldn't inspect container %s, skipping: %s", c.Id, err) continue } // Increment reference counter refering to how many containers use volume container and image if len(container.HostConfig.VolumesFrom) > 0 { for _, vc := range container.HostConfig.VolumesFrom { usedVolumeContainers[vc]++ } } debug(" + Container %s uses image %s", c.Id, container.Image) usedImages[container.Image]++ if container.State.Running { debug(" + Container is still running") continue } debug(" + not running") if container.State.FinishedAt == time.Date(1, 1, 1, 0, 0, 0, 0, time.UTC) && !*unsafe { debug(" + Container %s has empty FinishedAt field, skipping", c.Id) continue } created, err := time.Parse(time.RFC3339, container.Created) if err != nil { return nil, nil, err } debug(" + Container and image threshold %s", now.Add(-*ageContainer)) if created.After(now.Add(-*ageContainer)) { debug(" + Creation time is not old enough: %s", created) continue } debug(" + Creation time is older than %s", *ageContainer) if container.State.FinishedAt.After(now.Add(-*ageContainer)) { debug(" + Exit time is not old enough: %s", container.State.FinishedAt) continue } debug(" + Exit time is older than %s", *ageContainer) // Decrement reference counter for old containers if len(container.HostConfig.VolumesFrom) > 0 { for _, vc := range container.HostConfig.VolumesFrom { usedVolumeContainers[vc]-- } } usedImages[container.Image]-- oldContainers = append(oldContainers, container) } for _, c := range oldContainers { name := c.Name[1:] // Remove leading / if usedVolumeContainers[name] > 0 { continue } expiredContainers = append(expiredContainers, c) } log.Printf("Found %d expired containers", len(expiredContainers)) // Images images, err := client.ListImages(true) if err != nil { return nil, nil, err } for _, image := range images { debug("< image id: %s", image.Id) ctime := time.Unix(image.Created, 0) if ctime.After(now.Add(-*ageImage)) { continue } debug(" + older than %s", *ageImage) if usedImages[image.Id] > 0 { debug(" + in use, skipping") continue } expiredImages = append(expiredImages, image) } log.Printf("Found %d expired images", len(expiredImages)) return expiredContainers, expiredImages, nil }