chore: fix await on promises

There were missing await or non catched promises

Change-Id: I477776c329500ad8b20357ca50b9ea57b07664f7

Signed-off-by: Florent Benoit <fbenoit@redhat.com>
This commit is contained in:
Florent Benoit 2023-05-15 10:31:25 +02:00 committed by Florent BENOIT
parent 4a42e761dd
commit 5e2cad9c36
44 changed files with 468 additions and 357 deletions

View file

@ -7,3 +7,4 @@ extensions/*/builtin/**
extensions/*/scripts/**
extensions/*.ts
__mocks__
coverage

View file

@ -53,6 +53,7 @@
"@typescript-eslint/no-explicit-any": "error",
"prefer-promise-reject-errors": "error",
"@typescript-eslint/await-thenable": "error",
"@typescript-eslint/no-floating-promises": "error",
/**
* Having a semicolon helps the optimizer interpret your code correctly.

View file

@ -47,11 +47,11 @@ let kindCli: string | undefined;
const imageHandler = new ImageHandler();
function registerProvider(
async function registerProvider(
extensionContext: extensionApi.ExtensionContext,
provider: extensionApi.Provider,
telemetryLogger: extensionApi.TelemetryLogger,
): void {
): Promise<void> {
const disposable = provider.setKubernetesProviderConnectionFactory({
// eslint-disable-next-line @typescript-eslint/no-explicit-any
create: (params: { [key: string]: any }, logger?: Logger, token?: CancellationToken) =>
@ -61,7 +61,7 @@ function registerProvider(
extensionContext.subscriptions.push(disposable);
// search
searchKindClusters(provider);
await searchKindClusters(provider);
console.log('kind extension is active');
}
@ -163,14 +163,14 @@ async function updateClusters(provider: extensionApi.Provider, containers: exten
});
}
async function searchKindClusters(provider: extensionApi.Provider) {
async function searchKindClusters(provider: extensionApi.Provider): Promise<void> {
const allContainers = await extensionApi.containerEngine.listContainers();
// search all containers with io.x-k8s.kind.cluster label
const kindContainers = allContainers.filter(container => {
return container.Labels?.['io.x-k8s.kind.cluster'];
});
updateClusters(provider, kindContainers);
await updateClusters(provider, kindContainers);
}
export function refreshKindClustersOnProviderConnectionUpdate(provider: extensionApi.Provider) {
@ -181,10 +181,10 @@ export function refreshKindClustersOnProviderConnectionUpdate(provider: extensio
});
}
function createProvider(
async function createProvider(
extensionContext: extensionApi.ExtensionContext,
telemetryLogger: extensionApi.TelemetryLogger,
) {
): Promise<void> {
const provider = extensionApi.provider.createProvider({
name: 'Kind',
id: 'kind',
@ -198,11 +198,11 @@ function createProvider(
},
});
extensionContext.subscriptions.push(provider);
registerProvider(extensionContext, provider, telemetryLogger);
await registerProvider(extensionContext, provider, telemetryLogger);
extensionContext.subscriptions.push(
extensionApi.commands.registerCommand(KIND_MOVE_IMAGE_COMMAND, image => {
extensionApi.commands.registerCommand(KIND_MOVE_IMAGE_COMMAND, async image => {
telemetryLogger.logUsage('moveImage');
imageHandler.moveImage(image, kindClusters, kindCli);
await imageHandler.moveImage(image, kindClusters, kindCli);
}),
);
@ -210,7 +210,7 @@ function createProvider(
extensionApi.containerEngine.onEvent(async event => {
if (event.Type === 'container') {
// needs to search for kind clusters
searchKindClusters(provider);
await searchKindClusters(provider);
}
});
@ -218,15 +218,15 @@ function createProvider(
refreshKindClustersOnProviderConnectionUpdate(provider);
// search when a new container is updated or removed
extensionApi.provider.onDidRegisterContainerConnection(() => {
searchKindClusters(provider);
extensionApi.provider.onDidRegisterContainerConnection(async () => {
await searchKindClusters(provider);
});
extensionApi.provider.onDidUnregisterContainerConnection(() => {
searchKindClusters(provider);
extensionApi.provider.onDidUnregisterContainerConnection(async () => {
await searchKindClusters(provider);
});
extensionApi.provider.onDidUpdateProvider(() => registerProvider(extensionContext, provider, telemetryLogger));
extensionApi.provider.onDidUpdateProvider(async () => registerProvider(extensionContext, provider, telemetryLogger));
// search for kind clusters on boot
searchKindClusters(provider);
await searchKindClusters(provider);
}
export async function activate(extensionContext: extensionApi.ExtensionContext): Promise<void> {
@ -248,7 +248,7 @@ export async function activate(extensionContext: extensionApi.ExtensionContext):
if (status) {
statusBarItem.dispose();
kindCli = await detectKind(extensionContext.storagePath, installer);
createProvider(extensionContext, telemetryLogger);
await createProvider(extensionContext, telemetryLogger);
}
},
(err: unknown) => window.showErrorMessage('Kind installation failed ' + err),
@ -258,7 +258,7 @@ export async function activate(extensionContext: extensionApi.ExtensionContext):
statusBarItem.show();
}
} else {
createProvider(extensionContext, telemetryLogger);
await createProvider(extensionContext, telemetryLogger);
}
}

View file

@ -1,5 +1,5 @@
/**********************************************************************
* Copyright (C) 2022 Red Hat, Inc.
* Copyright (C) 2022-2023 Red Hat, Inc.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
@ -89,17 +89,17 @@ export async function activate(extensionContext: extensionApi.ExtensionContext):
// if path exists, update context
if (fs.existsSync(kubeconfigFile)) {
updateContext(extensionContext, kubeconfigFile);
await updateContext(extensionContext, kubeconfigFile);
}
// update context menu on change
extensionApi.kubernetes.onDidUpdateKubeconfig((event: extensionApi.KubeconfigUpdateEvent) => {
extensionApi.kubernetes.onDidUpdateKubeconfig(async (event: extensionApi.KubeconfigUpdateEvent) => {
// update the tray everytime .kube/config file is updated
if (event.type === 'UPDATE' || event.type === 'CREATE') {
kubeconfigFile = event.location.fsPath;
updateContext(extensionContext, kubeconfigFile);
await updateContext(extensionContext, kubeconfigFile);
} else if (event.type === 'DELETE') {
deleteContext();
await deleteContext();
kubeconfigFile = undefined;
}
});
@ -107,7 +107,7 @@ export async function activate(extensionContext: extensionApi.ExtensionContext):
const command = extensionApi.commands.registerCommand('kubecontext.switch', async (newContext: string) => {
const file = getKubeconfig();
if (!file) {
extensionApi.window.showErrorMessage('No kubeconfig file found');
await extensionApi.window.showErrorMessage('No kubeconfig file found');
return;
}
// load the file

View file

@ -69,7 +69,7 @@ test('darwin: DarwinSocketCompatibility class, test runSudoMacHelperCommand ran
});
// Run the command
socketCompatClass.runCommand('enable', 'enabled');
await socketCompatClass.runCommand('enable', 'enabled');
// Expect that mac helper command was ran
expect(spyMacHelperCommand).toHaveBeenCalled();

View file

@ -95,18 +95,19 @@ export class DarwinSocketCompatibility extends SocketCompatibility {
// Find the podman-mac-helper binary
const podmanHelperBinary = this.findPodmanHelper();
if (podmanHelperBinary === '') {
extensionApi.window.showErrorMessage('podman-mac-helper binary not found.', 'OK');
await extensionApi.window.showErrorMessage('podman-mac-helper binary not found.', 'OK');
return;
}
const fullCommand = `${podmanHelperBinary} ${command}`;
try {
await this.runSudoMacHelperCommand(fullCommand);
extensionApi.window.showInformationMessage(`Docker socket compatibility mode for Podman has been ${description}.
await extensionApi.window
.showInformationMessage(`Docker socket compatibility mode for Podman has been ${description}.
Restart your Podman machine to apply the changes.`);
} catch (error) {
console.error(`Error running podman-mac-helper: ${error}`);
extensionApi.window.showErrorMessage(`Error running podman-mac-helper: ${error}`, 'OK');
await extensionApi.window.showErrorMessage(`Error running podman-mac-helper: ${error}`, 'OK');
}
}

View file

@ -75,10 +75,13 @@ test('verify create command called with correct values', async () => {
});
test('test checkDefaultMachine, if the machine running is not default, the function will prompt', async () => {
const machineDefaultName = 'podman-machine-default';
const machine1Name = 'podman-machine-1';
// Create fake of MachineJSON
const fakeJSON: extension.MachineJSON[] = [
{
Name: 'podman-machine-default',
Name: machineDefaultName,
CPUs: 2,
Memory: '1048000000',
DiskSize: '250000000000',
@ -87,7 +90,7 @@ test('test checkDefaultMachine, if the machine running is not default, the funct
Default: false,
},
{
Name: 'podman-machine-1',
Name: machine1Name,
CPUs: 2,
Memory: '1048000000',
DiskSize: '250000000000',
@ -100,7 +103,7 @@ test('test checkDefaultMachine, if the machine running is not default, the funct
await extension.checkDefaultMachine(fakeJSON);
expect(extensionApi.window.showInformationMessage).toBeCalledWith(
"Podman Machine 'podman-machine-default' is running but not the default machine (default is 'podman-machine-1'). This will cause podman CLI errors while trying to connect to 'podman-machine-default'. Do you want to set it as default?",
`Podman Machine '${machineDefaultName}' is running but not the default machine (default is '${machine1Name}'). This will cause podman CLI errors while trying to connect to '${machineDefaultName}'. Do you want to set it as default?`,
'Yes',
'Ignore',
'Cancel',

View file

@ -85,7 +85,7 @@ async function updateMachines(provider: extensionApi.Provider): Promise<void> {
const machines = JSON.parse(machineListOutput) as MachineJSON[];
// update status of existing machines
machines.forEach(machine => {
machines.forEach(async machine => {
const running = machine?.Running === true;
let status: extensionApi.ProviderConnectionStatus = running ? 'started' : 'stopped';
@ -114,7 +114,7 @@ async function updateMachines(provider: extensionApi.Provider): Promise<void> {
if (containerProviderConnections.has(machine.Name)) {
const containerProviderConnection = containerProviderConnections.get(machine.Name);
updateContainerConfiguration(containerProviderConnection, podmanMachinesInfo.get(machine.Name));
await updateContainerConfiguration(containerProviderConnection, podmanMachinesInfo.get(machine.Name));
}
});
@ -238,17 +238,17 @@ export async function checkDefaultMachine(machines: MachineJSON[]): Promise<void
}
}
function updateContainerConfiguration(
async function updateContainerConfiguration(
containerProviderConnection: extensionApi.ContainerProviderConnection,
machineInfo: MachineInfo,
) {
): Promise<void> {
// get configuration for this connection
const containerConfiguration = extensionApi.configuration.getConfiguration('podman', containerProviderConnection);
// Set values for the machine
containerConfiguration.update('machine.cpus', machineInfo.cpus);
containerConfiguration.update('machine.memory', machineInfo.memory);
containerConfiguration.update('machine.diskSize', machineInfo.diskSize);
await containerConfiguration.update('machine.cpus', machineInfo.cpus);
await containerConfiguration.update('machine.memory', machineInfo.memory);
await containerConfiguration.update('machine.diskSize', machineInfo.diskSize);
}
function calcMacosSocketPath(machineName: string): string {
@ -289,7 +289,9 @@ async function initDefaultLinux(provider: extensionApi.Provider) {
},
};
monitorPodmanSocket(socketPath);
monitorPodmanSocket(socketPath).catch((error: unknown) => {
console.error('Error monitoring podman socket', error);
});
const disposable = provider.registerContainerProviderConnection(containerProviderConnection);
currentConnections.set('podman', disposable);
@ -334,7 +336,9 @@ async function monitorPodmanSocket(socketPath: string, machineName?: string) {
// ignore the update of machines
}
await timeout(5000);
monitorPodmanSocket(socketPath, machineName);
monitorPodmanSocket(socketPath, machineName).catch((error: unknown) => {
console.error('Error monitoring podman socket', error);
});
}
}
@ -368,7 +372,9 @@ async function monitorMachines(provider: extensionApi.Provider) {
// ignore the update of machines
}
await timeout(5000);
monitorMachines(provider);
monitorMachines(provider).catch((error: unknown) => {
console.error('Error monitoring podman machines', error);
});
}
}
@ -394,7 +400,9 @@ async function monitorProvider(provider: extensionApi.Provider) {
}
}
await timeout(8000);
monitorProvider(provider);
monitorProvider(provider).catch((error: unknown) => {
console.error('Error monitoring podman provider', error);
});
}
function prettyMachineName(machineName: string): string {
@ -454,9 +462,9 @@ async function registerProviderFor(provider: extensionApi.Provider, machineInfo:
const containerConfiguration = extensionApi.configuration.getConfiguration('podman', containerProviderConnection);
// Set values for the machine
containerConfiguration.update('machine.cpus', machineInfo.cpus);
containerConfiguration.update('machine.memory', machineInfo.memory);
containerConfiguration.update('machine.diskSize', machineInfo.diskSize);
await containerConfiguration.update('machine.cpus', machineInfo.cpus);
await containerConfiguration.update('machine.memory', machineInfo.memory);
await containerConfiguration.update('machine.diskSize', machineInfo.diskSize);
currentConnections.set(machineInfo.name, disposable);
storedExtensionContext.subscriptions.push(disposable);
@ -551,7 +559,7 @@ export async function activate(extensionContext: extensionApi.ExtensionContext):
const provider = extensionApi.provider.createProvider(providerOptions);
// Check on initial setup
checkDisguisedPodmanSocket(provider);
await checkDisguisedPodmanSocket(provider);
// Update the status of the provider if the socket is changed, created or deleted
disguisedPodmanSocketWatcher = setupDisguisedPodmanSocketWatcher(provider, getSocketPath());
@ -620,7 +628,7 @@ export async function activate(extensionContext: extensionApi.ExtensionContext):
// provide an installation path ?
// add update information asynchronously
registerUpdatesIfAny(provider, installedPodman, podmanInstall);
await registerUpdatesIfAny(provider, installedPodman, podmanInstall);
// register autostart if enabled
if (isMac() || isWindows()) {
@ -669,7 +677,9 @@ export async function activate(extensionContext: extensionApi.ExtensionContext):
if (!fs.existsSync(podmanMachineSocketsDirectoryMac)) {
return;
}
monitorMachines(provider);
monitorMachines(provider).catch((error: unknown) => {
console.error('Error while monitoring machines', error);
});
} else if (isLinux()) {
// on Linux, need to run the system service for unlimited time
let command = 'podman';
@ -704,14 +714,20 @@ export async function activate(extensionContext: extensionApi.ExtensionContext):
podmanProcess.kill();
});
extensionContext.subscriptions.push(disposable);
initDefaultLinux(provider);
initDefaultLinux(provider).catch((error: unknown) => {
console.error('Error while initializing default linux', error);
});
} else if (isWindows()) {
monitorMachines(provider);
monitorMachines(provider).catch((error: unknown) => {
console.error('Error while monitoring machines', error);
});
}
// monitor provider
// like version, checks, warnings
monitorProvider(provider);
monitorProvider(provider).catch((error: unknown) => {
console.error('Error while monitoring provider', error);
});
// register the registries
const registrySetup = new RegistrySetup();
@ -847,8 +863,8 @@ function setupDisguisedPodmanSocketWatcher(
// and trigger a change if that happens
// Add the check to the listeners as well to make sure we check on podman status change as well
listeners.add(() => {
checkDisguisedPodmanSocket(provider);
listeners.add(async () => {
await checkDisguisedPodmanSocket(provider);
});
let socketWatcher: extensionApi.FileSystemWatcher;
@ -860,22 +876,22 @@ function setupDisguisedPodmanSocketWatcher(
}
// only trigger if the watched file is the socket file
const updateSocket = (uri: extensionApi.Uri) => {
const updateSocket = async (uri: extensionApi.Uri) => {
if (uri.fsPath === socketFile) {
checkDisguisedPodmanSocket(provider);
await checkDisguisedPodmanSocket(provider);
}
};
socketWatcher.onDidChange(uri => {
updateSocket(uri);
socketWatcher.onDidChange(async uri => {
await updateSocket(uri);
});
socketWatcher.onDidCreate(uri => {
updateSocket(uri);
socketWatcher.onDidCreate(async uri => {
await updateSocket(uri);
});
socketWatcher.onDidDelete(uri => {
updateSocket(uri);
socketWatcher.onDidDelete(async uri => {
await updateSocket(uri);
});
return socketWatcher;

View file

@ -1,5 +1,5 @@
/**********************************************************************
* Copyright (C) 2022 Red Hat, Inc.
* Copyright (C) 2022-2023 Red Hat, Inc.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
@ -37,16 +37,16 @@ export class PodmanConfiguration {
// we receive an update for the current proxy settings
extensionApi.proxy.onDidUpdateProxy(async (proxySettings: ProxySettings) => {
this.updateProxySettings(proxySettings);
await this.updateProxySettings(proxySettings);
});
// in case of proxy being enabled or disabled we need to update the containers.conf file
extensionApi.proxy.onDidStateChange(async (enabled: boolean) => {
if (enabled) {
const updatedProxySettings = extensionApi.proxy.getProxySettings();
this.updateProxySettings(updatedProxySettings);
await this.updateProxySettings(updatedProxySettings);
} else {
this.updateProxySettings(undefined);
await this.updateProxySettings(undefined);
}
});
@ -91,7 +91,7 @@ export class PodmanConfiguration {
extensionApi.proxy.isEnabled() &&
(httpsProxy || httpProxy || noProxy)
) {
extensionApi.proxy.setProxy(proxySettings);
await extensionApi.proxy.setProxy(proxySettings);
}
}

View file

@ -53,7 +53,7 @@ export class PodmanInfoImpl implements PodmanInfo {
set podmanVersion(version: string) {
if (this.podmanInfo.podmanVersion !== version) {
this.podmanInfo.podmanVersion = version;
this.writeInfo();
this.writeInfo().catch((err: unknown) => console.error('Unable to write Podman Version', err));
}
}
@ -64,7 +64,7 @@ export class PodmanInfoImpl implements PodmanInfo {
set lastUpdateCheck(lastCheck: number) {
if (this.podmanInfo.lastUpdateCheck !== lastCheck) {
this.podmanInfo.lastUpdateCheck = lastCheck;
this.writeInfo();
this.writeInfo().catch((err: unknown) => console.error('Unable to write Podman Version', err));
}
}
@ -79,7 +79,7 @@ export class PodmanInfoImpl implements PodmanInfo {
set ignoreVersionUpdate(version: string) {
if (this.podmanInfo.ignoreVersionUpdate !== version) {
this.podmanInfo.ignoreVersionUpdate = version;
this.writeInfo();
this.writeInfo().catch((err: unknown) => console.error('Unable to write Podman Version', err));
}
}

View file

@ -1,5 +1,5 @@
/**********************************************************************
* Copyright (C) 2022 Red Hat, Inc.
* Copyright (C) 2022-2023 Red Hat, Inc.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
@ -158,12 +158,12 @@ export class RegistrySetup {
}
// need to monitor this file
fs.watchFile(this.getAuthFileLocation(), () => {
this.updateRegistries(extensionContext);
fs.watchFile(this.getAuthFileLocation(), async () => {
await this.updateRegistries(extensionContext);
});
// else init with the content of this file
this.updateRegistries(extensionContext);
await this.updateRegistries(extensionContext);
}
protected async readAuthFile(): Promise<ContainersAuthConfigFile> {

View file

@ -412,7 +412,7 @@ declare module '@podman-desktop/api' {
export namespace proxy {
export function getProxySettings(): ProxySettings | undefined;
export function setProxy(proxySettings: ProxySettings): void;
export function setProxy(proxySettings: ProxySettings): Promise<void>;
// Podman Desktop has updated the settings, propagates the changes to the provider.
export const onDidUpdateProxy: Event<ProxySettings>;
@ -530,7 +530,7 @@ declare module '@podman-desktop/api' {
* Update a configuration value. The updated configuration values are persisted.
*/
// eslint-disable-next-line @typescript-eslint/no-explicit-any
update(section: string, value: any): PromiseLike<void>;
update(section: string, value: any): Promise<void>;
/**
* Readable dictionary that backs this configuration.

View file

@ -88,7 +88,9 @@ app.whenReady().then(
// Platforms: Linux, macOS, Windows
// Create the main window
createNewWindow();
createNewWindow().catch((error: unknown) => {
console.log('Error creating window', error);
});
// Platforms: macOS
// Required for macOS to start the app correctly (this is will be shown in the dock)

View file

@ -101,8 +101,8 @@ export class AuthenticationImpl {
return await Promise.all(providers);
}
public async signOut(providerId: string, sessionId: string) {
this.removeSession(providerId, sessionId);
public async signOut(providerId: string, sessionId: string): Promise<void> {
await this.removeSession(providerId, sessionId);
}
registerAuthenticationProvider(

View file

@ -1,5 +1,5 @@
/**********************************************************************
* Copyright (C) 2022 Red Hat, Inc.
* Copyright (C) 2022-2023 Red Hat, Inc.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
@ -47,13 +47,15 @@ export class AutostartEngine {
if (autostart) {
console.log('Autostarting container engine');
// send autostart
this.providerRegistry.runAutostart();
this.providerRegistry.runAutostart().catch((e: unknown) => {
console.error('Failed to autostart container engine', e);
});
}
// start the engine if we toggle the property
this.configurationRegistry.onDidChangeConfiguration(e => {
this.configurationRegistry.onDidChangeConfiguration(async e => {
if (e.key === 'preferences.engine.autostart' && e.value === true) {
this.providerRegistry.runAutostart();
await this.providerRegistry.runAutostart();
}
});
}

View file

@ -159,11 +159,13 @@ export class ContainerProviderRegistry {
const providerName = containerProviderConnection.name;
const id = `${provider.id}.${providerName}`;
this.containerProviders.set(id, containerProviderConnection);
this.telemetryService.track('registerContainerProviderConnection', {
name: containerProviderConnection.name,
type: containerProviderConnection.type,
total: this.containerProviders.size,
});
this.telemetryService
.track('registerContainerProviderConnection', {
name: containerProviderConnection.name,
type: containerProviderConnection.type,
total: this.containerProviders.size,
})
.catch((err: unknown) => console.error('Unable to track', err));
const internalProvider: InternalContainerProvider = {
id,
@ -244,7 +246,9 @@ export class ContainerProviderRegistry {
}),
);
const flatttenedContainers = containers.flat();
this.telemetryService.track('listSimpleContainers', { total: flatttenedContainers.length });
this.telemetryService
.track('listSimpleContainers', { total: flatttenedContainers.length })
.catch((err: unknown) => console.error('Unable to track', err));
return flatttenedContainers;
}
@ -325,7 +329,9 @@ export class ContainerProviderRegistry {
}),
);
const flatttenedContainers = containers.flat();
this.telemetryService.track('listContainers', { total: flatttenedContainers.length });
this.telemetryService
.track('listContainers', { total: flatttenedContainers.length })
.catch((err: unknown) => console.error('Unable to track', err));
return flatttenedContainers;
}
@ -348,13 +354,15 @@ export class ContainerProviderRegistry {
}),
);
const flatttenedImages = images.flat();
this.telemetryService.track('listImages', { total: flatttenedImages.length });
this.telemetryService
.track('listImages', { total: flatttenedImages.length })
.catch((err: unknown) => console.error('Unable to track', err));
return flatttenedImages;
}
async pruneImages(engineId: string): Promise<void> {
this.telemetryService.track('pruneImages');
this.telemetryService.track('pruneImages').catch((err: unknown) => console.error('Unable to track', err));
// We have to use two different API calls for pruning images, because the Podman API does not respect the 'dangling' filter
// and instead uses 'all' and 'external'. See: https://github.com/containers/podman/issues/11576
// so for Dockerode we'll have to call pruneImages with the 'dangling' filter, and for Podman we'll have to call pruneImages
@ -391,7 +399,9 @@ export class ContainerProviderRegistry {
}),
);
const flatttenedPods = pods.flat();
this.telemetryService.track('listPods', { total: flatttenedPods.length });
this.telemetryService
.track('listPods', { total: flatttenedPods.length })
.catch((err: unknown) => console.error('Unable to track', err));
return flatttenedPods;
}
@ -415,7 +425,9 @@ export class ContainerProviderRegistry {
}),
);
const flatttenedNetworks = networks.flat();
this.telemetryService.track('listNetworks', { total: flatttenedNetworks.length });
this.telemetryService
.track('listNetworks', { total: flatttenedNetworks.length })
.catch((err: unknown) => console.error('Unable to track', err));
return flatttenedNetworks;
}
@ -475,12 +487,14 @@ export class ContainerProviderRegistry {
}),
);
const flatttenedVolumes: VolumeListInfo[] = volumes.flat();
this.telemetryService.track('listVolumes', { total: flatttenedVolumes.length });
this.telemetryService
.track('listVolumes', { total: flatttenedVolumes.length })
.catch((err: unknown) => console.error('Unable to track', err));
return flatttenedVolumes;
}
async getVolumeInspect(engineId: string, volumeName: string): Promise<VolumeInspectInfo> {
this.telemetryService.track('volumeInspect');
this.telemetryService.track('volumeInspect').catch((err: unknown) => console.error('Unable to track', err));
// need to find the container engine of the container
const provider = this.internalProviders.get(engineId);
if (!provider) {
@ -499,7 +513,7 @@ export class ContainerProviderRegistry {
}
async removeVolume(engineId: string, volumeName: string): Promise<void> {
this.telemetryService.track('removeVolume');
this.telemetryService.track('removeVolume').catch((err: unknown) => console.error('Unable to track', err));
return this.getMatchingEngine(engineId).getVolume(volumeName).remove();
}
@ -588,12 +602,12 @@ export class ContainerProviderRegistry {
}
async stopContainer(engineId: string, id: string): Promise<void> {
this.telemetryService.track('stopContainer');
this.telemetryService.track('stopContainer').catch((err: unknown) => console.error('Unable to track', err));
return this.getMatchingContainer(engineId, id).stop();
}
async deleteImage(engineId: string, id: string): Promise<void> {
this.telemetryService.track('deleteImage');
this.telemetryService.track('deleteImage').catch((err: unknown) => console.error('Unable to track', err));
// use force to delete it even it is running
return this.getMatchingImage(engineId, id).remove({ force: true });
}
@ -610,7 +624,9 @@ export class ContainerProviderRegistry {
async pushImage(engineId: string, imageTag: string, callback: (name: string, data: string) => void): Promise<void> {
const engine = this.getMatchingEngine(engineId);
const image = engine.getImage(imageTag);
this.telemetryService.track('pushImage', { imageName: this.getImageHash(imageTag) });
this.telemetryService
.track('pushImage', { imageName: this.getImageHash(imageTag) })
.catch((err: unknown) => console.error('Unable to track', err));
const authconfig = this.imageRegistry.getAuthconfigForImage(imageTag);
const pushStream = await image.push({ authconfig });
pushStream.on('end', () => {
@ -631,7 +647,9 @@ export class ContainerProviderRegistry {
imageName: string,
callback: (event: PullEvent) => void,
): Promise<void> {
this.telemetryService.track('pullImage', { imageName: this.getImageHash(imageName) });
this.telemetryService
.track('pullImage', { imageName: this.getImageHash(imageName) })
.catch((err: unknown) => console.error('Unable to track', err));
const authconfig = this.imageRegistry.getAuthconfigForImage(imageName);
const matchingEngine = this.getMatchingEngineFromConnection(providerContainerConnectionInfo);
const pullStream = await matchingEngine.pull(imageName, {
@ -666,23 +684,23 @@ export class ContainerProviderRegistry {
}
async deleteContainer(engineId: string, id: string): Promise<void> {
this.telemetryService.track('deleteContainer');
this.telemetryService.track('deleteContainer').catch((err: unknown) => console.error('Unable to track', err));
// use force to delete it even it is running
return this.getMatchingContainer(engineId, id).remove({ force: true });
}
async startContainer(engineId: string, id: string): Promise<void> {
this.telemetryService.track('startContainer');
this.telemetryService.track('startContainer').catch((err: unknown) => console.error('Unable to track', err));
return this.getMatchingContainer(engineId, id).start();
}
async generatePodmanKube(engineId: string, names: string[]): Promise<string> {
this.telemetryService.track('generatePodmanKube');
this.telemetryService.track('generatePodmanKube').catch((err: unknown) => console.error('Unable to track', err));
return this.getMatchingPodmanEngine(engineId).generateKube(names);
}
async startPod(engineId: string, podId: string): Promise<void> {
this.telemetryService.track('startPod');
this.telemetryService.track('startPod').catch((err: unknown) => console.error('Unable to track', err));
return this.getMatchingPodmanEngine(engineId).startPod(podId);
}
@ -690,7 +708,7 @@ export class ContainerProviderRegistry {
selectedProvider: ProviderContainerConnectionInfo,
podOptions: PodCreateOptions,
): Promise<{ engineId: string; Id: string }> {
this.telemetryService.track('createPod');
this.telemetryService.track('createPod').catch((err: unknown) => console.error('Unable to track', err));
// grab all connections
const matchingContainerProvider = Array.from(this.internalProviders.values()).find(
containerProvider =>
@ -705,7 +723,7 @@ export class ContainerProviderRegistry {
}
async restartPod(engineId: string, podId: string): Promise<void> {
this.telemetryService.track('restartPod');
this.telemetryService.track('restartPod').catch((err: unknown) => console.error('Unable to track', err));
return this.getMatchingPodmanEngine(engineId).restartPod(podId);
}
@ -714,7 +732,9 @@ export class ContainerProviderRegistry {
target: { engineId: string },
overrideParameters: PodmanContainerCreateOptions,
): Promise<{ Id: string; Warnings: string[] }> {
this.telemetryService.track('replicatePodmanContainer');
this.telemetryService
.track('replicatePodmanContainer')
.catch((err: unknown) => console.error('Unable to track', err));
// will publish in the target engine
const libPod = this.getMatchingPodmanEngine(target.engineId);
@ -746,37 +766,37 @@ export class ContainerProviderRegistry {
}
async stopPod(engineId: string, podId: string): Promise<void> {
this.telemetryService.track('stopPod');
this.telemetryService.track('stopPod').catch((err: unknown) => console.error('Unable to track', err));
return this.getMatchingPodmanEngine(engineId).stopPod(podId);
}
async removePod(engineId: string, podId: string): Promise<void> {
this.telemetryService.track('removePod');
this.telemetryService.track('removePod').catch((err: unknown) => console.error('Unable to track', err));
return this.getMatchingPodmanEngine(engineId).removePod(podId);
}
async prunePods(engineId: string): Promise<void> {
this.telemetryService.track('prunePods');
this.telemetryService.track('prunePods').catch((err: unknown) => console.error('Unable to track', err));
return this.getMatchingPodmanEngine(engineId).prunePods();
}
async pruneContainers(engineId: string): Promise<Dockerode.PruneContainersInfo> {
this.telemetryService.track('pruneContainers');
this.telemetryService.track('pruneContainers').catch((err: unknown) => console.error('Unable to track', err));
return this.getMatchingEngine(engineId).pruneContainers();
}
async pruneVolumes(engineId: string): Promise<Dockerode.PruneVolumesInfo> {
this.telemetryService.track('pruneVolumes');
this.telemetryService.track('pruneVolumes').catch((err: unknown) => console.error('Unable to track', err));
return this.getMatchingEngine(engineId).pruneVolumes();
}
async restartContainer(engineId: string, id: string): Promise<void> {
this.telemetryService.track('restartContainer');
this.telemetryService.track('restartContainer').catch((err: unknown) => console.error('Unable to track', err));
return this.getMatchingContainer(engineId, id).restart();
}
async logsContainer(engineId: string, id: string, callback: (name: string, data: string) => void): Promise<void> {
this.telemetryService.track('logsContainer');
this.telemetryService.track('logsContainer').catch((err: unknown) => console.error('Unable to track', err));
let firstMessage = true;
const container = this.getMatchingContainer(engineId, id);
const containerStream = await container.logs({
@ -803,7 +823,7 @@ export class ContainerProviderRegistry {
id: string,
onData: (data: Buffer) => void,
): Promise<(param: string) => void> {
this.telemetryService.track('shellInContainer');
this.telemetryService.track('shellInContainer').catch((err: unknown) => console.error('Unable to track', err));
const exec = await this.getMatchingContainer(engineId, id).exec({
AttachStdin: true,
AttachStdout: true,
@ -836,13 +856,15 @@ export class ContainerProviderRegistry {
if (!engine.api) {
throw new Error('no running provider for the matching container');
}
this.telemetryService.track('createAndStartContainer');
this.telemetryService
.track('createAndStartContainer')
.catch((err: unknown) => console.error('Unable to track', err));
const container = await engine.api.createContainer(options);
return container.start();
}
async getImageInspect(engineId: string, id: string): Promise<ImageInspectInfo> {
this.telemetryService.track('imageInspect');
this.telemetryService.track('imageInspect').catch((err: unknown) => console.error('Unable to track', err));
// need to find the container engine of the container
const provider = this.internalProviders.get(engineId);
if (!provider) {
@ -861,7 +883,7 @@ export class ContainerProviderRegistry {
}
async getImageHistory(engineId: string, id: string): Promise<HistoryInfo[]> {
this.telemetryService.track('imageHistory');
this.telemetryService.track('imageHistory').catch((err: unknown) => console.error('Unable to track', err));
// need to find the container engine of the container
const provider = this.internalProviders.get(engineId);
if (!provider) {
@ -875,7 +897,7 @@ export class ContainerProviderRegistry {
}
async getContainerInspect(engineId: string, id: string): Promise<ContainerInspectInfo> {
this.telemetryService.track('containerInspect');
this.telemetryService.track('containerInspect').catch((err: unknown) => console.error('Unable to track', err));
// need to find the container engine of the container
const provider = this.internalProviders.get(engineId);
if (!provider) {
@ -895,7 +917,7 @@ export class ContainerProviderRegistry {
}
async saveImage(engineId: string, id: string, filename: string): Promise<void> {
this.telemetryService.track('imageSave');
this.telemetryService.track('imageSave').catch((err: unknown) => console.error('Unable to track', err));
// need to find the container engine of the container
const provider = this.internalProviders.get(engineId);
if (!provider) {
@ -913,7 +935,7 @@ export class ContainerProviderRegistry {
}
async getPodInspect(engineId: string, id: string): Promise<PodInspectInfo> {
this.telemetryService.track('podInspect');
this.telemetryService.track('podInspect').catch((err: unknown) => console.error('Unable to track', err));
// need to find the container engine of the container
const provider = this.internalProviders.get(engineId);
if (!provider) {
@ -948,7 +970,7 @@ export class ContainerProviderRegistry {
id: string,
callback: (stats: ContainerStatsInfo) => void,
): Promise<number> {
this.telemetryService.track('containerStats');
this.telemetryService.track('containerStats').catch((err: unknown) => console.error('Unable to track', err));
// need to find the container engine of the container
const provider = this.internalProviders.get(engineId);
if (!provider) {
@ -1000,7 +1022,7 @@ export class ContainerProviderRegistry {
kubernetesYamlFilePath: string,
selectedProvider: ProviderContainerConnectionInfo,
): Promise<PlayKubeInfo> {
this.telemetryService.track('playKube');
this.telemetryService.track('playKube').catch((err: unknown) => console.error('Unable to track', err));
// grab all connections
const matchingContainerProvider = Array.from(this.internalProviders.values()).find(
containerProvider =>
@ -1020,7 +1042,7 @@ export class ContainerProviderRegistry {
selectedProvider: ProviderContainerConnectionInfo,
eventCollect: (eventName: 'stream' | 'error' | 'finish', data: string) => void,
): Promise<unknown> {
this.telemetryService.track('buildImage');
this.telemetryService.track('buildImage').catch((err: unknown) => console.error('Unable to track', err));
// grab all connections
const matchingContainerProvider = Array.from(this.internalProviders.values()).find(
containerProvider =>

View file

@ -1,5 +1,5 @@
/**********************************************************************
* Copyright (C) 2022 Red Hat, Inc.
* Copyright (C) 2022-2023 Red Hat, Inc.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
@ -129,11 +129,11 @@ export class DockerDesktopInstallation {
});
return new Promise<void>((resolve, reject) => {
exportResult.on('close', () => {
exportResult.on('close', async () => {
fileWriteStream.close();
// ok we can remove the container
containerFromImage.remove().then(() => resolve(undefined));
await containerFromImage.remove().then(() => resolve(undefined));
});
exportResult.on('data', chunk => {

View file

@ -443,8 +443,8 @@ export class ExtensionLoader {
getProxySettings(): containerDesktopAPI.ProxySettings | undefined {
return proxyInstance.proxy;
},
setProxy(proxySettings: containerDesktopAPI.ProxySettings): void {
proxyInstance.setProxy(proxySettings);
async setProxy(proxySettings: containerDesktopAPI.ProxySettings): Promise<void> {
return proxyInstance.setProxy(proxySettings);
},
onDidUpdateProxy: (listener, thisArg, disposables) => {
return proxyInstance.onDidUpdateProxy(listener, thisArg, disposables);

View file

@ -142,10 +142,12 @@ export class ImageRegistry {
registerRegistry(registry: containerDesktopAPI.Registry): Disposable {
this.registries = [...this.registries, registry];
this.telemetryService.track('registerRegistry', {
serverUrl: this.getRegistryHash(registry),
total: this.registries.length,
});
this.telemetryService
.track('registerRegistry', {
serverUrl: this.getRegistryHash(registry),
total: this.registries.length,
})
.catch((err: unknown) => console.error('Unable to track', err));
this.apiSender.send('registry-register', registry);
this._onDidRegisterRegistry.fire(Object.freeze({ ...registry }));
return Disposable.create(() => {
@ -193,10 +195,12 @@ export class ImageRegistry {
this.registries = filtered;
this.apiSender.send('registry-unregister', registry);
}
this.telemetryService.track('unregisterRegistry', {
serverUrl: this.getRegistryHash(registry),
total: this.registries.length,
});
this.telemetryService
.track('unregisterRegistry', {
serverUrl: this.getRegistryHash(registry),
total: this.registries.length,
})
.catch((err: unknown) => console.error('Unable to track', err));
}
getRegistries(): readonly containerDesktopAPI.Registry[] {
@ -239,10 +243,12 @@ export class ImageRegistry {
registryCreateOptions.secret,
);
const registry = provider.create(registryCreateOptions);
this.telemetryService.track('createRegistry', {
serverUrlHash: this.getRegistryHash(registryCreateOptions),
total: this.registries.length,
});
this.telemetryService
.track('createRegistry', {
serverUrlHash: this.getRegistryHash(registryCreateOptions),
total: this.registries.length,
})
.catch((err: unknown) => console.error('Unable to track', err));
return this.registerRegistry(registry);
}
@ -259,10 +265,12 @@ export class ImageRegistry {
}
matchingRegistry.username = registry.username;
matchingRegistry.secret = registry.secret;
this.telemetryService.track('updateRegistry', {
serverUrl: this.getRegistryHash(matchingRegistry),
total: this.registries.length,
});
this.telemetryService
.track('updateRegistry', {
serverUrl: this.getRegistryHash(matchingRegistry),
total: this.registries.length,
})
.catch((err: unknown) => console.error('Unable to track', err));
this.apiSender.send('registry-update', registry);
this._onDidUpdateRegistry.fire(Object.freeze(registry));
}

View file

@ -289,7 +289,7 @@ export class PluginSystem {
);
if (skipConfirmationUrl) {
shell.openExternal(url);
await shell.openExternal(url);
return true;
}
@ -304,7 +304,7 @@ export class PluginSystem {
if (result.response === 0) {
// open externally the URL
shell.openExternal(url);
await shell.openExternal(url);
return true;
} else if (result.response === 1) {
// copy to clipboard
@ -430,8 +430,8 @@ export class PluginSystem {
// Register command 'version' that will display the current version and say that no update is available.
// Only show the "no update available" command for macOS and Windows users, not linux users.
commandRegistry.registerCommand('version', () => {
messageBox.showMessageBox({
commandRegistry.registerCommand('version', async () => {
await messageBox.showMessageBox({
type: 'info',
title: 'Version',
message: `Using version ${currentVersion}`,
@ -564,7 +564,7 @@ export class PluginSystem {
await autoUpdater.downloadUpdate();
} catch (error) {
console.error('Update error: ', error);
messageBox.showMessageBox({
await messageBox.showMessageBox({
type: 'error',
title: 'Update Failed',
message: `An error occurred while trying to update to version ${updateVersion}. See the developer console for more information.`,
@ -1248,7 +1248,7 @@ export class PluginSystem {
if (securityRestrictionCurrentHandler.handler) {
await securityRestrictionCurrentHandler.handler(link);
} else {
shell.openExternal(link);
await shell.openExternal(link);
}
},
);
@ -1575,7 +1575,7 @@ export class PluginSystem {
apiSender.send('extensions-started');
this.markAsExtensionsStarted();
}
autoStartConfiguration.start();
autoStartConfiguration.start().catch((err: unknown) => console.error('Unable to perform autostart', err));
return this.extensionLoader;
}

View file

@ -1,5 +1,5 @@
/**********************************************************************
* Copyright (C) 2022 Red Hat, Inc.
* Copyright (C) 2022-2023 Red Hat, Inc.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
@ -171,11 +171,11 @@ export class KubernetesClient {
}
// Update the property on change
this.configurationRegistry.onDidChangeConfiguration(e => {
this.configurationRegistry.onDidChangeConfiguration(async e => {
if (e.key === 'kubernetes.Kubeconfig') {
const val = e.value as string;
this.setupWatcher(val);
this.setKubeconfig(Uri.file(val));
await this.setKubeconfig(Uri.file(val));
}
});
}
@ -218,7 +218,8 @@ export class KubernetesClient {
() => this.apiSender.send('pod-event'),
(err: unknown) => console.error('Kube event error', err),
)
.then(req => (this.kubeWatcher = req));
.then(req => (this.kubeWatcher = req))
.catch((err: unknown) => console.error('Kube event error', err));
}
}
@ -417,7 +418,7 @@ export class KubernetesClient {
callback('data', chunk.toString('utf-8'));
});
log.log(ns, name, container, logStream, { follow: true });
await log.log(ns, name, container, logStream, { follow: true });
}
}
@ -425,7 +426,7 @@ export class KubernetesClient {
const ns = this.currentNamespace;
if (ns) {
const k8sApi = this.kubeConfig.makeApiClient(CoreV1Api);
k8sApi.deleteNamespacedPod(name, ns);
await k8sApi.deleteNamespacedPod(name, ns);
}
}

View file

@ -69,7 +69,7 @@ export class ProgressImpl {
);
}
withWidget<R>(
async withWidget<R>(
options: extensionApi.ProgressOptions,
task: (
progress: extensionApi.Progress<{ message?: string; increment?: number }>,
@ -91,11 +91,12 @@ export class ProgressImpl {
},
new CancellationTokenImpl(),
);
task_.then(() => {
await task_.then(async () => {
t.status = 'success';
t.state = 'completed';
this.taskManager.updateTask(t);
});
task_.catch((err: unknown) => {
t.status = 'failure';
t.state = 'completed';

View file

@ -34,6 +34,7 @@ const apiSenderSendMock = vi.fn();
beforeEach(() => {
vi.clearAllMocks();
telemetryTrackMock.mockImplementation(() => Promise.resolve());
const telemetry: Telemetry = {
track: telemetryTrackMock,
} as unknown as Telemetry;

View file

@ -1,5 +1,5 @@
/**********************************************************************
* Copyright (C) 2022 Red Hat, Inc.
* Copyright (C) 2022-2023 Red Hat, Inc.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
@ -178,7 +178,9 @@ export class ProviderRegistry {
if (providerOptions.version) {
trackOpts.version = providerOptions.version;
}
this.telemetryService.track('createProvider', trackOpts);
this.telemetryService
.track('createProvider', trackOpts)
.catch((err: unknown) => console.error('Unable to track', err));
this.apiSender.send('provider-create', id);
providerImpl.onDidUpdateVersion(() => this.apiSender.send('provider:update-version'));
return providerImpl;
@ -404,9 +406,11 @@ export class ProviderRegistry {
if (!providerInstall) {
throw new Error(`No matching installation for provider ${provider.internalId}`);
}
this.telemetryService.track('installProvider', {
name: provider.name,
});
this.telemetryService
.track('installProvider', {
name: provider.name,
})
.catch((err: unknown) => console.error('Unable to track', err));
return providerInstall.install(new LoggerImpl());
}
@ -418,9 +422,11 @@ export class ProviderRegistry {
throw new Error(`No matching update for provider ${provider.internalId}`);
}
this.telemetryService.track('updateProvider', {
name: provider.name,
});
this.telemetryService
.track('updateProvider', {
name: provider.name,
})
.catch((err: unknown) => console.error('Unable to track', err));
return providerUpdate.update(new LoggerImpl());
}
@ -464,17 +470,21 @@ export class ProviderRegistry {
}
if (provider.containerProviderConnectionFactory && provider.containerProviderConnectionFactory.initialize) {
this.telemetryService.track('initializeProvider', {
name: provider.name,
});
this.telemetryService
.track('initializeProvider', {
name: provider.name,
})
.catch((err: unknown) => console.error('Unable to track', err));
return provider.containerProviderConnectionFactory.initialize();
}
if (provider.kubernetesProviderConnectionFactory && provider.kubernetesProviderConnectionFactory.initialize) {
this.telemetryService.track('initializeProvider', {
name: provider.name,
});
this.telemetryService
.track('initializeProvider', {
name: provider.name,
})
.catch((err: unknown) => console.error('Unable to track', err));
return provider.kubernetesProviderConnectionFactory.initialize();
}
@ -873,7 +883,9 @@ export class ProviderRegistry {
if (!lifecycle || !lifecycle.delete) {
throw new Error('The container connection does not support delete lifecycle');
}
this.telemetryService.track('deleteProviderConnection', { name: providerConnectionInfo.name });
this.telemetryService
.track('deleteProviderConnection', { name: providerConnectionInfo.name })
.catch((err: unknown) => console.error('Unable to track', err));
return lifecycle.delete(logHandler);
}
@ -971,10 +983,12 @@ export class ProviderRegistry {
const providerName = kubernetesProviderConnection.name;
const id = `${provider.id}.${providerName}`;
this.kubernetesProviders.set(id, kubernetesProviderConnection);
this.telemetryService.track('registerKubernetesProviderConnection', {
name: kubernetesProviderConnection.name,
total: this.kubernetesProviders.size,
});
this.telemetryService
.track('registerKubernetesProviderConnection', {
name: kubernetesProviderConnection.name,
total: this.kubernetesProviders.size,
})
.catch((err: unknown) => console.error('Unable to track', err));
let previousStatus = kubernetesProviderConnection.status();

View file

@ -97,7 +97,7 @@ export class Proxy {
this.proxyState = isEnabled;
}
setProxy(proxy: ProxySettings): void {
async setProxy(proxy: ProxySettings): Promise<void> {
// notify
this._onDidUpdateProxy.fire(proxy);
@ -106,9 +106,9 @@ export class Proxy {
// update configuration
const proxyConfiguration = this.configurationRegistry.getConfiguration('proxy');
proxyConfiguration.update('http', proxy.httpProxy);
proxyConfiguration.update('https', proxy.httpsProxy);
proxyConfiguration.update('no', proxy.noProxy);
await proxyConfiguration.update('http', proxy.httpProxy);
await proxyConfiguration.update('https', proxy.httpsProxy);
await proxyConfiguration.update('no', proxy.noProxy);
}
get proxy(): ProxySettings | undefined {
@ -124,7 +124,9 @@ export class Proxy {
// update configuration
const proxyConfiguration = this.configurationRegistry.getConfiguration('proxy');
proxyConfiguration.update('enabled', state);
proxyConfiguration.update('enabled', state).catch((err: unknown) => {
console.error('Error updating proxy state', err);
});
// notify
this._onDidStateChange.fire(this.proxyState);

View file

@ -159,13 +159,17 @@ export class Telemetry {
return {
// prefix with extension id the event
sendEventData(eventName: string, data?: Record<string, unknown>): void {
thisArg.track.apply(thisArg, [`${extensionInfo.id}.${eventName}`, data]);
thisArg.track.apply(thisArg, [`${extensionInfo.id}.${eventName}`, data]).catch((err: unknown) => {
console.log(`Error sending event ${eventName}: ${err}`);
});
},
// report using the id of the extension suffixed by error
sendErrorData(error: Error, data?: Record<string, unknown>): void {
data = data || {};
data.sourceError = error.message;
thisArg.track.apply(thisArg, [`${extensionInfo.id}.error`, data]);
thisArg.track.apply(thisArg, [`${extensionInfo.id}.error`, data]).catch((err: unknown) => {
console.log(`Error sending error event: ${err}`);
});
},
async flush(): Promise<void> {
await instanceFlush?.();
@ -203,7 +207,9 @@ export class Telemetry {
await this.initTelemetry();
this.internalTrack(STARTUP_EVENT_TYPE);
this.internalTrack(STARTUP_EVENT_TYPE).catch((err: unknown) => {
console.log(`Error sending startup event: ${err}`);
});
let sendShutdownAnalytics = false;
app.on('before-quit', async e => {
@ -222,7 +228,9 @@ export class Telemetry {
// send all pending items
this.pendingItems.forEach(item => {
this.internalTrack(item.eventName, item.properties);
this.internalTrack(item.eventName, item.properties).catch((err: unknown) => {
console.log(`Error sending pending event: ${err}`);
});
});
this.pendingItems.length = 0;
this.telemetryConfigured = true;
@ -294,14 +302,18 @@ export class Telemetry {
if (!this.telemetryEnabled) {
return;
}
this.internalTrack(event, eventProperties);
this.internalTrack(event, eventProperties).catch((err: unknown) => {
console.log(`Error sending event: ${event}`, err);
});
}
async sendFeedback(feedbackProperties: unknown): Promise<void> {
if (!this.telemetryConfigured) {
await this.initTelemetry();
}
this.internalTrack('feedback', feedbackProperties);
this.internalTrack('feedback', feedbackProperties).catch((err: unknown) => {
console.log(`Error sending feedback event: ${err}`);
});
}
protected async getLocale(): Promise<string> {

View file

@ -1,5 +1,5 @@
/**********************************************************************
* Copyright (C) 2022 Red Hat, Inc.
* Copyright (C) 2022-2023 Red Hat, Inc.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
@ -77,21 +77,21 @@ export class TrayMenuRegistry {
);
ipcMain.on('tray:menu-item-click', (_, menuItemId: string, label: string) => {
try {
this.commandRegistry.executeCommand(menuItemId, label);
} catch (err) {
this.commandRegistry.executeCommand(menuItemId, label).catch((err: unknown) => {
console.error(err);
}
});
});
ipcMain.on('tray:menu-provider-click', (_, param: { action: string; providerInfo: ProviderInfo }) => {
this.telemetryService.track('tray:menu-provider-click', { action: param.action, name: param.providerInfo.name });
ipcMain.on('tray:menu-provider-click', async (_, param: { action: string; providerInfo: ProviderInfo }) => {
this.telemetryService
.track('tray:menu-provider-click', { action: param.action, name: param.providerInfo.name })
.catch((err: unknown) => console.error('Unable to track', err));
const provider = this.providers.get(param.providerInfo.internalId);
if (provider) {
if (param.action === 'Start') {
providerRegistry.startProviderLifecycle(param.providerInfo.internalId);
return providerRegistry.startProviderLifecycle(param.providerInfo.internalId);
} else if (param.action === 'Stop') {
providerRegistry.stopProviderLifecycle(param.providerInfo.internalId);
return providerRegistry.stopProviderLifecycle(param.providerInfo.internalId);
}
}
});
@ -106,10 +106,12 @@ export class TrayMenuRegistry {
providerContainerConnectionInfo: ProviderContainerConnectionInfo;
},
) => {
this.telemetryService.track('tray:menu-provider-container-connection-click', {
action: param.action,
name: param.providerContainerConnectionInfo.name,
});
this.telemetryService
.track('tray:menu-provider-container-connection-click', {
action: param.action,
name: param.providerContainerConnectionInfo.name,
})
.catch((err: unknown) => console.error('Unable to track', err));
const provider = this.providers.get(param.providerInfo.internalId);
if (provider) {

View file

@ -1,5 +1,5 @@
/**********************************************************************
* Copyright (C) 2022 Red Hat, Inc.
* Copyright (C) 2022-2023 Red Hat, Inc.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
@ -89,12 +89,12 @@ export class StartupInstall {
// add notification handling
this.configurationRegistry.onDidChangeConfiguration(e => {
this.configurationRegistry.onDidChangeConfiguration(async e => {
if (e.key === 'preferences.login.start') {
if (e.value === true) {
this.enableStartupOnLogin();
await this.enableStartupOnLogin();
} else {
this.disableStartupOnLogin();
await this.disableStartupOnLogin();
}
}
// If the "minimize on start" option has changed, we need to update the startup configuration
@ -103,7 +103,7 @@ export class StartupInstall {
const dashboardConfiguration = this.configurationRegistry.getConfiguration('preferences.login');
const enabled = dashboardConfiguration.get<boolean>('start');
if (enabled) {
this.enableStartupOnLogin();
await this.enableStartupOnLogin();
}
}
});

View file

@ -1,5 +1,5 @@
/**********************************************************************
* Copyright (C) 2022 Red Hat, Inc.
* Copyright (C) 2022-2023 Red Hat, Inc.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
@ -407,7 +407,9 @@ export class TrayMenu {
}
window?.show();
if (isMac()) {
app.dock.show();
app.dock.show().catch((error: unknown) => {
console.error('Error while showing dock', error);
});
}
window?.focus();
window?.moveTop();

View file

@ -1,5 +1,5 @@
/**********************************************************************
* Copyright (C) 2022 Red Hat, Inc.
* Copyright (C) 2022-2023 Red Hat, Inc.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
@ -143,7 +143,9 @@ export class DockerExtensionPreload {
const execProcess: dockerDesktopAPI.ExecProcess = {
close(): void {
// send abort on the remote side
ipcRenderer.invoke('docker-plugin-adapter:execAbort', callbackId);
ipcRenderer.invoke('docker-plugin-adapter:execAbort', callbackId).catch((err: unknown) => {
console.error('docker-plugin-adapter:execAbort', err);
});
},
};
return execProcess;
@ -214,16 +216,22 @@ export class DockerExtensionPreload {
const toast: dockerDesktopAPI.Toast = {
success(msg: string): void {
console.info('docker-desktop-adapter:toast:success', msg);
ipcRenderer.invoke('docker-desktop-adapter:desktopUIToast', 'success', msg);
ipcRenderer.invoke('docker-desktop-adapter:desktopUIToast', 'success', msg).catch((err: unknown) => {
console.error('docker-desktop-adapter:toast:success:error', err);
});
},
warning(msg: string): void {
console.warn('docker-desktop-adapter:toast:warning', msg);
ipcRenderer.invoke('docker-desktop-adapter:desktopUIToast', 'warning', msg);
ipcRenderer.invoke('docker-desktop-adapter:desktopUIToast', 'warning', msg).catch((err: unknown) => {
console.error('docker-desktop-adapter:toast:warning', err);
});
},
error(msg: string): void {
console.error('docker-desktop-adapter:toast:error', msg);
ipcRenderer.invoke('docker-desktop-adapter:desktopUIToast', 'error', msg);
ipcRenderer.invoke('docker-desktop-adapter:desktopUIToast', 'error', msg).catch((err: unknown) => {
console.error('docker-desktop-adapter:toast:error', err);
});
},
};
@ -356,7 +364,9 @@ export class DockerExtensionPreload {
const toastError = (error: Error) => {
console.error(error);
ipcRenderer.invoke('docker-desktop-adapter:desktopUIToast', 'error', error?.toString());
ipcRenderer.invoke('docker-desktop-adapter:desktopUIToast', 'error', error?.toString()).catch((err: unknown) => {
console.error('docker-desktop-adapter:desktopUIToast', err);
});
};
(result as any).toastError = toastError;

View file

@ -38,9 +38,9 @@ export class TelemetryService {
this.handlerFlusher = undefined;
}
this.handlerFlusher = setTimeout(() => {
this.handlerFlusher = setTimeout(async () => {
if (window.telemetryPage) {
window.telemetryPage(pagePath);
await window.telemetryPage(pagePath);
}
}, 200);
}

View file

@ -34,7 +34,9 @@ beforeAll(() => {
(window as any).getConfigurationValue = vi.fn();
(window as any).updateConfigurationValue = vi.fn();
(window as any).getContributedMenus = vi.fn();
(window as any).onDidUpdateProviderStatus = vi.fn();
const onDidUpdateProviderStatusMock = vi.fn();
(window as any).onDidUpdateProviderStatus = onDidUpdateProviderStatusMock;
onDidUpdateProviderStatusMock.mockImplementation(() => Promise.resolve());
(window as any).hasAuthconfigForImage = vi.fn();
(window as any).hasAuthconfigForImage.mockImplementation(() => Promise.resolve(false));

View file

@ -77,13 +77,13 @@ test('Expect that page shows registered authentication providers with account as
expect(signoutButton).toBeEnabled();
});
test('Expect Sign Out button click calls window.requestAuthenticationProviderSignOut with provider and account ids', () => {
test('Expect Sign Out button click calls window.requestAuthenticationProviderSignOut with provider and account ids', async () => {
authenticationProviders.set(testProvidersInfo);
render(PreferencesAuthenticationProvidersRendering, {});
const signoutButton = screen.getByRole('button', { name: `Sign out of ${testProvidersInfo[0].accounts[0].label}` });
const requestSignOutMock = vi.fn().mockImplementation(() => {});
(window as any).requestAuthenticationProviderSignOut = requestSignOutMock;
fireEvent.click(signoutButton);
await fireEvent.click(signoutButton);
expect(requestSignOutMock).toBeCalledWith('test', 'test-account');
});
@ -125,13 +125,13 @@ test('Expect Sign in menu item to be visible when there are session requests', a
render(PreferencesAuthenticationProvidersRendering, {});
const menuButton = screen.getAllByRole('button');
expect(menuButton.length).equals(1); // menu button
fireEvent.click(menuButton[0]);
await fireEvent.click(menuButton[0]);
render(PreferencesAuthenticationProvidersRendering, {});
const menuItems = screen.getAllByText('Sign in to use Extension Label');
expect(menuItems.length).equals(1);
const requestSignInMock = vi.fn();
(window as any).requestAuthenticationProviderSignIn = requestSignInMock;
fireEvent.click(menuItems[0]);
await fireEvent.click(menuItems[0]);
expect(requestSignInMock).toBeCalled();
});

View file

@ -34,7 +34,9 @@ beforeAll(() => {
(window as any).getConfigurationValue = vi.fn();
(window as any).updateConfigurationValue = vi.fn();
(window as any).getContributedMenus = vi.fn();
(window as any).onDidUpdateProviderStatus = vi.fn();
const onDidUpdateProviderStatusMock = vi.fn();
(window as any).onDidUpdateProviderStatus = onDidUpdateProviderStatusMock;
onDidUpdateProviderStatusMock.mockImplementation(() => Promise.resolve());
(window as any).listVolumes = listVolumesMock;
(window as any).listImages = vi.fn();

View file

@ -25,8 +25,8 @@ export class WelcomeUtils {
return window.getConfigurationValue<string>(WelcomeSettings.SectionName + '.' + WelcomeSettings.Version);
}
updateVersion(val: string) {
window.updateConfigurationValue(
async updateVersion(val: string): Promise<void> {
await window.updateConfigurationValue(
WelcomeSettings.SectionName + '.' + WelcomeSettings.Version,
val,
CONFIGURATION_DEFAULT_SCOPE,
@ -41,17 +41,19 @@ export class WelcomeUtils {
console.log('Telemetry enablement: ' + telemetry);
// store if the user said yes or no to telemetry
window.updateConfigurationValue(
await window.updateConfigurationValue(
TelemetrySettings.SectionName + '.' + TelemetrySettings.Enabled,
telemetry,
CONFIGURATION_DEFAULT_SCOPE,
);
// trigger telemetry system initialization
if (telemetry) window.telemetryConfigure();
if (telemetry) {
await window.telemetryConfigure();
}
// save the fact that we've prompted
window.updateConfigurationValue(
await window.updateConfigurationValue(
TelemetrySettings.SectionName + '.' + TelemetrySettings.Check,
true,
CONFIGURATION_DEFAULT_SCOPE,

View file

@ -31,15 +31,15 @@ export async function fetchConfigurationProperties() {
export const configurationProperties: Writable<IConfigurationPropertyRecordedSchema[]> = writable([]);
window.events?.receive('extensions-started', () => {
fetchConfigurationProperties();
window.events?.receive('extensions-started', async () => {
await fetchConfigurationProperties();
});
window.events?.receive('extension-started', () => {
fetchConfigurationProperties();
window.events?.receive('extension-started', async () => {
await fetchConfigurationProperties();
});
window.events?.receive('extension-stopped', () => {
fetchConfigurationProperties();
window.events?.receive('extension-stopped', async () => {
await fetchConfigurationProperties();
});
window.addEventListener('system-ready', () => {
fetchConfigurationProperties();
window.addEventListener('system-ready', async () => {
await fetchConfigurationProperties();
});

View file

@ -41,40 +41,40 @@ export const filtered = derived([searchPattern, containersInfos], ([$searchPatte
);
// need to refresh when extension is started
window.events?.receive('extension-started', () => {
fetchContainers();
window.events?.receive('extension-started', async () => {
await fetchContainers();
});
window.addEventListener('tray:update-provider', () => {
fetchContainers();
window.addEventListener('tray:update-provider', async () => {
await fetchContainers();
});
window.events?.receive('container-stopped-event', () => {
fetchContainers();
window.events?.receive('container-stopped-event', async () => {
await fetchContainers();
});
window.events?.receive('container-die-event', () => {
fetchContainers();
window.events?.receive('container-die-event', async () => {
await fetchContainers();
});
window.events?.receive('container-kill-event', () => {
fetchContainers();
window.events?.receive('container-kill-event', async () => {
await fetchContainers();
});
window.events?.receive('container-started-event', () => {
fetchContainers();
window.events?.receive('container-started-event', async () => {
await fetchContainers();
});
window.events?.receive('container-removed-event', () => {
fetchContainers();
window.events?.receive('container-removed-event', async () => {
await fetchContainers();
});
window.events?.receive('provider-change', () => {
fetchContainers();
window.events?.receive('provider-change', async () => {
await fetchContainers();
});
window.events?.receive('pod-event', () => {
fetchContainers();
window.events?.receive('pod-event', async () => {
await fetchContainers();
});
window?.events?.receive('extensions-started', async () => {

View file

@ -28,13 +28,13 @@ export async function fetchContributions() {
export const contributions: Writable<readonly ContributionInfo[]> = writable([]);
// need to refresh when new registry are updated/deleted
window.events?.receive('contribution-register', () => {
fetchContributions();
window.events?.receive('contribution-register', async () => {
await fetchContributions();
});
window.events?.receive('contribution-unregister', () => {
fetchContributions();
window.events?.receive('contribution-unregister', async () => {
await fetchContributions();
});
window.addEventListener('system-ready', () => {
fetchContributions();
window.addEventListener('system-ready', async () => {
await fetchContributions();
});

View file

@ -29,24 +29,24 @@ export async function fetchExtensions() {
export const extensionInfos: Writable<ExtensionInfo[]> = writable([]);
// need to refresh when extension is started or stopped
window?.events?.receive('extension-starting', () => {
fetchExtensions();
window?.events?.receive('extension-starting', async () => {
await fetchExtensions();
});
window?.events?.receive('extension-started', () => {
fetchExtensions();
window?.events?.receive('extension-started', async () => {
await fetchExtensions();
});
window?.events?.receive('extension-stopping', () => {
fetchExtensions();
window?.events?.receive('extension-stopping', async () => {
await fetchExtensions();
});
window?.events?.receive('extension-stopped', () => {
fetchExtensions();
window?.events?.receive('extension-stopped', async () => {
await fetchExtensions();
});
window?.events?.receive('extension-removed', () => {
fetchExtensions();
window?.events?.receive('extension-removed', async () => {
await fetchExtensions();
});
window?.events?.receive('extensions-started', () => {
fetchExtensions();
window?.events?.receive('extensions-started', async () => {
await fetchExtensions();
});
window.addEventListener('system-ready', () => {
fetchExtensions();
window.addEventListener('system-ready', async () => {
await fetchExtensions();
});

View file

@ -41,44 +41,44 @@ export const filtered = derived([searchPattern, imagesInfos], ([$searchPattern,
);
// need to refresh when extension is started or stopped
window?.events?.receive('extension-started', () => {
fetchImages();
window?.events?.receive('extension-started', async () => {
await fetchImages();
});
window?.events?.receive('extension-stopped', () => {
fetchImages();
window?.events?.receive('extension-stopped', async () => {
await fetchImages();
});
window.addEventListener('image-build', () => {
fetchImages();
window.addEventListener('image-build', async () => {
await fetchImages();
});
window?.events?.receive('provider-change', () => {
fetchImages();
window?.events?.receive('provider-change', async () => {
await fetchImages();
});
window.events?.receive('image-pull-event', () => {
fetchImages();
window.events?.receive('image-pull-event', async () => {
await fetchImages();
});
window.events?.receive('image-remove-event', () => {
fetchImages();
window.events?.receive('image-remove-event', async () => {
await fetchImages();
});
window.events?.receive('image-build-event', () => {
fetchImages();
window.events?.receive('image-build-event', async () => {
await fetchImages();
});
window.events?.receive('registry-register', () => {
fetchImages();
window.events?.receive('registry-register', async () => {
await fetchImages();
});
window.events?.receive('registry-unregister', () => {
fetchImages();
window.events?.receive('registry-unregister', async () => {
await fetchImages();
});
window.events?.receive('image-tag-event', () => {
fetchImages();
window.events?.receive('image-tag-event', async () => {
await fetchImages();
});
window.events?.receive('image-untag-event', () => {
fetchImages();
window.events?.receive('image-untag-event', async () => {
await fetchImages();
});
window?.events?.receive('extensions-started', async () => {

View file

@ -46,35 +46,35 @@ export const filtered = derived([searchPattern, podsInfos], ([$searchPattern, $i
});
// need to refresh when extension is started or stopped
window.events?.receive('extension-started', () => {
fetchPods();
window.events?.receive('extension-started', async () => {
await fetchPods();
});
window.events?.receive('extension-stopped', () => {
fetchPods();
window.events?.receive('extension-stopped', async () => {
await fetchPods();
});
window.events?.receive('container-stopped-event', () => {
fetchPods();
window.events?.receive('container-stopped-event', async () => {
await fetchPods();
});
window.events?.receive('container-die-event', () => {
fetchPods();
window.events?.receive('container-die-event', async () => {
await fetchPods();
});
window.events?.receive('container-kill-event', () => {
fetchPods();
window.events?.receive('container-kill-event', async () => {
await fetchPods();
});
window.events?.receive('container-started-event', () => {
fetchPods();
window.events?.receive('container-started-event', async () => {
await fetchPods();
});
window.events?.receive('provider-change', () => {
fetchPods();
window.events?.receive('provider-change', async () => {
await fetchPods();
});
window.events?.receive('pod-event', () => {
fetchPods();
window.events?.receive('pod-event', async () => {
await fetchPods();
});
window?.events?.receive('extensions-started', async () => {

View file

@ -26,9 +26,13 @@ export async function fetchProviders() {
result.forEach(providerInfo => {
// register only if none for this provider id
if (!updateProviderCallbacks.includes(providerInfo.internalId)) {
window.onDidUpdateProviderStatus(providerInfo.internalId, () => {
fetchProviders();
});
window
.onDidUpdateProviderStatus(providerInfo.internalId, async () => {
await fetchProviders();
})
.catch((err: unknown) => {
console.error('Failed to register onDidUpdateProviderStatus callback', err);
});
updateProviderCallbacks.push(providerInfo.internalId);
}
});
@ -37,48 +41,48 @@ export async function fetchProviders() {
export const providerInfos: Writable<ProviderInfo[]> = writable([]);
// need to refresh when extension is started or stopped
window?.events?.receive('extension-started', () => {
fetchProviders();
window?.events?.receive('extension-started', async () => {
await fetchProviders();
});
window?.events?.receive('extension-stopped', () => {
fetchProviders();
window?.events?.receive('extension-stopped', async () => {
await fetchProviders();
});
window.addEventListener('provider-lifecycle-change', () => {
fetchProviders();
window.addEventListener('provider-lifecycle-change', async () => {
await fetchProviders();
});
window?.events?.receive('provider-lifecycle-change', () => {
fetchProviders();
window?.events?.receive('provider-lifecycle-change', async () => {
await fetchProviders();
});
window?.events?.receive('provider-change', () => {
fetchProviders();
window?.events?.receive('provider-change', async () => {
await fetchProviders();
});
window?.events?.receive('provider-create', () => {
fetchProviders();
window?.events?.receive('provider-create', async () => {
await fetchProviders();
});
window?.events?.receive('provider-delete', () => {
fetchProviders();
window?.events?.receive('provider-delete', async () => {
await fetchProviders();
});
window?.events?.receive('provider:update-status', () => {
fetchProviders();
window?.events?.receive('provider:update-status', async () => {
await fetchProviders();
});
window?.events?.receive('provider:update-warnings', () => {
fetchProviders();
window?.events?.receive('provider:update-warnings', async () => {
await fetchProviders();
});
window?.events?.receive('provider:update-version', () => {
fetchProviders();
window?.events?.receive('provider:update-version', async () => {
await fetchProviders();
});
window.addEventListener('system-ready', () => {
fetchProviders();
window.addEventListener('system-ready', async () => {
await fetchProviders();
});
window?.events?.receive('provider-register-kubernetes-connection', () => {
fetchProviders();
window?.events?.receive('provider-register-kubernetes-connection', async () => {
await fetchProviders();
});
window?.events?.receive('provider-unregister-kubernetes-connection', () => {
fetchProviders();
window?.events?.receive('provider-unregister-kubernetes-connection', async () => {
await fetchProviders();
});
window.events?.receive('extensions-started', () => {
fetchProviders();
window.events?.receive('extensions-started', async () => {
await fetchProviders();
});

View file

@ -56,22 +56,22 @@ export const registriesSuggestedInfos: Writable<readonly containerDesktopAPI.Reg
export const searchPattern = writable('');
// need to refresh when new registry are updated/deleted
window.events?.receive('registry-register', () => {
fetchRegistries();
window.events?.receive('registry-register', async () => {
await fetchRegistries();
});
window.events?.receive('registry-unregister', () => {
fetchRegistries();
window.events?.receive('registry-unregister', async () => {
await fetchRegistries();
});
window.events?.receive('registry-update', () => {
fetchRegistries();
window.events?.receive('registry-update', async () => {
await fetchRegistries();
});
window.addEventListener('system-ready', () => {
fetchRegistries();
window.addEventListener('system-ready', async () => {
await fetchRegistries();
});
window.events?.receive('extensions-started', () => {
fetchRegistries();
window.events?.receive('extensions-started', async () => {
await fetchRegistries();
});

View file

@ -31,6 +31,6 @@ export const statusBarEntries: Writable<readonly StatusBarEntryDescriptor[]> = w
window.events?.receive(STATUS_BAR_UPDATED_EVENT_NAME, async () => {
await fetchRenderModel();
});
window.addEventListener('system-ready', () => {
fetchRenderModel();
window.addEventListener('system-ready', async () => {
await fetchRenderModel();
});