diff --git a/cockpit/webpack.config.ts b/cockpit/webpack.config.ts
index 910bc9c56..00a170fdb 100644
--- a/cockpit/webpack.config.ts
+++ b/cockpit/webpack.config.ts
@@ -27,6 +27,9 @@ module.exports = {
mode,
devtool,
plugins,
+ devServer: {
+ historyApiFallback: true, // Ensures all routes are served with `index.html`
+ },
resolve: {
fallback: {
path: require.resolve('path-browserify'),
diff --git a/fec.config.js b/fec.config.js
index 86ddb935d..8bfa0a782 100644
--- a/fec.config.js
+++ b/fec.config.js
@@ -112,6 +112,7 @@ module.exports = {
// to false
cockpit: false,
'cockpit/fsinfo': false,
+ 'os-release': false,
},
},
routes: {
diff --git a/src/AppCockpit.tsx b/src/AppCockpit.tsx
index 76da43a0e..6384a8fc2 100644
--- a/src/AppCockpit.tsx
+++ b/src/AppCockpit.tsx
@@ -6,7 +6,7 @@ import React from 'react';
import NotificationsPortal from '@redhat-cloud-services/frontend-components-notifications/NotificationPortal';
import { createRoot } from 'react-dom/client';
import { Provider } from 'react-redux';
-import { BrowserRouter } from 'react-router-dom';
+import { HashRouter } from 'react-router-dom';
import { Router } from './Router';
import { onPremStore as store } from './store';
@@ -15,9 +15,9 @@ const Application = () => {
return (
-
+
-
+
);
};
diff --git a/src/Components/Blueprints/BlueprintDiffModal.tsx b/src/Components/Blueprints/BlueprintDiffModal.tsx
index 8501fa7b2..bddf26d59 100644
--- a/src/Components/Blueprints/BlueprintDiffModal.tsx
+++ b/src/Components/Blueprints/BlueprintDiffModal.tsx
@@ -5,9 +5,9 @@ import { Button, Modal, ModalVariant } from '@patternfly/react-core';
import { BuildImagesButton } from './BuildImagesButton';
+import { useGetBlueprintQuery } from '../../store/backendApi';
import { selectSelectedBlueprintId } from '../../store/BlueprintSlice';
import { useAppSelector } from '../../store/hooks';
-import { useGetBlueprintQuery } from '../../store/imageBuilderApi';
type blueprintDiffProps = {
// baseVersion is the version of the blueprint to compare the latest version against
diff --git a/src/Components/Blueprints/BuildImagesButton.tsx b/src/Components/Blueprints/BuildImagesButton.tsx
index 25e364ff9..c486322a8 100644
--- a/src/Components/Blueprints/BuildImagesButton.tsx
+++ b/src/Components/Blueprints/BuildImagesButton.tsx
@@ -19,12 +19,12 @@ import { addNotification } from '@redhat-cloud-services/frontend-components-noti
import { skipToken } from '@reduxjs/toolkit/query';
import { targetOptions } from '../../constants';
+import { useGetBlueprintQuery } from '../../store/backendApi';
import { selectSelectedBlueprintId } from '../../store/BlueprintSlice';
import { useAppDispatch, useAppSelector } from '../../store/hooks';
import {
ImageTypes,
useComposeBlueprintMutation,
- useGetBlueprintQuery,
} from '../../store/imageBuilderApi';
type BuildImagesButtonPropTypes = {
diff --git a/src/Components/CreateImageWizard/CreateImageWizard.tsx b/src/Components/CreateImageWizard/CreateImageWizard.tsx
index 6a6dd2677..ceb80b977 100644
--- a/src/Components/CreateImageWizard/CreateImageWizard.tsx
+++ b/src/Components/CreateImageWizard/CreateImageWizard.tsx
@@ -34,6 +34,7 @@ import Azure from './steps/TargetEnvironment/Azure';
import Gcp from './steps/TargetEnvironment/Gcp';
import TimezoneStep from './steps/Timezone';
import UsersStep from './steps/Users';
+import { getHostArch, getHostDistro } from './utilities/getHostInfo';
import {
useFilesystemValidation,
useSnapshotValidation,
@@ -192,6 +193,24 @@ const CreateImageWizard = ({ isEdit }: CreateImageWizardProps) => {
if (searchParams.get('target') === 'qcow2') {
dispatch(addImageType('guest-image'));
}
+
+ const initializeHostDistro = async () => {
+ const distro = await getHostDistro();
+ dispatch(changeDistribution(distro));
+ };
+
+ const initializeHostArch = async () => {
+ const arch = await getHostArch();
+ dispatch(changeArchitecture(arch));
+ };
+
+ if (process.env.IS_ON_PREMISE) {
+ if (!searchParams.get('release')) {
+ initializeHostDistro();
+ }
+
+ initializeHostArch();
+ }
// This useEffect hook should run *only* on mount and therefore has an empty
// dependency array. eslint's exhaustive-deps rule does not support this use.
// eslint-disable-next-line react-hooks/exhaustive-deps
@@ -391,7 +410,9 @@ const CreateImageWizard = ({ isEdit }: CreateImageWizardProps) => {
name={complianceEnabled ? 'Compliance' : 'OpenSCAP'}
id="step-oscap"
key="step-oscap"
- isHidden={distribution === RHEL_10_BETA}
+ isHidden={
+ distribution === RHEL_10_BETA || !!process.env.IS_ON_PREMISE
+ }
footer={
}
@@ -442,7 +463,9 @@ const CreateImageWizard = ({ isEdit }: CreateImageWizardProps) => {
name="Custom repositories"
id="wizard-custom-repositories"
key="wizard-custom-repositories"
- isHidden={distribution === RHEL_10_BETA}
+ isHidden={
+ distribution === RHEL_10_BETA || !!process.env.IS_ON_PREMISE
+ }
isDisabled={snapshotValidation.disabledNext}
footer={
diff --git a/src/Components/CreateImageWizard/EditImageWizard.tsx b/src/Components/CreateImageWizard/EditImageWizard.tsx
index 31721de5f..cf30de0b6 100644
--- a/src/Components/CreateImageWizard/EditImageWizard.tsx
+++ b/src/Components/CreateImageWizard/EditImageWizard.tsx
@@ -5,8 +5,8 @@ import { useNavigate } from 'react-router-dom';
import CreateImageWizard from './CreateImageWizard';
import { mapRequestToState } from './utilities/requestMapper';
+import { useGetBlueprintQuery } from '../../store/backendApi';
import { useAppDispatch } from '../../store/hooks';
-import { useGetBlueprintQuery } from '../../store/imageBuilderApi';
import { loadWizardState } from '../../store/wizardSlice';
import { resolveRelPath } from '../../Utilities/path';
diff --git a/src/Components/CreateImageWizard/steps/ImageOutput/ArchSelect.tsx b/src/Components/CreateImageWizard/steps/ImageOutput/ArchSelect.tsx
index 3e8669eb6..32fe90c72 100644
--- a/src/Components/CreateImageWizard/steps/ImageOutput/ArchSelect.tsx
+++ b/src/Components/CreateImageWizard/steps/ImageOutput/ArchSelect.tsx
@@ -7,7 +7,7 @@ import {
SelectVariant,
} from '@patternfly/react-core/deprecated';
-import { ARCHS } from '../../../../constants';
+import { ARCHES } from '../../../../constants';
import { useAppDispatch, useAppSelector } from '../../../../store/hooks';
import { ImageRequest } from '../../../../store/imageBuilderApi';
import {
@@ -30,7 +30,15 @@ const ArchSelect = () => {
const setSelectOptions = () => {
const options: ReactElement[] = [];
- ARCHS.forEach((arch) => {
+ const arches = ARCHES.filter((a) => {
+ // we don't want to support cross-arch
+ // builds for on-prem for now
+ if (process.env.IS_ON_PREMISE) {
+ return a === arch;
+ }
+ return true;
+ });
+ arches.forEach((arch) => {
options.push(
{arch}
diff --git a/src/Components/CreateImageWizard/steps/ImageOutput/ReleaseSelect.tsx b/src/Components/CreateImageWizard/steps/ImageOutput/ReleaseSelect.tsx
index 8c0f73ae0..d6ef70262 100644
--- a/src/Components/CreateImageWizard/steps/ImageOutput/ReleaseSelect.tsx
+++ b/src/Components/CreateImageWizard/steps/ImageOutput/ReleaseSelect.tsx
@@ -17,6 +17,7 @@ import {
RHEL_9_FULL_SUPPORT,
RHEL_9_MAINTENANCE_SUPPORT,
RHEL_10_BETA,
+ ON_PREM_RELEASES,
} from '../../../../constants';
import { useAppDispatch, useAppSelector } from '../../../../store/hooks';
import { Distributions } from '../../../../store/imageBuilderApi';
@@ -40,6 +41,8 @@ const ReleaseSelect = () => {
const isRHEL9BetaEnabled = useFlag('image-builder.rhel9.beta.enabled');
const isRHEL10BetaEnabled = useFlag('image-builder.rhel10.beta.enabled');
+ const releases = process.env.IS_ON_PREMISE ? ON_PREM_RELEASES : RELEASES;
+
const handleSelect = (_event: React.MouseEvent, selection: Distributions) => {
dispatch(changeDistribution(selection));
setIsOpen(false);
@@ -75,7 +78,11 @@ const ReleaseSelect = () => {
const setSelectOptions = () => {
const options: ReactElement[] = [];
const filteredRhel = new Map(
- [...RELEASES].filter(([key]) => {
+ [...releases].filter(([key]) => {
+ if (process.env.IS_ON_PREMISE) {
+ return key === distribution;
+ }
+
if (key === RHEL_9_BETA) {
return isRHEL9BetaEnabled;
}
@@ -99,7 +106,7 @@ const ReleaseSelect = () => {
value={key}
description={setDescription(key as Distributions)}
>
- {RELEASES.get(key)}
+ {releases.get(key)}
);
});
@@ -114,14 +121,17 @@ const ReleaseSelect = () => {
variant={SelectVariant.single}
onToggle={() => setIsOpen(!isOpen)}
onSelect={handleSelect}
- selections={RELEASES.get(distribution)}
+ selections={releases.get(distribution)}
isOpen={isOpen}
- {...(!showDevelopmentOptions && {
- loadingVariant: {
- text: 'Show options for further development of RHEL',
- onClick: handleExpand,
- },
- })}
+ {...(!showDevelopmentOptions &&
+ // Hide this for on-prem since the host
+ // could be centos or fedora
+ !process.env.IS_ON_PREMISE && {
+ loadingVariant: {
+ text: 'Show options for further development of RHEL',
+ onClick: handleExpand,
+ },
+ })}
>
{setSelectOptions()}
diff --git a/src/Components/CreateImageWizard/steps/ImageOutput/TargetEnvironment.tsx b/src/Components/CreateImageWizard/steps/ImageOutput/TargetEnvironment.tsx
index dacd1f021..481159637 100644
--- a/src/Components/CreateImageWizard/steps/ImageOutput/TargetEnvironment.tsx
+++ b/src/Components/CreateImageWizard/steps/ImageOutput/TargetEnvironment.tsx
@@ -12,13 +12,10 @@ import {
Tile,
} from '@patternfly/react-core';
import { HelpIcon } from '@patternfly/react-icons';
-import { useFlag } from '@unleash/proxy-client-react';
+import { useGetArchitecturesQuery } from '../../../../store/backendApi';
import { useAppSelector, useAppDispatch } from '../../../../store/hooks';
-import {
- ImageTypes,
- useGetArchitecturesQuery,
-} from '../../../../store/imageBuilderApi';
+import { ImageTypes } from '../../../../store/imageBuilderApi';
import { provisioningApi } from '../../../../store/provisioningApi';
import { rhsmApi } from '../../../../store/rhsmApi';
import {
@@ -31,6 +28,7 @@ import {
selectDistribution,
selectImageTypes,
} from '../../../../store/wizardSlice';
+import { useFlag } from '../../../../Utilities/useGetEnvironment';
const TargetEnvironment = () => {
const arch = useAppSelector(selectArchitecture);
diff --git a/src/Components/CreateImageWizard/steps/Oscap/Oscap.tsx b/src/Components/CreateImageWizard/steps/Oscap/Oscap.tsx
index d883a0219..00f0044b9 100644
--- a/src/Components/CreateImageWizard/steps/Oscap/Oscap.tsx
+++ b/src/Components/CreateImageWizard/steps/Oscap/Oscap.tsx
@@ -24,6 +24,7 @@ import {
RHEL_10_BETA,
RHEL_10,
} from '../../../../constants';
+import { useGetOscapProfilesQuery } from '../../../../store/backendApi';
import { usePoliciesQuery, PolicyRead } from '../../../../store/complianceApi';
import { useAppDispatch, useAppSelector } from '../../../../store/hooks';
import {
@@ -32,7 +33,6 @@ import {
Filesystem,
OpenScapProfile,
useGetOscapCustomizationsQuery,
- useGetOscapProfilesQuery,
useLazyGetOscapCustomizationsQuery,
Services,
} from '../../../../store/imageBuilderApi';
diff --git a/src/Components/CreateImageWizard/steps/Oscap/index.tsx b/src/Components/CreateImageWizard/steps/Oscap/index.tsx
index ae2926562..192f94255 100644
--- a/src/Components/CreateImageWizard/steps/Oscap/index.tsx
+++ b/src/Components/CreateImageWizard/steps/Oscap/index.tsx
@@ -9,7 +9,6 @@ import {
Title,
} from '@patternfly/react-core';
import { ExternalLinkAltIcon } from '@patternfly/react-icons';
-import { useFlag } from '@unleash/proxy-client-react';
import { Oscap, removeBetaFromRelease } from './Oscap';
@@ -18,7 +17,7 @@ import {
COMPLIANCE_PROD_URL,
COMPLIANCE_STAGE_URL,
} from '../../../../constants';
-import { imageBuilderApi } from '../../../../store/enhancedImageBuilderApi';
+import { useBackendPrefetch } from '../../../../store/backendApi';
import { useAppDispatch, useAppSelector } from '../../../../store/hooks';
import { useGetOscapCustomizationsQuery } from '../../../../store/imageBuilderApi';
import {
@@ -35,17 +34,17 @@ import {
selectComplianceType,
clearKernelAppend,
} from '../../../../store/wizardSlice';
-import { useGetEnvironment } from '../../../../Utilities/useGetEnvironment';
+import {
+ useFlag,
+ useGetEnvironment,
+} from '../../../../Utilities/useGetEnvironment';
const OscapStep = () => {
const dispatch = useAppDispatch();
const complianceEnabled = useFlag('image-builder.compliance.enabled');
const complianceType = useAppSelector(selectComplianceType);
const profileID = useAppSelector(selectComplianceProfileID);
- const prefetchOscapProfile = imageBuilderApi.usePrefetch(
- 'getOscapProfiles',
- {}
- );
+ const prefetchOscapProfile = useBackendPrefetch('getOscapProfiles', {});
const { isProd } = useGetEnvironment();
const release = removeBetaFromRelease(useAppSelector(selectDistribution));
const { data: currentProfileData } = useGetOscapCustomizationsQuery(
diff --git a/src/Components/CreateImageWizard/steps/Packages/Packages.tsx b/src/Components/CreateImageWizard/steps/Packages/Packages.tsx
index c662e45cf..52eeefb98 100644
--- a/src/Components/CreateImageWizard/steps/Packages/Packages.tsx
+++ b/src/Components/CreateImageWizard/steps/Packages/Packages.tsx
@@ -49,6 +49,7 @@ import {
EPEL_9_REPO_DEFINITION,
RH_ICON_SIZE,
} from '../../../../constants';
+import { useGetArchitecturesQuery } from '../../../../store/backendApi';
import {
ApiRepositoryResponseRead,
useCreateRepositoryMutation,
@@ -57,10 +58,7 @@ import {
useSearchPackageGroupMutation,
} from '../../../../store/contentSourcesApi';
import { useAppSelector } from '../../../../store/hooks';
-import {
- Package,
- useGetArchitecturesQuery,
-} from '../../../../store/imageBuilderApi';
+import { Package } from '../../../../store/imageBuilderApi';
import {
selectArchitecture,
selectPackages,
diff --git a/src/Components/CreateImageWizard/steps/Packages/index.tsx b/src/Components/CreateImageWizard/steps/Packages/index.tsx
index ed8702308..35501ddd6 100644
--- a/src/Components/CreateImageWizard/steps/Packages/index.tsx
+++ b/src/Components/CreateImageWizard/steps/Packages/index.tsx
@@ -1,7 +1,6 @@
import React from 'react';
import { Alert, Text, Form, Title } from '@patternfly/react-core';
-import { useFlag } from '@unleash/proxy-client-react';
import PackageRecommendations from './PackageRecommendations';
import Packages from './Packages';
@@ -9,6 +8,7 @@ import Packages from './Packages';
import { RHEL_8, RHEL_9 } from '../../../../constants';
import { useAppSelector } from '../../../../store/hooks';
import { selectDistribution } from '../../../../store/wizardSlice';
+import { useFlag } from '../../../../Utilities/useGetEnvironment';
const PackagesStep = () => {
const packageRecommendationsFlag = useFlag('image-builder.pkgrecs.enabled');
diff --git a/src/Components/CreateImageWizard/steps/Registration/index.tsx b/src/Components/CreateImageWizard/steps/Registration/index.tsx
index 5a1900156..0acaa5589 100644
--- a/src/Components/CreateImageWizard/steps/Registration/index.tsx
+++ b/src/Components/CreateImageWizard/steps/Registration/index.tsx
@@ -26,15 +26,17 @@ const RegistrationStep = () => {
system during initial boot.
-
- {activationKey && registrationType !== 'register-later' && (
-
-
-
- )}
+ {!process.env.IS_ON_PREMISE && }
+ {!process.env.IS_ON_PREMISE &&
+ activationKey &&
+ registrationType !== 'register-later' && (
+
+
+
+ )}
);
};
diff --git a/src/Components/CreateImageWizard/steps/Review/ReviewStepTextLists.tsx b/src/Components/CreateImageWizard/steps/Review/ReviewStepTextLists.tsx
index e6d0c6c46..55744870b 100644
--- a/src/Components/CreateImageWizard/steps/Review/ReviewStepTextLists.tsx
+++ b/src/Components/CreateImageWizard/steps/Review/ReviewStepTextLists.tsx
@@ -24,6 +24,7 @@ import {
import { FSReviewTable } from './ReviewStepTables';
import {
+ ON_PREM_RELEASES,
RELEASES,
RHEL_8,
RHEL_8_FULL_SUPPORT,
@@ -93,6 +94,7 @@ const ExpirationWarning = () => {
export const ImageOutputList = () => {
const distribution = useAppSelector(selectDistribution);
const arch = useAppSelector(selectArchitecture);
+ const releases = process.env.IS_ON_PREMISE ? ON_PREM_RELEASES : RELEASES;
return (
{distribution === RHEL_8 && (
@@ -118,7 +120,7 @@ export const ImageOutputList = () => {
Release
- {RELEASES.get(distribution)}
+ {releases.get(distribution)}
Architecture
diff --git a/src/Components/CreateImageWizard/utilities/getHostInfo.ts b/src/Components/CreateImageWizard/utilities/getHostInfo.ts
new file mode 100644
index 000000000..beff5a858
--- /dev/null
+++ b/src/Components/CreateImageWizard/utilities/getHostInfo.ts
@@ -0,0 +1,18 @@
+import cockpit from 'cockpit';
+import { read_os_release } from 'os-release';
+
+import { Distributions } from '../../../store/imageBuilderApi';
+
+export const getHostDistro = async () => {
+ const osRel = await read_os_release();
+ return `${osRel.ID}-${osRel.VERSION_ID}` as Distributions;
+};
+
+type Architecture = 'x86_64' | 'aarch64';
+export const getHostArch = async () => {
+ const hostArch = await cockpit.spawn(['uname', '-m'], {
+ superuser: 'try',
+ });
+
+ return (hostArch as string).trim() as Architecture;
+};
diff --git a/src/Components/CreateImageWizard/utilities/useValidation.tsx b/src/Components/CreateImageWizard/utilities/useValidation.tsx
index 25aba3631..433039eeb 100644
--- a/src/Components/CreateImageWizard/utilities/useValidation.tsx
+++ b/src/Components/CreateImageWizard/utilities/useValidation.tsx
@@ -1,11 +1,9 @@
import { useEffect, useState } from 'react';
import { UNIQUE_VALIDATION_DELAY } from '../../../constants';
+import { useLazyGetBlueprintsQuery } from '../../../store/backendApi';
import { useAppSelector } from '../../../store/hooks';
-import {
- BlueprintsResponse,
- useLazyGetBlueprintsQuery,
-} from '../../../store/imageBuilderApi';
+import { BlueprintsResponse } from '../../../store/imageBuilderApi';
import { useShowActivationKeyQuery } from '../../../store/rhsmApi';
import {
selectBlueprintId,
diff --git a/src/Components/edge/ImageDetails.tsx b/src/Components/edge/ImageDetails.tsx
index 1b15829c6..89d45586a 100644
--- a/src/Components/edge/ImageDetails.tsx
+++ b/src/Components/edge/ImageDetails.tsx
@@ -3,7 +3,6 @@ import React from 'react';
import AsyncComponent from '@redhat-cloud-services/frontend-components/AsyncComponent';
import ErrorState from '@redhat-cloud-services/frontend-components/ErrorState';
import Unavailable from '@redhat-cloud-services/frontend-components/Unavailable';
-import { useFlag } from '@unleash/proxy-client-react';
import { useDispatch } from 'react-redux';
import { useNavigate, useLocation, useParams } from 'react-router-dom';
@@ -12,6 +11,7 @@ import {
manageEdgeImagesUrlName,
} from '../../Utilities/edge';
import { resolveRelPath } from '../../Utilities/path';
+import { useFlag } from '../../Utilities/useGetEnvironment';
const ImageDetail = () => {
const dispatch = useDispatch();
diff --git a/src/Components/edge/ImagesTable.tsx b/src/Components/edge/ImagesTable.tsx
index b8c9a17ea..d8c54de69 100644
--- a/src/Components/edge/ImagesTable.tsx
+++ b/src/Components/edge/ImagesTable.tsx
@@ -3,7 +3,6 @@ import React from 'react';
import AsyncComponent from '@redhat-cloud-services/frontend-components/AsyncComponent';
import ErrorState from '@redhat-cloud-services/frontend-components/ErrorState';
import Unavailable from '@redhat-cloud-services/frontend-components/Unavailable';
-import { useFlag } from '@unleash/proxy-client-react';
import { useDispatch } from 'react-redux';
import { useNavigate, useLocation } from 'react-router-dom';
@@ -13,6 +12,7 @@ import {
manageEdgeImagesUrlName,
} from '../../Utilities/edge';
import { resolveRelPath } from '../../Utilities/path';
+import { useFlag } from '../../Utilities/useGetEnvironment';
const ImagesTable = () => {
const dispatch = useDispatch();
diff --git a/src/Components/sharedComponents/ImageBuilderHeader.tsx b/src/Components/sharedComponents/ImageBuilderHeader.tsx
index ce2a71276..b911c6317 100644
--- a/src/Components/sharedComponents/ImageBuilderHeader.tsx
+++ b/src/Components/sharedComponents/ImageBuilderHeader.tsx
@@ -24,8 +24,8 @@ import {
CREATING_IMAGES_WITH_IB_SERVICE_URL,
OSBUILD_SERVICE_ARCHITECTURE_URL,
} from '../../constants';
+import { useBackendPrefetch } from '../../store/backendApi';
import { useAppSelector } from '../../store/hooks';
-import { imageBuilderApi } from '../../store/imageBuilderApi';
import { selectDistribution } from '../../store/wizardSlice';
import { resolveRelPath } from '../../Utilities/path';
import './ImageBuilderHeader.scss';
@@ -99,7 +99,7 @@ export const ImageBuilderHeader = ({
const navigate = useNavigate();
const distribution = useAppSelector(selectDistribution);
- const prefetchTargets = imageBuilderApi.usePrefetch('getArchitectures');
+ const prefetchTargets = useBackendPrefetch('getArchitectures');
const importExportFlag = useFlagWithEphemDefault(
'image-builder.import.enabled'
diff --git a/src/Utilities/path.ts b/src/Utilities/path.ts
index 15cafc6e1..16d9d52c5 100644
--- a/src/Utilities/path.ts
+++ b/src/Utilities/path.ts
@@ -1,4 +1,9 @@
function resolveRelPath(path = '') {
+ if (process.env.IS_ON_PREMISE) {
+ // We're using the hash router
+ // so we can just return the path
+ return path.length > 0 ? path : '/';
+ }
return `/insights/image-builder${path.length > 0 ? `/${path}` : ''}`;
}
diff --git a/src/Utilities/useGetEnvironment.ts b/src/Utilities/useGetEnvironment.ts
index 3ec3d1bcd..eaeced88c 100644
--- a/src/Utilities/useGetEnvironment.ts
+++ b/src/Utilities/useGetEnvironment.ts
@@ -1,14 +1,16 @@
import { useChrome } from '@redhat-cloud-services/frontend-components/useChrome';
import { useFlag as useUnleashFlag } from '@unleash/proxy-client-react';
-export const useGetEnvironment = () => {
- const { isBeta, isProd, getEnvironment } = useChrome();
- // Expose beta features in the ephemeral environment
- if (isBeta() || getEnvironment() === 'qa') {
- return { isBeta: () => true, isProd: isProd };
- }
- return { isBeta: () => false, isProd: isProd };
-};
+export const useGetEnvironment = process.env.IS_ON_PREMISE
+ ? () => ({ isBeta: () => false, isProd: () => true })
+ : () => {
+ const { isBeta, isProd, getEnvironment } = useChrome();
+ // Expose beta features in the ephemeral environment
+ if (isBeta() || getEnvironment() === 'qa') {
+ return { isBeta: () => true, isProd: isProd };
+ }
+ return { isBeta: () => false, isProd: isProd };
+ };
/**
* A hook that returns the value of a flag with a default value for ephemeral environment.
diff --git a/src/constants.ts b/src/constants.ts
index 8e49932c2..af41711c4 100644
--- a/src/constants.ts
+++ b/src/constants.ts
@@ -56,6 +56,9 @@ export const RHEL_9_BETA = 'rhel-9-beta';
export const RHEL_10 = 'rhel-10';
export const RHEL_10_BETA = 'rhel-10-beta';
export const CENTOS_9 = 'centos-9';
+export const CENTOS_10 = 'centos-10';
+export const FEDORA_40 = 'fedora-40';
+export const FEDORA_41 = 'fedora-41';
export const X86_64 = 'x86_64';
export const AARCH64 = 'aarch64';
@@ -90,12 +93,20 @@ export const RELEASES = new Map([
[CENTOS_9, 'CentOS Stream 9'],
]);
+export const ON_PREM_RELEASES = new Map([
+ [CENTOS_10, 'CentOS Stream 10'],
+ [FEDORA_40, 'Fedora Linux 40'],
+ [FEDORA_41, 'Fedora Linux 41'],
+ [RHEL_10_BETA, 'Red Hat Enterprise Linux (RHEL) 10 Beta'],
+ [RHEL_10, 'Red Hat Enterprise Linux (RHEL) 10'],
+]);
+
export const RHEL_9_FULL_SUPPORT = ['2022-05-18', '2027-05-31'];
export const RHEL_8_FULL_SUPPORT = ['2019-05-07', '2024-05-31'];
export const RHEL_9_MAINTENANCE_SUPPORT = ['2027-05-31', '2032-05-31'];
export const RHEL_8_MAINTENANCE_SUPPORT = ['2024-05-31', '2029-05-31'];
-export const ARCHS = [X86_64, AARCH64];
+export const ARCHES = [X86_64, AARCH64];
export const DEFAULT_AWS_REGION = 'us-east-1';
diff --git a/src/store/backendApi.ts b/src/store/backendApi.ts
index 1a1564158..250d8ed71 100644
--- a/src/store/backendApi.ts
+++ b/src/store/backendApi.ts
@@ -1,21 +1,35 @@
-import {
- useGetBlueprintsQuery as useCockpitGetBlueprintsQuery,
- useDeleteBlueprintMutation as useCockpitDeleteMutation,
-} from './cockpitApi';
+import * as cockpitQueries from './cockpitApi';
import { cockpitApi } from './enhancedCockpitApi';
import { imageBuilderApi } from './enhancedImageBuilderApi';
-import {
- useGetBlueprintsQuery as useImageBuilderGetBlueprintsQuery,
- useDeleteBlueprintMutation as useImageBuilderDeleteMutation,
-} from './imageBuilderApi';
+import * as imageBuilderQueries from './imageBuilderApi';
+
+export const useGetArchitecturesQuery = process.env.IS_ON_PREMISE
+ ? cockpitQueries.useGetArchitecturesQuery
+ : imageBuilderQueries.useGetArchitecturesQuery;
+
+export const useGetBlueprintQuery = process.env.IS_ON_PREMISE
+ ? cockpitQueries.useGetBlueprintQuery
+ : imageBuilderQueries.useGetBlueprintQuery;
export const useGetBlueprintsQuery = process.env.IS_ON_PREMISE
- ? useCockpitGetBlueprintsQuery
- : useImageBuilderGetBlueprintsQuery;
+ ? cockpitQueries.useGetBlueprintsQuery
+ : imageBuilderQueries.useGetBlueprintsQuery;
+
+export const useLazyGetBlueprintsQuery = process.env.IS_ON_PREMISE
+ ? cockpitQueries.useLazyGetBlueprintsQuery
+ : imageBuilderQueries.useLazyGetBlueprintsQuery;
export const useDeleteBlueprintMutation = process.env.IS_ON_PREMISE
- ? useCockpitDeleteMutation
- : useImageBuilderDeleteMutation;
+ ? cockpitQueries.useDeleteBlueprintMutation
+ : imageBuilderQueries.useDeleteBlueprintMutation;
+
+export const useGetOscapProfilesQuery = process.env.IS_ON_PREMISE
+ ? cockpitQueries.useGetOscapProfilesQuery
+ : imageBuilderQueries.useGetOscapProfilesQuery;
+
+export const useBackendPrefetch = process.env.IS_ON_PREMISE
+ ? cockpitApi.usePrefetch
+ : imageBuilderApi.usePrefetch;
export const backendApi = process.env.IS_ON_PREMISE
? cockpitApi
diff --git a/src/store/cockpitApi.ts b/src/store/cockpitApi.ts
index 9e5f6d5dd..cdd1718e9 100644
--- a/src/store/cockpitApi.ts
+++ b/src/store/cockpitApi.ts
@@ -19,6 +19,10 @@ import {
DeleteBlueprintApiResponse,
DeleteBlueprintApiArg,
BlueprintItem,
+ GetOscapProfilesApiArg,
+ GetOscapProfilesApiResponse,
+ GetBlueprintApiResponse,
+ GetBlueprintApiArg,
} from './imageBuilderApi';
import { mapOnPremToHosted } from '../Components/Blueprints/helpers/onPremToHostedBlueprintMapper';
@@ -39,9 +43,62 @@ export const cockpitApi = emptyCockpitApi.injectEndpoints({
GetArchitecturesApiResponse,
GetArchitecturesApiArg
>({
- query: (queryArg) => ({
- url: `/architectures/${queryArg.distribution}`,
- }),
+ queryFn: () => {
+ // TODO: this is hardcoded for now, but we may need to query
+ // the cloudapi endpoint on the composer socket to get the
+ // available information
+ return {
+ data: [
+ {
+ arch: 'aarch64',
+ image_types: ['aws', 'guest-image', 'image-installer'],
+ repositories: [],
+ },
+ {
+ arch: 'x86_64',
+ image_types: [
+ 'aws',
+ 'gcp',
+ 'azure',
+ 'rhel-edge-commit',
+ 'rhel-edge-installer',
+ 'edge-commit',
+ 'edge-installer',
+ 'guest-image',
+ 'image-installer',
+ 'vsphere',
+ ],
+ repositories: [],
+ },
+ ],
+ };
+ },
+ }),
+ getBlueprint: builder.query({
+ queryFn: async ({ id, version }) => {
+ try {
+ const blueprintsDir = await getBlueprintsPath();
+ const file = cockpit.file(path.join(blueprintsDir, id));
+
+ const contents = await file.read();
+ const parsed = toml.parse(contents);
+ file.close();
+
+ const blueprint = mapOnPremToHosted(parsed);
+
+ return {
+ data: {
+ ...blueprint,
+ id,
+ version,
+ last_modified_at: Date.now().toString(),
+ image_requests: [],
+ },
+ };
+ } catch (error) {
+ return { error };
+ }
+ },
}),
getBlueprints: builder.query<
GetBlueprintsApiResponse,
@@ -143,12 +200,28 @@ export const cockpitApi = emptyCockpitApi.injectEndpoints({
}
},
}),
+ getOscapProfiles: builder.query<
+ GetOscapProfilesApiResponse,
+ GetOscapProfilesApiArg
+ >({
+ queryFn: async () => {
+ // TODO: make a call to get the openscap profiles
+ // For now, just return an empty list so we can
+ // step through the wizard.
+ return {
+ data: [],
+ };
+ },
+ }),
};
},
});
export const {
+ useGetArchitecturesQuery,
+ useGetBlueprintQuery,
useGetBlueprintsQuery,
+ useLazyGetBlueprintsQuery,
useDeleteBlueprintMutation,
- useGetArchitecturesQuery,
+ useGetOscapProfilesQuery,
} = cockpitApi;
diff --git a/src/store/index.ts b/src/store/index.ts
index 9a8c06781..46557ae6e 100644
--- a/src/store/index.ts
+++ b/src/store/index.ts
@@ -33,6 +33,10 @@ export const serviceReducer = combineReducers({
});
export const onPremReducer = combineReducers({
+ [contentSourcesApi.reducerPath]: contentSourcesApi.reducer,
+ [rhsmApi.reducerPath]: rhsmApi.reducer,
+ [provisioningApi.reducerPath]: provisioningApi.reducer,
+ [complianceApi.reducerPath]: complianceApi.reducer,
[cockpitApi.reducerPath]: cockpitApi.reducer,
// TODO: add other endpoints so we can remove this.
// It's still needed to get things to work.
@@ -125,6 +129,10 @@ export const onPremMiddleware = (getDefaultMiddleware: Function) =>
promiseMiddleware,
// TODO: add other endpoints so we can remove this.
// It's still needed to get things to work.
+ contentSourcesApi.middleware,
+ rhsmApi.middleware,
+ provisioningApi.middleware,
+ complianceApi.middleware,
imageBuilderApi.middleware,
cockpitApi.middleware
);
diff --git a/src/test/mocks/os-release/index.ts b/src/test/mocks/os-release/index.ts
new file mode 100644
index 000000000..81fab5061
--- /dev/null
+++ b/src/test/mocks/os-release/index.ts
@@ -0,0 +1,13 @@
+type osRelease = {
+ ID: string;
+ VERSION_ID: string;
+};
+
+export const read_os_release = (): Promise => {
+ return new Promise((resolve) => {
+ resolve({
+ ID: '',
+ VERSION_ID: '',
+ });
+ });
+};
diff --git a/vitest.config.ts b/vitest.config.ts
index ea646e570..0d67068c8 100644
--- a/vitest.config.ts
+++ b/vitest.config.ts
@@ -34,6 +34,7 @@ const config = {
__dirname,
'src/test/mocks/cockpit/fsinfo'
),
+ 'os-release': path.resolve(__dirname, 'src/test/mocks/os-release'),
},
},
esbuild: {