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

refactor: moving pod events method to PodManager #1131

Merged
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
42 changes: 20 additions & 22 deletions packages/backend/src/managers/applicationManager.spec.ts
Original file line number Diff line number Diff line change
Expand Up @@ -29,21 +29,14 @@ import * as portsUtils from '../utils/ports';
import { goarch } from '../utils/arch';
import * as utils from '../utils/utils';
import * as podman from '../utils/podman';
import type { Webview, TelemetryLogger, PodInfo } from '@podman-desktop/api';
import type { Webview, TelemetryLogger, PodInfo, Disposable } from '@podman-desktop/api';
import type { CatalogManager } from './catalogManager';
import type { LocalRepositoryRegistry } from '../registries/LocalRepositoryRegistry';
import type {
PodmanConnection,
machineStopHandle,
podRemoveHandle,
podStartHandle,
podStopHandle,
startupHandle,
} from './podmanConnection';
import type { PodmanConnection, machineStopHandle, startupHandle } from './podmanConnection';
import { TaskRegistry } from '../registries/TaskRegistry';
import type { CancellationTokenRegistry } from '../registries/CancellationTokenRegistry';
import type { BuilderManager } from './recipes/BuilderManager';
import type { PodManager } from './recipes/PodManager';
import type { PodEvent, PodManager } from './recipes/PodManager';

const mocks = vi.hoisted(() => {
return {
Expand All @@ -61,9 +54,6 @@ const mocks = vi.hoisted(() => {
pullImageMock: vi.fn(),
stopContainerMock: vi.fn(),
containerRegistrySubscribeMock: vi.fn(),
onPodStartMock: vi.fn(),
onPodStopMock: vi.fn(),
onPodRemoveMock: vi.fn(),
startupSubscribeMock: vi.fn(),
onMachineStopMock: vi.fn(),
listContainersMock: vi.fn(),
Expand Down Expand Up @@ -142,6 +132,9 @@ const podManager = {
stopPod: vi.fn(),
removePod: vi.fn(),
startPod: vi.fn(),
onStartPodEvent: vi.fn(),
onStopPodEvent: vi.fn(),
onRemovePodEvent: vi.fn(),
} as unknown as PodManager;

const localRepositoryRegistry = {
Expand Down Expand Up @@ -994,9 +987,6 @@ describe('pod detection', async () => {
postMessage: mocks.postMessageMock,
} as unknown as Webview,
{
onPodStart: mocks.onPodStartMock,
onPodStop: mocks.onPodStopMock,
onPodRemove: mocks.onPodRemoveMock,
startupSubscribe: mocks.startupSubscribeMock,
onMachineStop: mocks.onMachineStopMock,
} as unknown as PodmanConnection,
Expand Down Expand Up @@ -1071,7 +1061,7 @@ describe('pod detection', async () => {
test('onPodStart updates the applications state with the started pod', async () => {
vi.mocked(podManager.getAllPods).mockResolvedValue([]);
mocks.onMachineStopMock.mockImplementation((_f: machineStopHandle) => {});
mocks.onPodStartMock.mockImplementation((f: podStartHandle) => {
vi.mocked(podManager.onStartPodEvent).mockImplementation((f: (e: PodInfo) => void): Disposable => {
f({
engineId: 'engine-1',
engineName: 'Engine 1',
Expand All @@ -1081,6 +1071,7 @@ describe('pod detection', async () => {
'ai-lab-model-id': 'model-id-1',
},
} as unknown as PodInfo);
return { dispose: vi.fn() };
});
const sendApplicationStateSpy = vi.spyOn(manager, 'notify').mockResolvedValue();
manager.adoptRunningApplications();
Expand All @@ -1090,12 +1081,13 @@ describe('pod detection', async () => {
test('onPodStart does no update the applications state with the started pod without labels', async () => {
vi.mocked(podManager.getAllPods).mockResolvedValue([]);
mocks.onMachineStopMock.mockImplementation((_f: machineStopHandle) => {});
mocks.onPodStartMock.mockImplementation((f: podStartHandle) => {
vi.mocked(podManager.onStartPodEvent).mockImplementation((f: (e: PodInfo) => void): Disposable => {
f({
engineId: 'engine-1',
engineName: 'Engine 1',
kind: 'podman',
} as unknown as PodInfo);
return { dispose: vi.fn() };
});
const sendApplicationStateSpy = vi.spyOn(manager, 'notify').mockResolvedValue();
manager.adoptRunningApplications();
Expand All @@ -1105,7 +1097,7 @@ describe('pod detection', async () => {
test('onPodStart does no update the applications state with the started pod without specific labels', async () => {
vi.mocked(podManager.getAllPods).mockResolvedValue([]);
mocks.onMachineStopMock.mockImplementation((_f: machineStopHandle) => {});
mocks.onPodStartMock.mockImplementation((f: podStartHandle) => {
vi.mocked(podManager.onStartPodEvent).mockImplementation((f: (e: PodInfo) => void): Disposable => {
f({
engineId: 'engine-1',
engineName: 'Engine 1',
Expand All @@ -1114,6 +1106,7 @@ describe('pod detection', async () => {
label1: 'value1',
},
} as unknown as PodInfo);
return { dispose: vi.fn() };
});
const sendApplicationStateSpy = vi.spyOn(manager, 'notify').mockResolvedValue();
manager.adoptRunningApplications();
Expand All @@ -1133,7 +1126,7 @@ describe('pod detection', async () => {
} as unknown as PodInfo,
]);
mocks.onMachineStopMock.mockImplementation((_f: machineStopHandle) => {});
mocks.onPodStopMock.mockImplementation((f: podStopHandle) => {
vi.mocked(podManager.onStopPodEvent).mockImplementation((f: (e: PodInfo) => void): Disposable => {
setTimeout(() => {
f({
engineId: 'engine-1',
Expand All @@ -1144,7 +1137,9 @@ describe('pod detection', async () => {
'ai-lab-model-id': 'model-id-1',
},
} as unknown as PodInfo);
return { dispose: vi.fn() };
}, 1);
return { dispose: vi.fn() };
});
const sendApplicationStateSpy = vi.spyOn(manager, 'notify').mockResolvedValue();
manager.adoptRunningApplications();
Expand All @@ -1166,10 +1161,13 @@ describe('pod detection', async () => {
} as unknown as PodInfo,
]);
mocks.onMachineStopMock.mockImplementation((_f: machineStopHandle) => {});
mocks.onPodRemoveMock.mockImplementation((f: podRemoveHandle) => {
vi.mocked(podManager.onRemovePodEvent).mockImplementation((f: (e: PodEvent) => void): Disposable => {
setTimeout(() => {
f('pod-id-1');
f({
podId: 'pod-id-1',
});
}, 1);
return { dispose: vi.fn() };
});
const sendApplicationStateSpy = vi.spyOn(manager, 'notify').mockResolvedValue();
manager.adoptRunningApplications();
Expand Down
4 changes: 2 additions & 2 deletions packages/backend/src/managers/applicationManager.ts
Original file line number Diff line number Diff line change
Expand Up @@ -578,10 +578,10 @@ export class ApplicationManager extends Publisher<ApplicationState[]> implements
this.notify();
});

this.podmanConnection.onPodStart((pod: PodInfo) => {
this.podManager.onStartPodEvent((pod: PodInfo) => {
this.adoptPod(pod);
});
this.podmanConnection.onPodRemove((podId: string) => {
this.podManager.onRemovePodEvent(({ podId }) => {
this.forgetPodById(podId);
});

Expand Down
70 changes: 0 additions & 70 deletions packages/backend/src/managers/podmanConnection.ts
Original file line number Diff line number Diff line change
Expand Up @@ -20,34 +20,25 @@ import {
type RegisterContainerConnectionEvent,
provider,
type UpdateContainerConnectionEvent,
containerEngine,
type PodInfo,
type Disposable,
} from '@podman-desktop/api';
import { getFirstRunningPodmanConnection } from '../utils/podman';

export type startupHandle = () => void;
export type machineStartHandle = () => void;
export type machineStopHandle = () => void;
export type podStartHandle = (pod: PodInfo) => void;
export type podStopHandle = (pod: PodInfo) => void;
export type podRemoveHandle = (podId: string) => void;

export class PodmanConnection implements Disposable {
#firstFound = false;
#toExecuteAtStartup: startupHandle[] = [];
#toExecuteAtMachineStop: machineStopHandle[] = [];
#toExecuteAtMachineStart: machineStartHandle[] = [];
#toExecuteAtPodStart: podStartHandle[] = [];
#toExecuteAtPodStop: podStopHandle[] = [];
#toExecuteAtPodRemove: podRemoveHandle[] = [];

#onEventDisposable: Disposable | undefined;

init(): void {
this.listenRegistration();
this.listenMachine();
this.watchPods();
}

dispose(): void {
Expand Down Expand Up @@ -114,65 +105,4 @@ export class PodmanConnection implements Disposable {
onMachineStop(f: machineStopHandle) {
this.#toExecuteAtMachineStop.push(f);
}

watchPods() {
if (this.#onEventDisposable !== undefined) throw new Error('already watching pods.');

this.#onEventDisposable = containerEngine.onEvent(event => {
if (event.Type !== 'pod') {
return;
}
switch (event.status) {
case 'remove':
for (const f of this.#toExecuteAtPodRemove) {
f(event.id);
}
break;
case 'start':
containerEngine
.listPods()
.then((pods: PodInfo[]) => {
const pod = pods.find((p: PodInfo) => p.Id === event.id);
if (!pod) {
return;
}
for (const f of this.#toExecuteAtPodStart) {
f(pod);
}
})
.catch((err: unknown) => {
console.error(err);
});
break;
case 'stop':
containerEngine
.listPods()
.then((pods: PodInfo[]) => {
const pod = pods.find((p: PodInfo) => p.Id === event.id);
if (!pod) {
return;
}
for (const f of this.#toExecuteAtPodStop) {
f(pod);
}
})
.catch((err: unknown) => {
console.error(err);
});
break;
}
});
}

onPodStart(f: podStartHandle) {
this.#toExecuteAtPodStart.push(f);
}

onPodStop(f: podStopHandle) {
this.#toExecuteAtPodStop.push(f);
}

onPodRemove(f: podRemoveHandle) {
this.#toExecuteAtPodRemove.push(f);
}
}
Loading