Skip to content

Commit

Permalink
feat: use the new function to create a container within a pod (#231)
Browse files Browse the repository at this point in the history
* feat: use the new function to create a container within a pod

Signed-off-by: lstocchi <[email protected]>

* fix: remove mapping function

Signed-off-by: lstocchi <[email protected]>

---------

Signed-off-by: lstocchi <[email protected]>
  • Loading branch information
lstocchi authored Mar 13, 2024
1 parent d97f3fe commit 60d8821
Show file tree
Hide file tree
Showing 2 changed files with 43 additions and 59 deletions.
53 changes: 29 additions & 24 deletions packages/backend/src/managers/applicationManager.spec.ts
Original file line number Diff line number Diff line change
Expand Up @@ -50,10 +50,8 @@ const mocks = vi.hoisted(() => {
getImageInspectMock: vi.fn(),
createPodMock: vi.fn(),
createContainerMock: vi.fn(),
replicatePodmanContainerMock: vi.fn(),
startContainerMock: vi.fn(),
startPod: vi.fn(),
deleteContainerMock: vi.fn(),
inspectContainerMock: vi.fn(),
logUsageMock: vi.fn(),
logErrorMock: vi.fn(),
Expand Down Expand Up @@ -109,10 +107,8 @@ vi.mock('@podman-desktop/api', () => ({
getImageInspect: mocks.getImageInspectMock,
createPod: mocks.createPodMock,
createContainer: mocks.createContainerMock,
replicatePodmanContainer: mocks.replicatePodmanContainerMock,
startContainer: mocks.startContainerMock,
startPod: mocks.startPod,
deleteContainer: mocks.deleteContainerMock,
inspectContainer: mocks.inspectContainerMock,
pullImage: mocks.pullImageMock,
stopContainer: mocks.stopContainerMock,
Expand Down Expand Up @@ -1058,35 +1054,44 @@ describe('createAndAddContainersToPod', () => {
modelService: false,
ports: ['8080', '8081'],
};
test('check that after the creation and copy inside the pod, the container outside the pod is actually deleted', async () => {
const imageInfo2: ImageInfo = {
id: 'id2',
appName: 'appName2',
modelService: true,
ports: ['8085'],
};
test('check that containers are correctly created', async () => {
mocks.createContainerMock.mockResolvedValue({
id: 'container-1',
});
vi.spyOn(manager, 'getRandomName').mockReturnValue('name');
await manager.createAndAddContainersToPod(pod, [imageInfo1], 'path');
expect(mocks.createContainerMock).toBeCalledWith('engine', {
await manager.createAndAddContainersToPod(pod, [imageInfo1, imageInfo2], 'path');
expect(mocks.createContainerMock).toHaveBeenNthCalledWith(1, 'engine', {
Image: 'id',
Detach: true,
HostConfig: {
AutoRemove: true,
},
Env: [],
Env: ['MODEL_ENDPOINT=http://localhost:8085'],
start: false,
name: 'name',
pod: 'id',
});
expect(mocks.replicatePodmanContainerMock).toBeCalledWith(
{
id: 'container-1',
engineId: 'engine',
},
{
engineId: 'engine',
},
{
pod: 'id',
name: 'name',
expect(mocks.createContainerMock).toHaveBeenNthCalledWith(2, 'engine', {
Image: 'id2',
Detach: true,
Env: ['MODEL_PATH=/path'],
start: false,
name: 'name',
pod: 'id',
HostConfig: {
Mounts: [
{
Mode: 'Z',
Source: 'path',
Target: '/path',
Type: 'bind',
},
],
},
);
expect(mocks.deleteContainerMock).toBeCalledWith('engine', 'container-1');
});
});
});

Expand Down
49 changes: 14 additions & 35 deletions packages/backend/src/managers/applicationManager.ts
Original file line number Diff line number Diff line change
Expand Up @@ -20,13 +20,8 @@ import type { Recipe } from '@shared/src/models/IRecipe';
import type { GitCloneInfo, GitManager } from './gitManager';
import fs from 'fs';
import * as path from 'node:path';
import {
type PodCreatePortOptions,
containerEngine,
type TelemetryLogger,
type PodInfo,
type Webview,
} from '@podman-desktop/api';
import { containerEngine } from '@podman-desktop/api';
import type { HostConfig, PodCreatePortOptions, TelemetryLogger, PodInfo, Webview } from '@podman-desktop/api';
import type { AIConfig, AIConfigFile, ContainerConfig } from '../models/AIConfig';
import { parseYamlFile } from '../models/AIConfig';
import type { Task } from '@shared/src/models/ITask';
Expand Down Expand Up @@ -265,62 +260,46 @@ export class ApplicationManager extends Publisher<ApplicationState[]> {
const containers: ContainerAttachedInfo[] = [];
await Promise.all(
images.map(async image => {
let hostConfig: unknown;
let hostConfig: HostConfig;
let envs: string[] = [];
// if it's a model service we mount the model as a volume
if (image.modelService) {
const modelName = path.basename(modelPath);
hostConfig = {
AutoRemove: true,
Mounts: [
{
Target: `/${modelName}`,
Source: modelPath,
Type: 'bind',
Mode: 'Z',
},
],
};
envs = [`MODEL_PATH=/${modelName}`];
} else {
hostConfig = {
AutoRemove: true,
};
// TODO: remove static port
const modelService = images.find(image => image.modelService);
if (modelService && modelService.ports.length > 0) {
const endPoint = `http://localhost:${modelService.ports[0]}`;
envs = [`MODEL_ENDPOINT=${endPoint}`];
}
}
const createdContainer = await containerEngine.createContainer(podInfo.engineId, {

const podifiedName = this.getRandomName(`${image.appName}-podified`);
await containerEngine.createContainer(podInfo.engineId, {
Image: image.id,
name: podifiedName,
Detach: true,
HostConfig: hostConfig,
Env: envs,
start: false,
pod: podInfo.Id,
});
containers.push({
name: podifiedName,
modelService: image.modelService,
ports: image.ports,
});

// now, for each container, put it in the pod
if (createdContainer) {
const podifiedName = this.getRandomName(`${image.appName}-podified`);
await containerEngine.replicatePodmanContainer(
{
id: createdContainer.id,
engineId: podInfo.engineId,
},
{ engineId: podInfo.engineId },
{ pod: podInfo.Id, name: podifiedName },
);
containers.push({
name: podifiedName,
modelService: image.modelService,
ports: image.ports,
});
// remove the external container
await containerEngine.deleteContainer(podInfo.engineId, createdContainer.id);
} else {
throw new Error(`failed at creating container for image ${image.id}`);
}
}),
);
return containers;
Expand Down

0 comments on commit 60d8821

Please sign in to comment.