Skip to content

Commit 2fc4d76

Browse files
committed
feat: choice to download RHEL 10 or 9
1 parent 08f463c commit 2fc4d76

6 files changed

Lines changed: 65 additions & 29 deletions

File tree

package.json

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -25,9 +25,9 @@
2525
},
2626
"macadam.factory.machine.image": {
2727
"type": "string",
28-
"enum": ["RHEL 10", "local image on disk"],
28+
"enum": ["RHEL 10.0", "RHEL 9.6", "local image on disk"],
2929
"scope": "VmProviderConnectionFactory",
30-
"default": "RHEL 10",
30+
"default": "RHEL 10.0",
3131
"description": "Image to download"
3232
},
3333
"macadam.factory.machine.image-path": {

src/cache.spec.ts

Lines changed: 25 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -16,7 +16,7 @@
1616
* SPDX-License-Identifier: Apache-2.0
1717
***********************************************************************/
1818

19-
import * as fs from 'node:fs';
19+
import type { Dirent } from 'node:fs';
2020
import * as fsPromises from 'node:fs/promises';
2121
import { resolve } from 'node:path';
2222

@@ -27,15 +27,32 @@ import { ImageCache } from './cache';
2727
vi.mock('node:fs');
2828
vi.mock('node:fs/promises');
2929

30-
test('images/image file is deleted during init if it exists', async () => {
31-
const cache = new ImageCache(resolve('/', 'path', 'to', 'cache'));
30+
test('images/image and images/rhel9_5 are deleted during init if they exist, rhel9_§ is not deleted', async () => {
31+
const cachePath = resolve('/', 'path', 'to', 'cache');
32+
const cache = new ImageCache(cachePath);
3233

33-
vi.mocked(fs.existsSync).mockImplementation((path: fs.PathLike): boolean => {
34-
return path === resolve('/', 'path', 'to', 'cache', 'images', 'image');
35-
});
34+
vi.mocked(fsPromises.readdir).mockResolvedValue([
35+
{
36+
name: 'image',
37+
parentPath: resolve(cachePath, 'images'),
38+
isFile: () => true,
39+
} as Dirent,
40+
{
41+
name: 'rhel9_5',
42+
parentPath: resolve(cachePath, 'images'),
43+
isFile: () => true,
44+
} as Dirent,
45+
{
46+
name: 'rhel9_6',
47+
parentPath: resolve(cachePath, 'images'),
48+
isFile: () => true,
49+
} as Dirent,
50+
]);
3651
await cache.init();
3752

3853
expect(fsPromises.rm).toHaveBeenCalledWith(resolve('/', 'path', 'to', 'cache', 'images', 'image'));
54+
expect(fsPromises.rm).toHaveBeenCalledWith(resolve('/', 'path', 'to', 'cache', 'images', 'rhel9_5'));
55+
expect(fsPromises.rm).not.toHaveBeenCalledWith(resolve('/', 'path', 'to', 'cache', 'images', 'rhel9_6'));
3956
});
4057

4158
test('images directory is created', async () => {
@@ -49,8 +66,8 @@ test('images directory is created', async () => {
4966
test('getPath returns path for known image', async () => {
5067
const cache = new ImageCache(resolve('/', 'path', 'to', 'cache'));
5168
await cache.init();
52-
const path = cache.getPath('RHEL 10');
53-
expect(path).toBe(resolve('/', 'path', 'to', 'cache', 'images', 'rhel10'));
69+
const path = cache.getPath('RHEL 10.0');
70+
expect(path).toBe(resolve('/', 'path', 'to', 'cache', 'images', 'rhel10_0'));
5471
});
5572

5673
test('getPath raises an exception for an unknown image', async () => {

src/cache.ts

Lines changed: 15 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -16,33 +16,38 @@
1616
* SPDX-License-Identifier: Apache-2.0
1717
***********************************************************************/
1818

19-
import { existsSync } from 'node:fs';
20-
import { mkdir, rm } from 'node:fs/promises';
19+
import { mkdir, readdir, rm } from 'node:fs/promises';
2120
import { resolve } from 'node:path';
2221

23-
import { MACADAM_IMAGE_PROPERTY_VALUE_RHEL_10 } from './constants';
22+
import { MACADAM_IMAGE_PROPERTY_VALUE_RHEL_9, MACADAM_IMAGE_PROPERTY_VALUE_RHEL_10 } from './constants';
2423

2524
export class ImageCache {
2625
#cachedImageDir: string;
2726

2827
#cachedImageNames: Record<string, string> = {
29-
[MACADAM_IMAGE_PROPERTY_VALUE_RHEL_10]: 'rhel10',
28+
[MACADAM_IMAGE_PROPERTY_VALUE_RHEL_10]: 'rhel10_0',
29+
[MACADAM_IMAGE_PROPERTY_VALUE_RHEL_9]: 'rhel9_6',
3030
};
3131

3232
constructor(storagePath: string) {
3333
this.#cachedImageDir = resolve(storagePath, 'images');
3434
}
3535

3636
async init(): Promise<void> {
37-
await this.cleanupv1();
37+
await this.cleanup();
3838
await mkdir(this.#cachedImageDir, { recursive: true });
3939
}
4040

41-
// v1 supported only 1 image, cached as `images/image`
42-
async cleanupv1(): Promise<void> {
43-
const imagePath = resolve(this.#cachedImageDir, 'image');
44-
if (existsSync(imagePath)) {
45-
await rm(imagePath);
41+
// delete all files not listed in cachedImageNames
42+
async cleanup(): Promise<void> {
43+
const possibleValues = Object.values(this.#cachedImageNames);
44+
const files = await readdir(this.#cachedImageDir, { recursive: false, withFileTypes: true });
45+
for (const file of files) {
46+
if (!file.isFile() || possibleValues.includes(file.name)) {
47+
continue;
48+
}
49+
console.log('deleting unused image from cache', resolve(file.parentPath, file.name));
50+
await rm(resolve(file.parentPath, file.name));
4651
}
4752
}
4853

src/constants.ts

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -18,6 +18,9 @@
1818

1919
export const MACADAM_IMAGE_PROPERTY_KEY = 'macadam.factory.machine.image';
2020
export const MACADAM_IMAGE_PROPERTY_VALUE_LOCAL = 'local image on disk';
21-
export const MACADAM_IMAGE_PROPERTY_VALUE_RHEL_10 = 'RHEL 10';
21+
22+
// Must match enumed value for macadam.factory.machine.image in package.json
23+
export const MACADAM_IMAGE_PROPERTY_VALUE_RHEL_10 = 'RHEL 10.0';
24+
export const MACADAM_IMAGE_PROPERTY_VALUE_RHEL_9 = 'RHEL 9.6';
2225

2326
export const MACADAM_LOCAL_IMAGE_KEY = 'macadam.localImage';

src/extension.ts

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -504,7 +504,7 @@ async function createVM(
504504
logger?.log(`Using image cached in ${cachedImagePath}\n`);
505505
} else {
506506
const client = await initAuthentication();
507-
const imageSha = getImageSha(provider);
507+
const imageSha = getImageSha(provider, image);
508508
logger?.log('Downloading image, please wait...\n');
509509
await pullImageFromRedHatRegistry(client, imageSha, cachedImagePath, logger, token);
510510
logger?.log(`Image downloaded\n`);

src/images.ts

Lines changed: 18 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -18,22 +18,33 @@
1818

1919
import { arch } from 'node:os';
2020

21-
const IMAGES: { [provider: string]: string } = {
22-
applehv: 'd32f05024821400932b3653647567abcd34dc03b4243d9a8ae5a11ecd11b1544',
23-
wsl: 'dccb2abb166981fa7598e948f9cab029aa1775219f8249fd54760ddd0f2b8910',
24-
linux_native_x64: '73473542ff4622524ae200ffabd4064bb2a7ff39ac40a012443a43d429d60019',
21+
import { MACADAM_IMAGE_PROPERTY_VALUE_RHEL_9, MACADAM_IMAGE_PROPERTY_VALUE_RHEL_10 } from './constants';
22+
23+
const IMAGES: { [provider: string]: { [version: string]: string } } = {
24+
applehv: {
25+
[MACADAM_IMAGE_PROPERTY_VALUE_RHEL_10]: 'd32f05024821400932b3653647567abcd34dc03b4243d9a8ae5a11ecd11b1544',
26+
[MACADAM_IMAGE_PROPERTY_VALUE_RHEL_9]: '73c93ad15404a93b2d5bb3b01474e2827e03eb74316132c1067519e4cb598652',
27+
},
28+
wsl: {
29+
[MACADAM_IMAGE_PROPERTY_VALUE_RHEL_10]: 'dccb2abb166981fa7598e948f9cab029aa1775219f8249fd54760ddd0f2b8910',
30+
[MACADAM_IMAGE_PROPERTY_VALUE_RHEL_9]: 'dca8920b81a0664788a098b20328ee98ee6f822f1a1106ee85e9146c50ae6b98',
31+
},
32+
linux_native_x64: {
33+
[MACADAM_IMAGE_PROPERTY_VALUE_RHEL_10]: '73473542ff4622524ae200ffabd4064bb2a7ff39ac40a012443a43d429d60019',
34+
[MACADAM_IMAGE_PROPERTY_VALUE_RHEL_9]: '49443696e7f2410e5647aa16f15eb7b7b08610fea92cdf3eba44ab9ec9ff899f',
35+
},
2536
};
2637

27-
export function getImageSha(provider?: string): string {
38+
export function getImageSha(provider: string | undefined, version: string): string {
2839
if (!provider) {
2940
if (arch() === 'x64') {
30-
return IMAGES['linux_native_x64'];
41+
return IMAGES['linux_native_x64'][version];
3142
} else {
3243
throw new Error('linux non-x64 is not supported');
3344
}
3445
}
3546
if (provider in IMAGES) {
36-
return IMAGES[provider];
47+
return IMAGES[provider][version];
3748
}
3849
throw new Error(`provider ${provider} is not supported`);
3950
}

0 commit comments

Comments
 (0)