private void DeleteImage(DockerImageNode image, string repoTag) { var imageShortId = DockerImageNode.GetImageShortId(image.InspectResponse.ID); var imageRepoTag = repoTag ?? "<none>"; Console.WriteLine($"[{DateTime.UtcNow.ToString()} UTC] Preparing to delete image: {imageShortId} ({imageRepoTag})"); // Delete image if (!string.IsNullOrEmpty(repoTag)) { _dockerClient.Images.DeleteImageAsync($"{imageRepoTag}", new ImageDeleteParameters() { Force = false, PruneChildren = true }).Wait(); } else { _dockerClient.Images.DeleteImageAsync(image.InspectResponse.ID, new ImageDeleteParameters() { Force = false, PruneChildren = true }).Wait(); } Console.WriteLine($"[{DateTime.UtcNow.ToString()} UTC] Image deleted: {imageShortId} ({imageRepoTag})"); }
private void DeleteImages(IList <DockerImageNode> images) { var recycledDiskSize = 0L; var deletedImages = 0; var dic = new Dictionary <string, int>(); foreach (var image in images) { var imageShortId = DockerImageNode.GetImageShortId(image.InspectResponse.ID); var imageRepoTags = image.InspectResponse.RepoTags; try { // Remove containers in black list states StopAndRemoveContainers(image); // Delete tagged image references foreach (var repoTag in imageRepoTags) { DeleteImage(image, repoTag); } // Delete untagged image if (imageRepoTags.Count() == 0) { DeleteImage(image, null); } recycledDiskSize += image.DiskSize; deletedImages++; } // If container created before we delete the image, docker will throw exception // In this case, we catch the exception here but keep on deleting catch (Exception e) { Console.Error.WriteLine($"[{DateTime.UtcNow.ToString()} UTC] {e}"); } } Console.WriteLine($"[{DateTime.UtcNow.ToString()} UTC] {deletedImages} images deleted (total of {(int)(recycledDiskSize / (1024 * 1024))} MB)"); _logger.LogCounter("images-recycled-count", deletedImages); _logger.LogCounter("disk-space-recycled-mb", (int)(recycledDiskSize / (1024 * 1024))); }
private void _printDependencyGraph(DockerImageNode node, IList <DockerImageNode> highlights, IMatchlist containerStateBlacklist, int indentOffset = 0, int indent = 2, string highlightMarker = "<---") { Console.Write(_indent(indentOffset) + $"Image: {DockerImageNode.GetImageShortId(node.InspectResponse.ID)} ({node.InspectResponse.RepoTags.FirstOrDefault() ?? "<none>"}) {(int)((DateTime.UtcNow - node.InspectResponse.Created).TotalDays)} days {node.DiskSize/(1024*1024)} MB "); if (node.Containers.Count > 0) { Console.Write($"({node.GetContainerCount() - node.GetContainerCount(containerStateBlacklist)}/{node.Containers.Count}) "); } if (highlights.Any(i => string.Equals(i.InspectResponse.ID, node.InspectResponse.ID, StringComparison.InvariantCultureIgnoreCase))) { Console.Write($"{highlightMarker} {highlights.IndexOf(node) + 1}"); } Console.WriteLine(); foreach (var child in node.Children) { _printDependencyGraph(child, highlights, containerStateBlacklist, indentOffset + indent); } }
private void StopAndRemoveContainers(DockerImageNode image) { var imageShortId = DockerImageNode.GetImageShortId(image.InspectResponse.ID); // Remove containers in black list states foreach (var container in image.Containers) { var status = _dockerClient.Containers.InspectContainerAsync(container.ID).Result.State.Status; // If container state changed and not in black list states, we should skip deleting if (!_containerStateBlacklist.Match(status)) { throw new Exception($"Postponed deletion for image: {imageShortId} due to container status change"); } else { Console.WriteLine($"[{DateTime.UtcNow.ToString()} UTC] Stop and remove container: {container.ID} using image: {imageShortId}"); _dockerClient.Containers.StopContainerAsync(container.ID, new ContainerStopParameters()).Wait(); _dockerClient.Containers.RemoveContainerAsync(container.ID, new ContainerRemoveParameters() { Force = false, RemoveLinks = false, RemoveVolumes = false }).Wait(); } } }