Skip to content

Commit

Permalink
Option to see dangling images in the explorer (#2967)
Browse files Browse the repository at this point in the history
  • Loading branch information
jnsjunior authored Jun 1, 2021
1 parent ef8dc97 commit a19ea5c
Show file tree
Hide file tree
Showing 9 changed files with 38 additions and 9 deletions.
12 changes: 12 additions & 0 deletions package.json
Original file line number Diff line number Diff line change
Expand Up @@ -58,6 +58,7 @@
"onCommand:vscode-docker.images.build",
"onCommand:vscode-docker.images.configureExplorer",
"onCommand:vscode-docker.images.inspect",
"onCommand:vscode-docker.images.showDangling",
"onCommand:vscode-docker.images.prune",
"onCommand:vscode-docker.images.pull",
"onCommand:vscode-docker.images.push",
Expand Down Expand Up @@ -290,6 +291,11 @@
"when": "view == dockerImages && !vscode-docker:newSdkContext",
"group": "navigation@2"
},
{
"command": "vscode-docker.images.showDangling",
"when": "view == dockerImages && !vscode-docker:newSdkContext",
"group": "navigation@2"
},
{
"command": "vscode-docker.images.configureExplorer",
"when": "view == dockerImages",
Expand Down Expand Up @@ -2360,6 +2366,12 @@
"category": "%vscode-docker.commands.category.dockerImages%",
"icon": "$(clear-all)"
},
{
"command": "vscode-docker.images.showDangling",
"title": "%vscode-docker.commands.images.showDangling%",
"category": "%vscode-docker.commands.category.dockerImages%",
"icon": "$(outline-view-icon)"
},
{
"command": "vscode-docker.images.pull",
"title": "%vscode-docker.commands.images.pull%",
Expand Down
1 change: 1 addition & 0 deletions package.nls.json
Original file line number Diff line number Diff line change
Expand Up @@ -219,6 +219,7 @@
"vscode-docker.commands.images.build": "Build Image...",
"vscode-docker.commands.images.configureExplorer": "Configure Explorer...",
"vscode-docker.commands.images.inspect": "Inspect",
"vscode-docker.commands.images.showDangling": "Show dangling images",
"vscode-docker.commands.images.prune": "Prune...",
"vscode-docker.commands.images.pull": "Pull",
"vscode-docker.commands.images.push": "Push...",
Expand Down
8 changes: 8 additions & 0 deletions src/commands/images/showDanglingImages.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@

import { ext } from "../../extensionVariables";
import { IActionContext } from 'vscode-azureextensionui';

export async function showDanglingImages(context: IActionContext): Promise<void> {
const conf: boolean = await ext.context.globalState.get('vscode-docker.images.showDanglingImages', false);
await ext.context.globalState.update('vscode-docker.images.showDanglingImages', !conf);
}
2 changes: 2 additions & 0 deletions src/commands/registerCommands.ts
Original file line number Diff line number Diff line change
Expand Up @@ -34,6 +34,7 @@ import { buildImage } from "./images/buildImage";
import { configureImagesExplorer } from "./images/configureImagesExplorer";
import { copyFullTag } from "./images/copyFullTag";
import { inspectImage } from "./images/inspectImage";
import { showDanglingImages } from "./images/showDanglingImages";
import { pruneImages } from "./images/pruneImages";
import { pullImage } from "./images/pullImage";
import { pushImage } from "./images/pushImage";
Expand Down Expand Up @@ -142,6 +143,7 @@ export function registerCommands(): void {
registerCommand('vscode-docker.images.configureExplorer', configureImagesExplorer);
registerCommand('vscode-docker.images.inspect', inspectImage);
registerCommand('vscode-docker.images.prune', pruneImages);
registerCommand('vscode-docker.images.showDangling', showDanglingImages);
registerWorkspaceCommand('vscode-docker.images.pull', pullImage);
registerWorkspaceCommand('vscode-docker.images.push', pushImage);
registerCommand('vscode-docker.images.remove', removeImage);
Expand Down
2 changes: 1 addition & 1 deletion src/docker/DockerApiClient.ts
Original file line number Diff line number Diff line change
Expand Up @@ -34,7 +34,7 @@ export interface DockerApiClient extends Disposable {
stopContainer(context: IActionContext, ref: string, token?: CancellationToken): Promise<void>;
removeContainer(context: IActionContext, ref: string, token?: CancellationToken): Promise<void>;

getImages(context: IActionContext, token?: CancellationToken): Promise<DockerImage[]>;
getImages(context: IActionContext, includeDangling: boolean, token?: CancellationToken): Promise<DockerImage[]>;
inspectImage(context: IActionContext, ref: string, token?: CancellationToken): Promise<DockerImageInspection>;
pruneImages(context: IActionContext, token?: CancellationToken): Promise<PruneResult | undefined>;
tagImage(context: IActionContext, ref: string, tag: string, token?: CancellationToken): Promise<void>;
Expand Down
2 changes: 1 addition & 1 deletion src/docker/DockerServeClient/DockerServeClient.ts
Original file line number Diff line number Diff line change
Expand Up @@ -139,7 +139,7 @@ export class DockerServeClient extends ContextChangeCancelClient implements Dock
}

// #region Not supported by the Docker SDK yet
public async getImages(context: IActionContext, token?: CancellationToken): Promise<DockerImage[]> {
public async getImages(context: IActionContext, includeDangling?: boolean, token?: CancellationToken): Promise<DockerImage[]> {
throw new NotSupportedError(context);
}

Expand Down
8 changes: 6 additions & 2 deletions src/docker/DockerodeApiClient/DockerodeApiClient.ts
Original file line number Diff line number Diff line change
Expand Up @@ -254,8 +254,12 @@ export class DockerodeApiClient extends ContextChangeCancelClient implements Doc
return this.callWithErrorHandling(context, async () => container.remove({ force: true }), token);
}

public async getImages(context: IActionContext, token?: CancellationToken): Promise<DockerImage[]> {
const images = await this.callWithErrorHandling(context, async () => this.dockerodeClient.listImages({ filters: { "dangling": ["false"] } }), token);
public async getImages(context: IActionContext, includeDangling: boolean = false, token?: CancellationToken): Promise<DockerImage[]> {
const filters = {};
if (!includeDangling) {
filters['dangling'] = ["false"];
}
const images = await this.callWithErrorHandling(context, async () => this.dockerodeClient.listImages({ filters: filters }), token);
const result: DockerImage[] = [];

for (const image of images) {
Expand Down
9 changes: 5 additions & 4 deletions src/tree/images/ImageTreeItem.ts
Original file line number Diff line number Diff line change
Expand Up @@ -67,10 +67,11 @@ export class ImageTreeItem extends AzExtTreeItemIntermediate {
public async deleteTreeItemImpl(context: IActionContext): Promise<void> {
let ref = this.fullTag;

// Dangling images are not shown in the explorer. However, an image can end up with <none> tag, if a new version of that particular tag is pulled.
if (ref.endsWith(':<none>') && this._item.RepoDigests?.length) {
// Image is tagged <none>. Need to delete by digest.
ref = this._item.RepoDigests[0];
// Dangling images are shown in the explorer, depending on the setting.
// In this case, an image end up with <none> tag need to be deleted using the Id.
if (ref.endsWith('<none>')) {
// Image is tagged <none>. Need to delete by ID.
ref = this._item.Id;
}

return ext.dockerClient.removeImage(context, ref);
Expand Down
3 changes: 2 additions & 1 deletion src/tree/images/ImagesTreeItem.ts
Original file line number Diff line number Diff line change
Expand Up @@ -58,7 +58,8 @@ export class ImagesTreeItem extends LocalRootTreeItemBase<DatedDockerImage, Imag
}

public async getItems(context: IActionContext): Promise<DatedDockerImage[]> {
const result = await ext.dockerClient.getImages(context);
const includeDangling = ext.context.globalState.get('vscode-docker.images.showDanglingImages', false);
const result = await ext.dockerClient.getImages(context, includeDangling);
this.outdatedImageChecker.markOutdatedImages(result);
return result;
}
Expand Down

0 comments on commit a19ea5c

Please sign in to comment.