Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Option to see dangling images in the explorer #2967

Merged
merged 6 commits into from
Jun 1, 2021
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
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 @@ -2354,6 +2360,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 @@ -218,6 +218,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 = {};
jnsjunior marked this conversation as resolved.
Show resolved Hide resolved
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