feat: add removeManifest API (#8127)

This commit is contained in:
Charlie Drage 2024-07-18 14:16:57 -04:00 committed by GitHub
parent 5a3f29c8b3
commit 86c7ee8b7d
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
8 changed files with 94 additions and 0 deletions

View file

@ -3670,6 +3670,7 @@ declare module '@podman-desktop/api' {
// Manifest related methods
export function createManifest(options: ManifestCreateOptions): Promise<{ engineId: string; Id: string }>;
export function inspectManifest(engineId: string, id: string): Promise<ManifestInspectInfo>;
export function removeManifest(engineId: string, id: string): Promise<void>;
}
/**

View file

@ -4720,3 +4720,27 @@ test('inspectManifest should fail if libpod is missing from the provider', async
'LibPod is not supported by this engine',
);
});
test('test removeManifest', async () => {
const api = new Dockerode({ protocol: 'http', host: 'localhost' });
const removeManifestMock = vi.fn();
const fakeLibPod = {
podmanRemoveManifest: removeManifestMock,
} as unknown as LibPod;
containerRegistry.addInternalProvider('podman1', {
name: 'podman',
id: 'podman1',
api,
libpodApi: fakeLibPod,
connection: {
type: 'podman',
},
} as unknown as InternalContainerProvider);
const result = await containerRegistry.removeManifest('podman1', 'manifestId');
expect(removeManifestMock).toBeCalledWith('manifestId');
expect(result).toBeUndefined();
});

View file

@ -1353,6 +1353,22 @@ export class ContainerProviderRegistry {
}
}
async removeManifest(engineId: string, manifestName: string): Promise<void> {
let telemetryOptions = {};
try {
const libPod = this.getMatchingPodmanEngineLibPod(engineId);
if (!libPod) {
throw new Error('No podman provider with a running engine');
}
return libPod.podmanRemoveManifest(manifestName);
} catch (error) {
telemetryOptions = { error: error };
throw error;
} finally {
this.telemetryService.track('removeManifest', telemetryOptions);
}
}
async replicatePodmanContainer(
source: { engineId: string; id: string },
target: { engineId: string },

View file

@ -273,3 +273,16 @@ test('Check create volume', async () => {
expect(response.Name).toBe('foo');
expect(response.Scope).toBe('local');
});
test('Test remove manifest', async () => {
nock('http://localhost').delete('/v4.2.0/libpod/manifests/name1').reply(200);
const api = new Dockerode({ protocol: 'http', host: 'localhost' });
const response = await (api as unknown as LibPod).podmanRemoveManifest('name1');
// Check that the request was made
expect(nock.isDone()).toBe(true);
// Check that the response is correct
expect(response).toBeDefined();
});

View file

@ -364,6 +364,7 @@ export interface LibPod {
podmanListImages(options?: PodmanListImagesOptions): Promise<ImageInfo[]>;
podmanCreateManifest(manifestOptions: ManifestCreateOptions): Promise<{ engineId: string; Id: string }>;
podmanInspectManifest(manifestName: string): Promise<ManifestInspectInfo>;
podmanRemoveManifest(manifestName: string): Promise<void>;
}
// tweak Dockerode by adding the support of libpod API
@ -895,5 +896,31 @@ export class LibpodDockerode {
});
});
};
// remove manifest
prototypeOfDockerode.podmanRemoveManifest = function (manifestName: string): Promise<unknown> {
// make sure encodeURI component for the name ex. domain.com/foo/bar:latest
const encodedManifestName = encodeURIComponent(manifestName);
const optsf = {
path: `/v4.2.0/libpod/manifests/${encodedManifestName}`,
method: 'DELETE',
statusCodes: {
200: true,
404: 'no such manifest',
500: 'server error',
},
options: {},
};
return new Promise((resolve, reject) => {
this.modem.dial(optsf, (err: unknown, data: unknown) => {
if (err) {
return reject(err);
}
resolve(data);
});
});
};
}
}

View file

@ -1175,6 +1175,9 @@ export class ExtensionLoader {
inspectManifest(engineId: string, id: string): Promise<containerDesktopAPI.ManifestInspectInfo> {
return containerProviderRegistry.inspectManifest(engineId, id);
},
removeManifest(engineId: string, id: string): Promise<void> {
return containerProviderRegistry.removeManifest(engineId, id);
},
replicatePodmanContainer(
source: { engineId: string; id: string },
target: { engineId: string },

View file

@ -806,6 +806,13 @@ export class PluginSystem {
},
);
this.ipcHandle(
'container-provider-registry:removeManifest',
async (_listener, engine: string, manifestId: string): Promise<void> => {
return containerProviderRegistry.removeManifest(engine, manifestId);
},
);
this.ipcHandle(
'container-provider-registry:generatePodmanKube',
async (_listener, engine: string, names: string[]): Promise<string> => {

View file

@ -303,6 +303,9 @@ export function initExposure(): void {
return ipcInvoke('container-provider-registry:inspectManifest', engine, manifestId);
},
);
contextBridge.exposeInMainWorld('removeManifest', async (engine: string, manifestId: string): Promise<void> => {
return ipcInvoke('container-provider-registry:removeManifest', engine, manifestId);
});
/**
* @deprecated This method is deprecated and will be removed in a future release.