From 35d85450eba2b46384151da8cfc0423c2a9bfadc Mon Sep 17 00:00:00 2001 From: Denis Golovin Date: Tue, 30 Apr 2024 14:40:54 -0700 Subject: [PATCH] fix: support of activation non default podman machines (#138) Signed-off-by: Denis Golovin --- src/extension.spec.ts | 7 +++- src/extension.ts | 88 +++++++++++++----------------------------- src/podman-cli.spec.ts | 41 +++++++++++--------- src/podman-cli.ts | 65 ++++++++++++++++++------------- src/subscription.ts | 42 ++++++++++++++++++++ 5 files changed, 134 insertions(+), 109 deletions(-) create mode 100644 src/subscription.ts diff --git a/src/extension.spec.ts b/src/extension.spec.ts index ff4aecce..71124b3d 100644 --- a/src/extension.spec.ts +++ b/src/extension.spec.ts @@ -27,6 +27,7 @@ import { } from '@podman-desktop/api'; import { authentication, commands } from '@podman-desktop/api'; import * as podmanCli from './podman-cli'; +import * as subscription from './subscription'; import { ExtensionTelemetryLogger } from './telemetry'; import { OrganizationService } from '@redhat-developer/rhsm-client'; @@ -175,7 +176,8 @@ suite('signin command telemetry reports', () => { }; }, ); - vi.spyOn(podmanCli, 'isPodmanMachineRunning').mockReturnValue(false); + vi.spyOn(subscription, 'isRedHatRegistryConfigured').mockResolvedValue(true); + vi.spyOn(podmanCli, 'getRunningPodmanMachineName').mockReturnValue(undefined); await extension.activate(createExtContext()); expect(commandFunctionCopy!).toBeDefined(); await commandFunctionCopy!(); @@ -238,7 +240,8 @@ suite('signin command telemetry reports', () => { }; }, ); - vi.spyOn(podmanCli, 'isPodmanMachineRunning').mockReturnValue(true); + vi.spyOn(subscription, 'isRedHatRegistryConfigured').mockReturnValue(true); + vi.spyOn(podmanCli, 'getRunningPodmanMachineName').mockReturnValue('machine1'); vi.spyOn(OrganizationService.prototype, 'checkOrgScaCapability').mockResolvedValue({ body: {} }); await extension.activate(createExtContext()); expect(commandFunctionCopy!).toBeDefined(); diff --git a/src/extension.ts b/src/extension.ts index a7331c01..6d8a5deb 100644 --- a/src/extension.ts +++ b/src/extension.ts @@ -21,8 +21,7 @@ import { getAuthConfig } from './configuration'; import { onDidChangeSessions, RedHatAuthenticationService } from './authentication-service'; import { ServiceAccountV1, ContainerRegistryAuthorizerClient } from '@redhat-developer/rhcra-client'; import path from 'node:path'; -import { homedir } from 'node:os'; -import { accessSync, constants, readFileSync } from 'node:fs'; +import { readFileSync } from 'node:fs'; import { runRpmInstallSubscriptionManager, runSubscriptionManager, @@ -30,14 +29,17 @@ import { runSubscriptionManagerRegister, runSubscriptionManagerUnregister, runCreateFactsFile, - isPodmanMachineRunning, runStartPodmanMachine, runStopPodmanMachine, + getRunningPodmanMachineName, } from './podman-cli'; import { SubscriptionManagerClient } from '@redhat-developer/rhsm-client'; import { isLinux } from './util'; import { SSOStatusBarItem } from './status-bar-item'; import { ExtensionTelemetryLogger as TelemetryLogger } from './telemetry'; +import { signIntoRedHatDeveloperAccount } from './subscription'; +import { isRedHatRegistryConfigured } from './subscription'; +import { REGISTRY_REDHAT_IO } from './subscription'; let authenticationServicePromise: Promise; let currentSession: extensionApi.AuthenticationSession | undefined; @@ -70,21 +72,6 @@ function parseJwt(token: string) { return JSON.parse(jsonPayload); } -async function signIntoRedHatDeveloperAccount( - createIfNone = true, -): Promise { - return extensionApi.authentication.getSession( - 'redhat.authentication-provider', - [ - 'api.iam.registry_service_accounts', //scope that gives access to hydra service accounts API - 'api.console', - ], // scope that gives access to console.redhat.com APIs - { createIfNone }, // will request to login in browser if session does not exists - ); -} - -const REGISTRY_REDHAT_IO = 'registry.redhat.io'; - async function createRegistry( username: string, secret: string, @@ -109,29 +96,6 @@ function removeRegistry(serverUrl: string = REGISTRY_REDHAT_IO): void { }); } -// TODO: add listRegistries to registry API to allow search by -// registry URL -function isRedHatRegistryConfigured(): boolean { - const pathToAuthJson = path.join(homedir(), '.config', 'containers', 'auth.json'); - let configured = false; - try { - // TODO: handle all kind problems with file existence, accessibility and parsable content - accessSync(pathToAuthJson, constants.R_OK); - const authFileContent = readFileSync(pathToAuthJson, { encoding: 'utf8' }); - const authFileJson: { - auths?: { - [registryUrl: string]: { - auth: string; - }; - }; - } = JSON.parse(authFileContent); - configured = authFileJson?.auths?.hasOwnProperty(REGISTRY_REDHAT_IO) || false; - } catch (_notAccessibleError) { - // if file is not there, ignore and return default value - } - return configured; -} - async function createOrReuseRegistryServiceAccount(): Promise { const currentSession = await signIntoRedHatDeveloperAccount(); const accessTokenJson = parseJwt(currentSession!.accessToken); @@ -162,7 +126,7 @@ async function createOrReuseRegistryServiceAccount(): Promise { ); } -async function createOrReuseActivationKey() { +async function createOrReuseActivationKey(machineName: string) { const currentSession = await signIntoRedHatDeveloperAccount(); const accessTokenJson = parseJwt(currentSession!.accessToken); const client = new SubscriptionManagerClient({ @@ -184,7 +148,7 @@ async function createOrReuseActivationKey() { }); } - await runSubscriptionManagerRegister('podman-desktop', accessTokenJson.organization.id); + await runSubscriptionManagerRegister(machineName, 'podman-desktop', accessTokenJson.organization.id); } async function isSimpleContentAccessEnabled(): Promise { @@ -197,14 +161,14 @@ async function isSimpleContentAccessEnabled(): Promise { return response.body && response.body.simpleContentAccess === 'enabled'; } -async function isSubscriptionManagerInstalled(): Promise { - const exitCode = await runSubscriptionManager(); +async function isSubscriptionManagerInstalled(machineName: string): Promise { + const exitCode = await runSubscriptionManager(machineName); return exitCode === 0; } -async function installSubscriptionManger() { +async function installSubscriptionManger(machineName: string) { try { - return await runRpmInstallSubscriptionManager(); + return await runRpmInstallSubscriptionManager(machineName); } catch (err) { console.error(`Subscription manager installation failed. ${String(err)}`); TelemetryLogger.logError('subscriptionManagerInstallationError', { error: String(err) }); @@ -212,13 +176,16 @@ async function installSubscriptionManger() { } } -async function isPodmanVmSubscriptionActivated() { - const exitCode = await runSubscriptionManagerActivationStatus(); +async function isPodmanVmSubscriptionActivated(machineName: string) { + const exitCode = await runSubscriptionManagerActivationStatus(machineName); return exitCode === 0; } async function removeSession(sessionId: string): Promise { - runSubscriptionManagerUnregister().catch(console.error); // ignore error in case vm subscription activation failed on login + const machineName = getRunningPodmanMachineName(); + if (machineName) { + runSubscriptionManagerUnregister(machineName).catch(console.error); // ignore error in case vm subscription activation failed on login + } removeRegistry(); // never fails, even if registry does not exist const service = await getAuthenticationService(); const session = await service.removeSession(sessionId); @@ -276,7 +243,8 @@ async function configureRegistryAndActivateSubscription() { title: 'Activating Red Hat Subscription', }, async progress => { - if (!isPodmanMachineRunning()) { + const podmanRunningMachineName = getRunningPodmanMachineName(); + if (!podmanRunningMachineName) { if (isLinux()) { await extensionApi.window.showInformationMessage( 'Signing into a Red Hat account requires a running Podman machine, and is currently not supported on a Linux host. Please start a Podman machine and try again.', @@ -301,18 +269,17 @@ async function configureRegistryAndActivateSubscription() { } throw new Error('SCA is not enabled and message closed'); } - - if (!(await isSubscriptionManagerInstalled())) { - await installSubscriptionManger(); - await runStopPodmanMachine(); - await runStartPodmanMachine(); + if (!(await isSubscriptionManagerInstalled(podmanRunningMachineName))) { + await installSubscriptionManger(podmanRunningMachineName); + await runStopPodmanMachine(podmanRunningMachineName); + await runStartPodmanMachine(podmanRunningMachineName); } - if (!(await isPodmanVmSubscriptionActivated())) { + if (!(await isPodmanVmSubscriptionActivated(podmanRunningMachineName))) { const facts = { supported_architectures: 'aarch64,x86_64', }; - await runCreateFactsFile(JSON.stringify(facts, undefined, 2)); - await createOrReuseActivationKey(); + await runCreateFactsFile(podmanRunningMachineName, JSON.stringify(facts, undefined, 2)); + await createOrReuseActivationKey(podmanRunningMachineName); } } }, @@ -326,9 +293,8 @@ async function configureRegistryAndActivateSubscription() { if (!telemetryData.successful && currentSession?.id) { removeSession(currentSession.id); // if at least one fail, remove session } - - TelemetryLogger.logUsage('signin', telemetryData); } + TelemetryLogger.logUsage('signin', telemetryData); } export async function activate(context: extensionApi.ExtensionContext): Promise { diff --git a/src/podman-cli.spec.ts b/src/podman-cli.spec.ts index cbd8b5f4..d5d56cee 100644 --- a/src/podman-cli.spec.ts +++ b/src/podman-cli.spec.ts @@ -67,7 +67,7 @@ beforeEach(() => { test('runSubscriptionManager returns 0 when it is installed', async () => { vi.mocked(podmanProcess.exec).mockResolvedValue(runResult); - const result = await runSubscriptionManager(); + const result = await runSubscriptionManager('machine1'); expect(result).toBe(0); }); @@ -78,15 +78,15 @@ test('runSubscriptionManager returns 1 when it is not installed', async () => { stderr: 'stderr output', toString: () => 'error message', }); - const result = await runSubscriptionManager(); + const result = await runSubscriptionManager('machine1'); expect(result).toBe(1); }); test('runRpmInstallSubscription manager returns 0 when successful', async () => { vi.mocked(podmanProcess.exec).mockResolvedValue(runResult); - const result = await runRpmInstallSubscriptionManager(); + const result = await runRpmInstallSubscriptionManager('machine1'); expect(result).toBe(runResult); - expect(podmanProcess.exec).toBeCalledWith(getPodmanCli(), PODMAN_COMMANDS.RPM_INSTALL_SM()); + expect(podmanProcess.exec).toBeCalledWith(getPodmanCli(), PODMAN_COMMANDS.RPM_INSTALL_SM('machine1')); }); test('runRpmInstallSubscription manager returns none 0 error code when failed and send telemetry', async () => { @@ -96,7 +96,7 @@ test('runRpmInstallSubscription manager returns none 0 error code when failed an }); const consoleError = vi.spyOn(console, 'error'); let error: Error | undefined; - const result = await runRpmInstallSubscriptionManager().catch(err => { + const result = await runRpmInstallSubscriptionManager('machine1').catch(err => { error = err; }); expect(String(error)).toBe(String(runError)); @@ -111,7 +111,7 @@ test('runRpmInstallSubscription manager returns none 0 error code when failed an test('runSubscriptionManagerActivationStatus returns 0 when it has subscription activated', async () => { vi.mocked(podmanProcess.exec).mockResolvedValue(runResult); - const result = await runSubscriptionManagerActivationStatus(); + const result = await runSubscriptionManagerActivationStatus('machine1'); expect(result).toBe(0); }); @@ -122,17 +122,17 @@ test('runSubscriptionManagerActivationStatus returns 1 when it has no active sub stderr: 'stderr output', toString: () => 'error message', }); - const result = await runSubscriptionManagerActivationStatus(); + const result = await runSubscriptionManagerActivationStatus('machine1'); expect(result).toBe(1); }); test('runSubscriptionManagerRegister returns 0 when successful', async () => { vi.mocked(podmanProcess.exec).mockResolvedValue(runResult); - const result = await runSubscriptionManagerRegister('activation-key-name', 'orgId'); + const result = await runSubscriptionManagerRegister('machine1', 'activation-key-name', 'orgId'); expect(result).toBe(runResult); expect(podmanProcess.exec).toBeCalledWith( getPodmanCli(), - PODMAN_COMMANDS.SM_ACTIVATE_SUBS('activation-key-name', 'orgId'), + PODMAN_COMMANDS.SM_ACTIVATE_SUBS('machine1', 'activation-key-name', 'orgId'), ); }); @@ -143,7 +143,7 @@ test('runSubscriptionManagerRegister manager returns none 0 error code when fail }); const consoleError = vi.spyOn(console, 'error'); let error: Error | undefined; - const result = await runSubscriptionManagerRegister('activation-key-name', 'orgId').catch(err => { + const result = await runSubscriptionManagerRegister('machine1', 'activation-key-name', 'orgId').catch(err => { error = err; }); expect(String(error)).toBe(String(runError)); @@ -158,9 +158,12 @@ test('runSubscriptionManagerRegister manager returns none 0 error code when fail test('runCreateFactsFile returns 0 when successful', async () => { vi.mocked(podmanProcess.exec).mockResolvedValue(runResult); - const result = await runCreateFactsFile('{"field":"value"}'); + const result = await runCreateFactsFile('machine1', '{"field":"value"}'); expect(result).toBe(runResult); - expect(podmanProcess.exec).toBeCalledWith(getPodmanCli(), PODMAN_COMMANDS.CREATE_FACTS_FILE('{"field":"value"}')); + expect(podmanProcess.exec).toBeCalledWith( + getPodmanCli(), + PODMAN_COMMANDS.CREATE_FACTS_FILE('machine1', '{"field":"value"}'), + ); }); test('runCreateFactsFile manager returns none 0 error code when failed and send telemetry', async () => { @@ -170,7 +173,7 @@ test('runCreateFactsFile manager returns none 0 error code when failed and send }); const consoleError = vi.spyOn(console, 'error'); let error: Error | undefined; - const result = await runCreateFactsFile('{"field":"value"}').catch(err => { + const result = await runCreateFactsFile('machine1', '{"field":"value"}').catch(err => { error = err; }); expect(String(error)).toBe(String(runError)); @@ -185,9 +188,9 @@ test('runCreateFactsFile manager returns none 0 error code when failed and send test('runStopPodmanMachine returns 0 when successful', async () => { vi.mocked(podmanProcess.exec).mockResolvedValue(runResult); - const result = await runStopPodmanMachine(); + const result = await runStopPodmanMachine('machine1'); expect(result).toBe(runResult); - expect(podmanProcess.exec).toBeCalledWith(getPodmanCli(), PODMAN_COMMANDS.MACHINE_STOP()); + expect(podmanProcess.exec).toBeCalledWith(getPodmanCli(), PODMAN_COMMANDS.MACHINE_STOP('machine1')); }); test('runStopPodmanMachine manager returns none 0 error code when failed and send telemetry', async () => { @@ -197,7 +200,7 @@ test('runStopPodmanMachine manager returns none 0 error code when failed and sen }); const consoleError = vi.spyOn(console, 'error'); let error: Error | undefined; - const result = await runStopPodmanMachine().catch(err => { + const result = await runStopPodmanMachine('machine1').catch(err => { error = err; }); expect(String(error)).toBe(String(runError)); @@ -212,9 +215,9 @@ test('runStopPodmanMachine manager returns none 0 error code when failed and sen test('runStartPodmanMachine returns 0 when successful', async () => { vi.mocked(podmanProcess.exec).mockResolvedValue(runResult); - const result = await runStartPodmanMachine(); + const result = await runStartPodmanMachine('machine1'); expect(result).toBe(runResult); - expect(podmanProcess.exec).toBeCalledWith(getPodmanCli(), PODMAN_COMMANDS.MACHINE_START()); + expect(podmanProcess.exec).toBeCalledWith(getPodmanCli(), PODMAN_COMMANDS.MACHINE_START('machine1')); }); test('runStartPodmanMachine manager returns none 0 error code when failed and send telemetry', async () => { @@ -224,7 +227,7 @@ test('runStartPodmanMachine manager returns none 0 error code when failed and se }); const consoleError = vi.spyOn(console, 'error'); let error: Error | undefined; - const result = await runStartPodmanMachine().catch(err => { + const result = await runStartPodmanMachine('machine1').catch(err => { error = err; }); expect(String(error)).toBe(String(runError)); diff --git a/src/podman-cli.ts b/src/podman-cli.ts index a9157d85..3d90cd22 100644 --- a/src/podman-cli.ts +++ b/src/podman-cli.ts @@ -22,19 +22,23 @@ import { ExtensionTelemetryLogger } from './telemetry'; const macosExtraPath = '/usr/local/bin:/opt/homebrew/bin:/opt/local/bin:/opt/podman/bin'; export const PODMAN_COMMANDS = { - SM_VERSION: () => 'machine ssh sudo subscription-manager'.split(' '), - RPM_INSTALL_SM: () => 'machine ssh sudo rpm-ostree install -y subscription-manager'.split(' '), - SM_ACTIVATION_STATUS: () => 'machine ssh sudo subscription-manager status'.split(' '), - SM_ACTIVATE_SUBS: (activationKeyName: string, orgId: string) => - `machine ssh sudo subscription-manager register --force --activationkey ${activationKeyName} --org ${orgId}`.split( + SM_VERSION: (machineName: string) => `machine ssh ${machineName} sudo subscription-manager`.split(' '), + RPM_INSTALL_SM: (machineName: string) => + `machine ssh ${machineName} sudo rpm-ostree install -y subscription-manager`.split(' '), + SM_ACTIVATION_STATUS: (machineName: string) => + `machine ssh ${machineName} sudo subscription-manager status`.split(' '), + SM_ACTIVATE_SUBS: (machineName: string, activationKeyName: string, orgId: string) => + `machine ssh ${machineName} sudo subscription-manager register --force --activationkey ${activationKeyName} --org ${orgId}`.split( ' ', ), - SM_DEACTIVATE_SUBS: () => `machine ssh sudo subscription-manager unregister`.split(' '), - MACHINE_STOP: () => 'machine stop'.split(' '), - MACHINE_START: () => 'machine start'.split(' '), - CREATE_FACTS_FILE: (oneLineJson: string) => [ + SM_DEACTIVATE_SUBS: (machineName: string) => + `machine ssh ${machineName} sudo subscription-manager unregister`.split(' '), + MACHINE_STOP: (machineName: string) => `machine stop ${machineName}`.split(' '), + MACHINE_START: (machineName: string) => `machine start ${machineName}`.split(' '), + CREATE_FACTS_FILE: (machineName: string, oneLineJson: string) => [ 'machine', 'ssh', + machineName, `sudo mkdir -p /etc/rhsm/facts/ && printf '${oneLineJson}\\n' | sudo tee /etc/rhsm/facts/podman-desktop-redhat-account-ext.facts`, ], }; @@ -86,6 +90,7 @@ async function runCommand( errorHandler: ErrorHandler, ): Promise { try { + console.log(`Executing: ${getPodmanCli()} ${command.join(' ')}`); return await podmanProcess.exec(getPodmanCli(), command).then(() => 0); } catch (err) { return errorHandler(commandName, err); @@ -99,6 +104,7 @@ async function runCommandAndSendTelemetry( errorHandler: TelemetryErrorHandler, ): Promise { try { + console.log(`Executing: ${getPodmanCli()} ${command.join(' ')}`); return await podmanProcess.exec(getPodmanCli(), command); } catch (err) { errorHandler(commandName, telemetryEventName, err); @@ -118,73 +124,77 @@ function errTelemetryHandler(commandName: string, telemetryEventName: string, er throw err; } -export async function runSubscriptionManager(): Promise { - return runCommand('Subscription manager execution', PODMAN_COMMANDS.SM_VERSION(), errToExitCodeHandler); +export async function runSubscriptionManager(machineName: string): Promise { + return runCommand('Subscription manager execution', PODMAN_COMMANDS.SM_VERSION(machineName), errToExitCodeHandler); } -export async function runRpmInstallSubscriptionManager(): Promise { +export async function runRpmInstallSubscriptionManager(machineName: string): Promise { return runCommandAndSendTelemetry( 'Subscription manager installation', 'subscriptionManagerInstallationError', - PODMAN_COMMANDS.RPM_INSTALL_SM(), + PODMAN_COMMANDS.RPM_INSTALL_SM(machineName), errTelemetryHandler, ); } -export async function runSubscriptionManagerActivationStatus(): Promise { +export async function runSubscriptionManagerActivationStatus(machineName: string): Promise { return runCommand( 'Subscription manager subscription activation check', - PODMAN_COMMANDS.SM_ACTIVATION_STATUS(), + PODMAN_COMMANDS.SM_ACTIVATION_STATUS(machineName), errToExitCodeHandler, ); } -export async function runSubscriptionManagerRegister(activationKeyName: string, orgId: string): Promise { +export async function runSubscriptionManagerRegister( + machineName: string, + activationKeyName: string, + orgId: string, +): Promise { return runCommandAndSendTelemetry( 'Subscription manager registration', 'subscriptionManagerRegisterError', - PODMAN_COMMANDS.SM_ACTIVATE_SUBS(activationKeyName, orgId), + PODMAN_COMMANDS.SM_ACTIVATE_SUBS(machineName, activationKeyName, orgId), errTelemetryHandler, ); } -export async function runSubscriptionManagerUnregister(): Promise { +export async function runSubscriptionManagerUnregister(machineName: string): Promise { return runCommandAndSendTelemetry( 'Subscription manager unregister', 'subscriptionManagerUnregisterError', - PODMAN_COMMANDS.SM_DEACTIVATE_SUBS(), + PODMAN_COMMANDS.SM_DEACTIVATE_SUBS(machineName), errTelemetryHandler, ); } -export async function runCreateFactsFile(jsonText: string): Promise { +export async function runCreateFactsFile(machineName: string, jsonText: string): Promise { return runCommandAndSendTelemetry( 'Writing /etc/rhsm/facts/podman-desktop-redhat-account-ext.facts', 'subscriptionManagerCreateFactsFileError', - PODMAN_COMMANDS.CREATE_FACTS_FILE(jsonText.replace('\n', '\\n')), + PODMAN_COMMANDS.CREATE_FACTS_FILE(machineName, jsonText.replace('\n', '\\n')), errTelemetryHandler, ); } -export async function runStopPodmanMachine(): Promise { +export async function runStopPodmanMachine(machineName: string): Promise { return runCommandAndSendTelemetry( 'Podman machine stop', 'stopPodmanMachineError', - PODMAN_COMMANDS.MACHINE_STOP(), + PODMAN_COMMANDS.MACHINE_STOP(machineName), errTelemetryHandler, ); } -export async function runStartPodmanMachine(): Promise { +export async function runStartPodmanMachine(machineName): Promise { return runCommandAndSendTelemetry( 'Podman machine start', 'startPodmanMachineError', - PODMAN_COMMANDS.MACHINE_START(), + PODMAN_COMMANDS.MACHINE_START(machineName), errTelemetryHandler, ); } -export function isPodmanMachineRunning(): boolean { +export function getRunningPodmanMachineName(): string | undefined { const conns = provider.getContainerConnections(); const startedPodman = conns.filter( conn => @@ -192,5 +202,6 @@ export function isPodmanMachineRunning(): boolean { conn.connection.status() === 'started' && !conn.connection.endpoint.socketPath.startsWith('/run/user/'), ); - return startedPodman.length === 1; + const tempName = startedPodman.length === 1 ? startedPodman[0].connection.name : undefined; + return tempName === 'Podman Machine' ? 'podman-machine-default' : tempName; } diff --git a/src/subscription.ts b/src/subscription.ts new file mode 100644 index 00000000..0994128e --- /dev/null +++ b/src/subscription.ts @@ -0,0 +1,42 @@ +import * as extensionApi from '@podman-desktop/api'; +import { accessSync, constants, readFileSync } from 'node:fs'; +import { homedir } from 'node:os'; +import path from 'node:path'; + +export const REGISTRY_REDHAT_IO = 'registry.redhat.io'; + +export async function signIntoRedHatDeveloperAccount( + createIfNone = true, +): Promise { + return extensionApi.authentication.getSession( + 'redhat.authentication-provider', + [ + 'api.iam.registry_service_accounts', //scope that gives access to hydra service accounts API + 'api.console', + ], // scope that gives access to console.redhat.com APIs + { createIfNone }, + ); +} + +// TODO: add listRegistries to registry API to allow search by +// registry URL +export function isRedHatRegistryConfigured(): boolean { + const pathToAuthJson = path.join(homedir(), '.config', 'containers', 'auth.json'); + let configured = false; + try { + // TODO: handle all kind problems with file existence, accessibility and parsable content + accessSync(pathToAuthJson, constants.R_OK); + const authFileContent = readFileSync(pathToAuthJson, { encoding: 'utf8' }); + const authFileJson: { + auths?: { + [registryUrl: string]: { + auth: string; + }; + }; + } = JSON.parse(authFileContent); + configured = authFileJson?.auths?.hasOwnProperty(REGISTRY_REDHAT_IO) || false; + } catch (_notAccessibleError) { + // if file is not there, ignore and return default value + } + return configured; +}