Skip to content

Commit

Permalink
fix: pick unused container name (#128)
Browse files Browse the repository at this point in the history
* fix: pick unused container name

Make sure we pick an unused container name so that it's possible to
kick off multiple builds at the same time.

Note that there are still two theoretical places this could still fail
due to the delay between when you kick off the task and we check for
conflicts vs when the container gets created: the first time you ever
run (if the bootc builder image takes time to pull down) and if you're
super-fast and run the action twice before the container engine can
create a container and register back in Podman Desktop. The first seems
very unlikely that someone would try, and the second I couldn't even
reproduce when trying.

Fixes #103.

Signed-off-by: Tim deBoer <[email protected]>

* fix: sync createBuilderImageOptions

Review changes: keep createBuilderImageOptions() sync, find an
unused name before calling it.

Signed-off-by: Tim deBoer <[email protected]>

---------

Signed-off-by: Tim deBoer <[email protected]>
  • Loading branch information
deboer-tim authored Feb 5, 2024
1 parent 209e730 commit c64efb5
Show file tree
Hide file tree
Showing 2 changed files with 49 additions and 2 deletions.
26 changes: 25 additions & 1 deletion src/build-disk-image.spec.ts
Original file line number Diff line number Diff line change
Expand Up @@ -17,14 +17,19 @@
***********************************************************************/

import { beforeEach, expect, test, vi } from 'vitest';
import { createBuilderImageOptions } from './build-disk-image';
import { createBuilderImageOptions, getUnusedName } from './build-disk-image';
import { bootcImageBuilderName } from './constants';
import type { ContainerInfo } from '@podman-desktop/api';
import { containerEngine } from '@podman-desktop/api';

vi.mock('@podman-desktop/api', async () => {
return {
env: {
createTelemetryLogger: vi.fn(),
},
containerEngine: {
listContainers: vi.fn().mockReturnValue([]),
},
};
});

Expand All @@ -46,3 +51,22 @@ test('check image builder options', async () => {
expect(options.HostConfig.Binds[0]).toEqual(outputFolder + ':/output/');
expect(options.Cmd).toEqual([image, '--type', type, '--output', '/output/']);
});

test('check we pick unused container name', async () => {
const basename = 'test';
let name = await getUnusedName(basename);
expect(name).toEqual(basename);

vi.spyOn(containerEngine, 'listContainers').mockReturnValue([{ Names: ['test'] }] as unknown as Promise<
ContainerInfo[]
>);
name = await getUnusedName(basename);
expect(name).toEqual(basename + '-2');

vi.spyOn(containerEngine, 'listContainers').mockReturnValue([
{ Names: ['test'] },
{ Names: ['/test-2'] },
] as unknown as Promise<ContainerInfo[]>);
name = await getUnusedName(basename);
expect(name).toEqual(basename + '-3');
});
25 changes: 24 additions & 1 deletion src/build-disk-image.ts
Original file line number Diff line number Diff line change
Expand Up @@ -130,8 +130,9 @@ export async function buildDiskImage(imageData: unknown, history: History) {
// Preliminary Step 0. Create the "bootc-image-builder" container
// options that we will use to build the image. This will help with debugging
// as well as making sure we delete the previous build, etc.
const containerName = await getUnusedName(buildContainerName);
const buildImageContainer = createBuilderImageOptions(
buildContainerName,
containerName,
image.name + ':' + image.tag,
selectedType,
selectedFolder,
Expand Down Expand Up @@ -233,6 +234,28 @@ async function logContainer(image, containerId: string, progress, callback: (dat
});
}

// find an unused container name
export async function getUnusedName(name: string): Promise<string> {
let containers: string[] = [];
try {
// get a list of all existing container names, which may start with /
containers = (await extensionApi.containerEngine.listContainers())
.map(c => c.Names)
.reduce((a, val) => [...a, ...val], [])
.map(n => (n.charAt(0) === '/' ? n.substring(1) : n));
} catch (e) {
console.warn('Could not get existing container names');
console.warn(e);
}

let unusedName = name;
let count = 2;
while (containers.includes(unusedName)) {
unusedName = name + '-' + count++;
}
return unusedName;
}

// Create builder options for the "bootc-image-builder" container
export function createBuilderImageOptions(
name: string,
Expand Down

0 comments on commit c64efb5

Please sign in to comment.