feat: add alias for registry entries (#6839)

* feat: add alias for registry entries

Fixes #6298

Signed-off-by: Jeff MAURY <jmaury@redhat.com>
This commit is contained in:
Jeff MAURY 2024-04-22 15:14:29 +02:00 committed by GitHub
parent e7a0b8a4ef
commit 0997da60fc
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
4 changed files with 81 additions and 7 deletions

View file

@ -56,17 +56,17 @@ afterEach(() => {
console.error = originalConsoleError;
});
type ReadFileType = (
path: string,
options: string,
callback: (err: NodeJS.ErrnoException | undefined, data: string | Buffer) => void,
) => void;
test('should work with invalid JSON auth file', async () => {
// mock the existSync
const existSyncSpy = vi.spyOn(fs, 'existsSync');
existSyncSpy.mockReturnValue(true);
type ReadFileType = (
path: string,
options: string,
callback: (err: NodeJS.ErrnoException | undefined, data: string | Buffer) => void,
) => void;
// mock the readFile
const readFileSpy = vi.spyOn(fs, 'readFile') as unknown as MockedFunction<ReadFileType>;
@ -94,3 +94,71 @@ test('should work with invalid JSON auth file', async () => {
// expect error was logged
expect(consoleErroMock).toHaveBeenCalledWith('Error parsing auth file', expect.anything());
});
test('should work with JSON auth file', async () => {
// mock the existSync
const existSyncSpy = vi.spyOn(fs, 'existsSync');
existSyncSpy.mockReturnValue(true);
// mock the readFile
const readFileSpy = vi.spyOn(fs, 'readFile') as unknown as MockedFunction<ReadFileType>;
const auth = Buffer.from('user:password').toString('base64');
readFileSpy.mockImplementation(
(_path: string, _encoding: string, callback: (err: Error | null, data: string) => void) => {
// mock the error
callback(undefined, JSON.stringify({ auths: { 'myregistry.io': { auth: auth } } }));
},
);
// mock the location
const authJsonLocation = '/tmp/containers/auth.json';
const mockGetAuthFileLocation = vi.spyOn(registrySetup, 'getAuthFileLocation');
mockGetAuthFileLocation.mockReturnValue(authJsonLocation);
// expect an error
const authFile = await registrySetup.publicReadAuthFile();
// expect the file to have a single entry
expect(authFile.auths['myregistry.io']).toBeDefined();
expect(authFile.auths['myregistry.io'].auth).toBe(auth);
expect(authFile.auths['myregistry.io']['podmanDesktopAlias']).not.toBeDefined();
// expect read with the correct file
expect(readFileSpy).toHaveBeenCalledWith(authJsonLocation, 'utf-8', expect.anything());
});
test('should work with JSON auth file and alias', async () => {
// mock the existSync
const existSyncSpy = vi.spyOn(fs, 'existsSync');
existSyncSpy.mockReturnValue(true);
// mock the readFile
const readFileSpy = vi.spyOn(fs, 'readFile') as unknown as MockedFunction<ReadFileType>;
const auth = Buffer.from('user:password').toString('base64');
readFileSpy.mockImplementation(
(_path: string, _encoding: string, callback: (err: Error | null, data: string) => void) => {
// mock the error
callback(undefined, JSON.stringify({ auths: { 'myregistry.io': { auth: auth, podmanDesktopAlias: 'alias' } } }));
},
);
// mock the location
const authJsonLocation = '/tmp/containers/auth.json';
const mockGetAuthFileLocation = vi.spyOn(registrySetup, 'getAuthFileLocation');
mockGetAuthFileLocation.mockReturnValue(authJsonLocation);
// expect an error
const authFile = await registrySetup.publicReadAuthFile();
// expect the file to have a single entry
expect(authFile.auths['myregistry.io']).toBeDefined();
expect(authFile.auths['myregistry.io'].auth).toBe(auth);
expect(authFile.auths['myregistry.io']['podmanDesktopAlias']).toBe('alias');
// expect read with the correct file
expect(readFileSpy).toHaveBeenCalledWith(authJsonLocation, 'utf-8', expect.anything());
});

View file

@ -27,6 +27,7 @@ import { isLinux, isMac, isWindows } from './util';
export type ContainerAuthConfigEntry = {
[key: string]: {
auth: string;
podmanDesktopAlias: string | undefined;
};
};
@ -70,6 +71,7 @@ export class RegistrySetup {
serverUrl,
username,
secret,
alias: value['podmanDesktopAlias'],
};
inFileRegistries.push(registry);
}
@ -117,6 +119,7 @@ export class RegistrySetup {
}
authFile.auths[registry.serverUrl] = {
auth: Buffer.from(`${registry.username}:${registry.secret}`).toString('base64'),
podmanDesktopAlias: registry.alias,
};
await this.writeAuthFile(JSON.stringify(authFile, undefined, 8));
@ -149,6 +152,7 @@ export class RegistrySetup {
}
authFile.auths[registry.serverUrl] = {
auth: Buffer.from(`${registry.username}:${registry.secret}`).toString('base64'),
podmanDesktopAlias: registry.alias,
};
await this.writeAuthFile(JSON.stringify(authFile, undefined, 8));

View file

@ -623,6 +623,7 @@ declare module '@podman-desktop/api' {
username: string;
secret: string;
insecure?: boolean;
alias?: string;
}
export interface RegistryProvider {

View file

@ -65,6 +65,7 @@ function markRegistryAsModified(registry: containerDesktopAPI.Registry) {
serverUrl: registry.serverUrl,
username: registry.username,
secret: registry.secret,
alias: registry.alias,
} as containerDesktopAPI.Registry;
originRegistries = [...originRegistries, originRegistry];
@ -282,7 +283,7 @@ function removeExistingRegistry(registry: containerDesktopAPI.Registry) {
{:else if !registry.username && !registry.secret}
<Button on:click="{() => markRegistryAsModified(registry)}">Login now</Button>
{:else}
{registry.username}
{registry.alias ?? registry.username}
{/if}
</div>