From 110da9a48d833c74978cf556beb43d543698e73d Mon Sep 17 00:00:00 2001 From: Philippe Martin Date: Tue, 6 Feb 2024 17:16:22 +0100 Subject: [PATCH] feat: expose listPods to extensions (#5864) * feat: expose listPods to extensions Signed-off-by: Philippe Martin * test: add unit test Signed-off-by: Philippe Martin --- packages/extension-api/src/extension-api.d.ts | 23 +++++++++++ .../src/plugin/container-registry.spec.ts | 40 +++++++++++++++++++ .../main/src/plugin/extension-loader.spec.ts | 13 ++++++ packages/main/src/plugin/extension-loader.ts | 4 ++ 4 files changed, 80 insertions(+) diff --git a/packages/extension-api/src/extension-api.d.ts b/packages/extension-api/src/extension-api.d.ts index 16c1c04654933..07ed20bd3422f 100644 --- a/packages/extension-api/src/extension-api.d.ts +++ b/packages/extension-api/src/extension-api.d.ts @@ -1908,6 +1908,28 @@ declare module '@podman-desktop/api' { MacAddress: string; } + interface PodContainerInfo { + Id: string; + Names: string; + Status: string; + } + + interface PodInfo { + engineId: string; + engineName: string; + kind: 'kubernetes' | 'podman'; + Cgroup: string; + Containers: PodContainerInfo[]; + Created: string; + Id: string; + InfraId: string; + Labels: { [key: string]: string }; + Name: string; + Namespace: string; + Networks: string[]; + Status: string; + } + interface AuthConfig { username: string; password: string; @@ -2388,6 +2410,7 @@ declare module '@podman-desktop/api' { overrideParameters: PodmanContainerCreateOptions, ): Promise<{ Id: string; Warnings: string[] }>; export function startPod(engineId: string, podId: string): Promise; + export function listPods(): Promise; } /** diff --git a/packages/main/src/plugin/container-registry.spec.ts b/packages/main/src/plugin/container-registry.spec.ts index 0f2b7f3c8bc28..680895217d5db 100644 --- a/packages/main/src/plugin/container-registry.spec.ts +++ b/packages/main/src/plugin/container-registry.spec.ts @@ -262,6 +262,7 @@ const apiSender: ApiSenderType = { }; beforeEach(() => { + nock.cleanAll(); vi.mocked(apiSender.receive).mockClear(); vi.mocked(apiSender.send).mockClear(); @@ -3058,3 +3059,42 @@ test('check that fails if selected provider is not a podman one', async () => { }), ).rejects.toThrowError('No podman provider with a running engine'); }); + +test('list pods', async () => { + const podsList = [ + { + Labels: { + key1: 'value1', + key2: 'value2', + }, + }, + ]; + + nock('http://localhost').get('/v4.2.0/libpod/pods/json').reply(200, podsList); + + const api = new Dockerode({ protocol: 'http', host: 'localhost' }); + + // set provider + containerRegistry.addInternalProvider('podman', { + name: 'podman', + id: 'podman1', + api, + libpodApi: api, + connection: { + type: 'podman', + }, + } as unknown as InternalContainerProvider); + + const pods = await containerRegistry.listPods(); + // ensure the field are correct + expect(pods).toBeDefined(); + expect(pods).toHaveLength(1); + const pod = pods[0]; + expect(pod.engineId).toBe('podman1'); + expect(pod.engineName).toBe('podman'); + expect(pod.kind).toBe('podman'); + expect(pod.Labels).toStrictEqual({ + key1: 'value1', + key2: 'value2', + }); +}); diff --git a/packages/main/src/plugin/extension-loader.spec.ts b/packages/main/src/plugin/extension-loader.spec.ts index ab0254e026c9a..4ba4d05e3db6c 100644 --- a/packages/main/src/plugin/extension-loader.spec.ts +++ b/packages/main/src/plugin/extension-loader.spec.ts @@ -135,6 +135,7 @@ const containerProviderRegistry: ContainerProviderRegistry = { imageExist: vi.fn(), volumeExist: vi.fn(), podExist: vi.fn(), + listPods: vi.fn(), } as unknown as ContainerProviderRegistry; const inputQuickPickRegistry: InputQuickPickRegistry = {} as unknown as InputQuickPickRegistry; @@ -1332,3 +1333,15 @@ test('check version', async () => { // check we called method expect(readPodmanVersion).toBe(fakeVersion); }); + +test('listPods', async () => { + const listPodsSpy = vi.spyOn(containerProviderRegistry, 'listPods'); + const api = extensionLoader.createApi('path', { + name: 'name', + publisher: 'publisher', + version: '1', + displayName: 'dname', + }); + await api.containerEngine.listPods(); + expect(listPodsSpy).toHaveBeenCalledOnce(); +}); diff --git a/packages/main/src/plugin/extension-loader.ts b/packages/main/src/plugin/extension-loader.ts index c4674afad5d94..99704297b20e9 100644 --- a/packages/main/src/plugin/extension-loader.ts +++ b/packages/main/src/plugin/extension-loader.ts @@ -73,6 +73,7 @@ import type { ImageCheckerImpl } from './image-checker.js'; import type { NavigationManager } from '/@/plugin/navigation/navigation-manager.js'; import type { WebviewRegistry } from '/@/plugin/webview/webview-registry.js'; import type { ImageInspectInfo } from '/@/plugin/api/image-inspect-info.js'; +import type { PodInfo } from './api/pod-info.js'; /** * Handle the loading of an extension @@ -1000,6 +1001,9 @@ export class ExtensionLoader { createPod(podOptions: containerDesktopAPI.PodCreateOptions): Promise<{ engineId: string; Id: string }> { return containerProviderRegistry.createPod(podOptions); }, + listPods(): Promise { + return containerProviderRegistry.listPods(); + }, replicatePodmanContainer( source: { engineId: string; id: string }, target: { engineId: string },