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

Check for and flag outdated images #2073

Merged
merged 14 commits into from
Jul 8, 2020
208 changes: 104 additions & 104 deletions .vscode/launch.json
Original file line number Diff line number Diff line change
@@ -1,107 +1,107 @@
// A launch configuration that compiles the extension and then opens it inside a new window
{
"version": "0.1.0",
"configurations": [
{
"name": "Launch Extension",
"type": "extensionHost",
"request": "launch",
"runtimeExecutable": "${execPath}",
"args": [
"--extensionDevelopmentPath=${workspaceFolder}"
],
"env": {
"AZCODE_DOCKER_IGNORE_BUNDLE": "1",
"DEBUGTELEMETRY": "1"
},
"stopOnEntry": false,
"sourceMaps": true,
"outFiles": [
"${workspaceFolder}/out/**/*.js"
],
"preLaunchTask": "${defaultBuildTask}"
},
{
"name": "Launch Extension (webpack)",
"type": "extensionHost",
"request": "launch",
"runtimeExecutable": "${execPath}",
"args": [
"--extensionDevelopmentPath=${workspaceFolder}"
],
"env": {
"AZCODE_DOCKER_IGNORE_BUNDLE": "",
"DEBUGTELEMETRY": "1"
},
"stopOnEntry": false,
"sourceMaps": true,
"outFiles": [
"${workspaceFolder}/out/**/*.js"
],
"preLaunchTask": "npm: webpack-prod"
},
{
"name": "Launch Tests",
"type": "extensionHost",
"request": "launch",
"runtimeExecutable": "${execPath}",
"args": [
"${workspaceFolder}/test/test.code-workspace",
"--extensionDevelopmentPath=${workspaceFolder}",
"--extensionTestsPath=${workspaceFolder}/out/test/index"
],
"stopOnEntry": false,
"sourceMaps": true,
"outFiles": [
"${workspaceFolder}/out/**/*.js"
],
"preLaunchTask": "${defaultBuildTask}",
"env": {
"AZCODE_DOCKER_IGNORE_BUNDLE": "1",
"MOCHA_grep": "", // RegExp of tests to run (empty means all)
}
},
{
"name": "Launch Tests (unit)",
"type": "extensionHost",
"request": "launch",
"runtimeExecutable": "${execPath}",
"args": [
"${workspaceFolder}/test/test.code-workspace",
"--extensionDevelopmentPath=${workspaceFolder}",
"--extensionTestsPath=${workspaceFolder}/out/test/index"
],
"stopOnEntry": false,
"sourceMaps": true,
"outFiles": [
"${workspaceFolder}/out/**/*.js"
],
"preLaunchTask": "${defaultBuildTask}",
"env": {
"AZCODE_DOCKER_IGNORE_BUNDLE": "1",
"MOCHA_grep": "\\(unit\\)", // RegExp of tests to run (empty means all)
}
},
{
"name": "Launch Tests (webpack)",
"type": "extensionHost",
"request": "launch",
"runtimeExecutable": "${execPath}",
"args": [
"${workspaceFolder}/test/test.code-workspace",
"--extensionDevelopmentPath=${workspaceFolder}",
"--extensionTestsPath=${workspaceFolder}/dist/test/index"
],
"stopOnEntry": false,
"sourceMaps": true,
"outFiles": [
"${workspaceFolder}/dist/**/*.js"
],
"preLaunchTask": "npm: webpack-prod",
"env": {
"AZCODE_DOCKER_IGNORE_BUNDLE": "",
"MOCHA_grep": "", // RegExp of tests to run (empty means all)
}
}
]
"version": "0.1.0",
"configurations": [
{
"name": "Launch Extension",
"type": "extensionHost",
"request": "launch",
"runtimeExecutable": "${execPath}",
"args": [
"--extensionDevelopmentPath=${workspaceFolder}"
],
"env": {
"AZCODE_DOCKER_IGNORE_BUNDLE": "1",
"DEBUGTELEMETRY": "1"
},
"stopOnEntry": false,
"sourceMaps": true,
"outFiles": [
"${workspaceFolder}/out/**/*.js"
],
"preLaunchTask": "${defaultBuildTask}"
},
{
"name": "Launch Extension (webpack)",
"type": "extensionHost",
"request": "launch",
"runtimeExecutable": "${execPath}",
"args": [
"--extensionDevelopmentPath=${workspaceFolder}"
],
"env": {
"AZCODE_DOCKER_IGNORE_BUNDLE": "",
"DEBUGTELEMETRY": "1"
},
"stopOnEntry": false,
"sourceMaps": true,
"outFiles": [
"${workspaceFolder}/out/**/*.js"
],
"preLaunchTask": "npm: webpack-prod"
},
{
"name": "Launch Tests",
"type": "extensionHost",
"request": "launch",
"runtimeExecutable": "${execPath}",
"args": [
"${workspaceFolder}/test/test.code-workspace",
"--extensionDevelopmentPath=${workspaceFolder}",
"--extensionTestsPath=${workspaceFolder}/out/test/index"
],
"stopOnEntry": false,
"sourceMaps": true,
"outFiles": [
"${workspaceFolder}/out/**/*.js"
],
"preLaunchTask": "${defaultBuildTask}",
"env": {
"AZCODE_DOCKER_IGNORE_BUNDLE": "1",
"MOCHA_grep": "", // RegExp of tests to run (empty means all)
}
},
{
"name": "Launch Tests (unit)",
"type": "extensionHost",
"request": "launch",
"runtimeExecutable": "${execPath}",
"args": [
"${workspaceFolder}/test/test.code-workspace",
"--extensionDevelopmentPath=${workspaceFolder}",
"--extensionTestsPath=${workspaceFolder}/out/test/index"
],
"stopOnEntry": false,
"sourceMaps": true,
"outFiles": [
"${workspaceFolder}/out/**/*.js"
],
"preLaunchTask": "${defaultBuildTask}",
"env": {
"AZCODE_DOCKER_IGNORE_BUNDLE": "1",
"MOCHA_grep": "\\(unit\\)", // RegExp of tests to run (empty means all)
}
},
{
"name": "Launch Tests (webpack)",
"type": "extensionHost",
"request": "launch",
"runtimeExecutable": "${execPath}",
"args": [
"${workspaceFolder}/test/test.code-workspace",
"--extensionDevelopmentPath=${workspaceFolder}",
"--extensionTestsPath=${workspaceFolder}/dist/test/index"
],
"stopOnEntry": false,
"sourceMaps": true,
"outFiles": [
"${workspaceFolder}/dist/**/*.js"
],
"preLaunchTask": "npm: webpack-prod",
"env": {
"AZCODE_DOCKER_IGNORE_BUNDLE": "",
"MOCHA_grep": "", // RegExp of tests to run (empty means all)
}
}
]
}
5 changes: 5 additions & 0 deletions package.json
Original file line number Diff line number Diff line change
Expand Up @@ -1782,6 +1782,11 @@
"Label"
]
},
"docker.images.checkForOutdatedImages": {
"type": "boolean",
"default": true,
"description": "%vscode-docker.config.docker.images.checkForOutdatedImages%"
},
"docker.networks.groupBy": {
"type": "string",
"default": "None",
Expand Down
1 change: 1 addition & 0 deletions package.nls.json
Original file line number Diff line number Diff line change
Expand Up @@ -136,6 +136,7 @@
"vscode-docker.config.docker.images.description": "Any secondary properties to display for a image (an array). Possible elements include: CreatedTime, FullTag, ImageId, Registry, Repository, RepositoryName, RepositoryNameAndTag, and Tag",
"vscode-docker.config.docker.images.label": "The primary property to display for a image: CreatedTime, FullTag, ImageId, Registry, Repository, RepositoryName, RepositoryNameAndTag, or Tag",
"vscode-docker.config.docker.images.sortBy": "The property to use to sort images in Docker view: CreatedTime or Label",
"vscode-docker.config.docker.images.checkForOutdatedImages": "Whether to check for outdated base images once per session",
"vscode-docker.config.docker.networks.groupBy": "The property to use to group networks in Docker view: CreatedTime, NetworkDriver, NetworkId, NetworkName, or None",
"vscode-docker.config.docker.networks.description": "Any secondary properties to display for a Docker network (an array). Possible elements include CreatedTime, NetworkDriver, NetworkId, and NetworkName",
"vscode-docker.config.docker.networks.label": "The primary property to display for a Docker network: CreatedTime, NetworkDriver, NetworkId, or NetworkName",
Expand Down
8 changes: 0 additions & 8 deletions src/constants.ts
Original file line number Diff line number Diff line change
Expand Up @@ -11,14 +11,6 @@ export const configPrefix: string = 'docker';
// Consider downloading multiple pages (images, tags, etc)
export const PAGE_SIZE = 100;

export namespace keytarConstants {
export const serviceId: string = 'vscode-docker';

export const dockerHubTokenKey: string = 'dockerhub.token';
export const dockerHubUserNameKey: string = 'dockerhub.username';
export const dockerHubPasswordKey: string = 'dockerhub.password';
}

export namespace configurationKeys {
export const groupImagesBy = 'groupImagesBy';
}
Expand Down
1 change: 1 addition & 0 deletions src/docker/Images.ts
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,7 @@ export interface DockerImage extends DockerObject {
export interface DockerImageInspection extends DockerObject {
readonly Config?: {
readonly ExposedPorts?: { readonly [portAndProtocol: string]: unknown; };
readonly Image?: string;
};

readonly Name: undefined; // Not defined for inspection
Expand Down
4 changes: 2 additions & 2 deletions src/tree/images/ImageGroupTreeItem.ts
Original file line number Diff line number Diff line change
Expand Up @@ -3,12 +3,12 @@
* Licensed under the MIT License. See LICENSE.md in the project root for license information.
*--------------------------------------------------------------------------------------------*/

import { DockerImage } from "../../docker/Images";
import { IconPath } from "../IconPath";
import { LocalGroupTreeItemBase } from "../LocalGroupTreeItemBase";
import { getImageGroupIcon, ImageProperty } from "./ImageProperties";
import { DatedDockerImage } from "./ImagesTreeItem";

export class ImageGroupTreeItem extends LocalGroupTreeItemBase<DockerImage, ImageProperty> {
export class ImageGroupTreeItem extends LocalGroupTreeItemBase<DatedDockerImage, ImageProperty> {
public static readonly contextValue: string = 'imageGroup';
public readonly contextValue: string = ImageGroupTreeItem.contextValue;
public childTypeLabel: string = 'image';
Expand Down
13 changes: 9 additions & 4 deletions src/tree/images/ImageTreeItem.ts
Original file line number Diff line number Diff line change
Expand Up @@ -4,17 +4,18 @@
*--------------------------------------------------------------------------------------------*/

import { AzExtParentTreeItem, AzExtTreeItem, IActionContext } from "vscode-azureextensionui";
import { DockerImage } from '../../docker/Images';
import { ext } from '../../extensionVariables';
import { localize } from "../../localize";
import { getThemedIconPath, IconPath } from '../IconPath';
import { getTreeId } from "../LocalRootTreeItemBase";
import { DatedDockerImage } from "./ImagesTreeItem";

export class ImageTreeItem extends AzExtTreeItem {
public static contextValue: string = 'image';
public contextValue: string = ImageTreeItem.contextValue;
private readonly _item: DockerImage;
private readonly _item: DatedDockerImage;

public constructor(parent: AzExtParentTreeItem, itemInfo: DockerImage) {
public constructor(parent: AzExtParentTreeItem, itemInfo: DatedDockerImage) {
super(parent);
this._item = itemInfo;
}
Expand All @@ -40,10 +41,14 @@ export class ImageTreeItem extends AzExtTreeItem {
}

public get description(): string | undefined {
return ext.imagesRoot.getTreeItemDescription(this._item);
return `${ext.imagesRoot.getTreeItemDescription(this._item)}${this._item.Outdated ? localize('vscode-docker.tree.images.outdated', ' (Out of date)') : ''}`;
}

public get iconPath(): IconPath {
if (this._item.Outdated) {
return getThemedIconPath('statusWarning');
}

let icon: string;
switch (ext.imagesRoot.labelSetting) {
case 'Tag':
Expand Down
17 changes: 12 additions & 5 deletions src/tree/images/ImagesTreeItem.ts
Original file line number Diff line number Diff line change
Expand Up @@ -13,14 +13,19 @@ import { ITreeArraySettingInfo, ITreeSettingInfo } from "../settings/ITreeSettin
import { ImageGroupTreeItem } from './ImageGroupTreeItem';
import { getImagePropertyValue, imageProperties, ImageProperty } from "./ImageProperties";
import { ImageTreeItem } from "./ImageTreeItem";
import { OutdatedImageChecker } from "./OutdatedImageChecker";

export type DatedDockerImage = DockerImage & { Outdated?: boolean };
bwateratmsft marked this conversation as resolved.
Show resolved Hide resolved

export class ImagesTreeItem extends LocalRootTreeItemBase<DatedDockerImage, ImageProperty> {
private readonly outdatedImageChecker: OutdatedImageChecker = new OutdatedImageChecker();

export class ImagesTreeItem extends LocalRootTreeItemBase<DockerImage, ImageProperty> {
public treePrefix: string = 'images';
public label: string = localize('vscode-docker.tree.images.label', 'Images');
public configureExplorerTitle: string = localize('vscode-docker.tree.images.configure', 'Configure images explorer');

public childType: LocalChildType<DockerImage> = ImageTreeItem;
public childGroupType: LocalChildGroupType<DockerImage, ImageProperty> = ImageGroupTreeItem;
public childType: LocalChildType<DatedDockerImage> = ImageTreeItem;
public childGroupType: LocalChildGroupType<DatedDockerImage, ImageProperty> = ImageGroupTreeItem;

public labelSettingInfo: ITreeSettingInfo<ImageProperty> = {
properties: imageProperties,
Expand All @@ -41,8 +46,10 @@ export class ImagesTreeItem extends LocalRootTreeItemBase<DockerImage, ImageProp
return this.groupBySetting === 'None' ? 'image' : 'image group';
}

public async getItems(context: IActionContext): Promise<DockerImage[]> {
return ext.dockerClient.getImages(context);
public async getItems(context: IActionContext): Promise<DatedDockerImage[]> {
const result = await ext.dockerClient.getImages(context);
this.outdatedImageChecker.markOutdatedImages(result);
return result;
}

public getPropertyValue(item: DockerImage, property: ImageProperty): string {
Expand Down
Loading