Fedora-services: add support for fedora env

This commit is contained in:
Amir 2025-03-12 19:05:44 +02:00 committed by Klara Simickova
parent 72aed71662
commit 1d86950f45
10 changed files with 111 additions and 45 deletions

View file

@ -57,7 +57,7 @@ import {
isGcpEmailValid,
} from './validators';
import { RHEL_8, RHEL_10_BETA, AARCH64 } from '../../constants';
import { RHEL_8, RHEL_10_BETA, AARCH64, CENTOS_9 } from '../../constants';
import { useAppDispatch, useAppSelector } from '../../store/hooks';
import './CreateImageWizard.scss';
import {
@ -77,10 +77,11 @@ import {
selectGcpShareMethod,
selectImageTypes,
addImageType,
changeRegistrationType,
} from '../../store/wizardSlice';
import isRhel from '../../Utilities/isRhel';
import { resolveRelPath } from '../../Utilities/path';
import { useFlag } from '../../Utilities/useGetEnvironment';
import { useFlag, useGetEnvironment } from '../../Utilities/useGetEnvironment';
import { ImageBuilderHeader } from '../sharedComponents/ImageBuilderHeader';
type CustomWizardFooterPropType = {
@ -145,7 +146,7 @@ const CreateImageWizard = ({ isEdit }: CreateImageWizardProps) => {
const navigate = useNavigate();
const dispatch = useAppDispatch();
const [searchParams] = useSearchParams();
const { isFedoraEnv } = useGetEnvironment();
// Feature flags
const isFirstBootEnabled = useFlag('image-builder.firstboot.enabled');
const complianceEnabled = useFlag('image-builder.compliance.enabled');
@ -158,6 +159,10 @@ const CreateImageWizard = ({ isEdit }: CreateImageWizardProps) => {
// IMPORTANT: Ensure the wizard starts with a fresh initial state
useEffect(() => {
dispatch(initializeWizard());
if (isFedoraEnv) {
dispatch(changeDistribution(CENTOS_9));
dispatch(changeRegistrationType('register-later'));
}
if (searchParams.get('release') === 'rhel8') {
dispatch(changeDistribution(RHEL_8));
}
@ -273,14 +278,14 @@ const CreateImageWizard = ({ isEdit }: CreateImageWizardProps) => {
);
// Only this code is different from the original
const status = (step.id !== activeStep.id && step.status) || 'default';
const status = (step?.id !== activeStep?.id && step?.status) || 'default';
return (
<WizardNavItem
key={step.id}
id={step.id}
key={step?.id}
id={step?.id}
content={step.name}
isCurrent={activeStep.id === step.id}
isCurrent={activeStep?.id === step?.id}
isDisabled={
step.isDisabled ||
(!step.isVisited &&
@ -450,7 +455,9 @@ const CreateImageWizard = ({ isEdit }: CreateImageWizardProps) => {
navItem={customStatusNavItem}
status={snapshotValidation.disabledNext ? 'error' : 'default'}
isHidden={
distribution === RHEL_10_BETA || !!process.env.IS_ON_PREMISE
distribution === RHEL_10_BETA ||
!!process.env.IS_ON_PREMISE ||
isFedoraEnv
}
footer={
<CustomWizardFooter
@ -467,7 +474,9 @@ const CreateImageWizard = ({ isEdit }: CreateImageWizardProps) => {
key="wizard-custom-repositories"
navItem={customStatusNavItem}
isHidden={
distribution === RHEL_10_BETA || !!process.env.IS_ON_PREMISE
distribution === RHEL_10_BETA ||
!!process.env.IS_ON_PREMISE ||
isFedoraEnv
}
isDisabled={snapshotValidation.disabledNext}
footer={
@ -481,6 +490,7 @@ const CreateImageWizard = ({ isEdit }: CreateImageWizardProps) => {
id="wizard-additional-packages"
key="wizard-additional-packages"
navItem={customStatusNavItem}
isHidden={isFedoraEnv}
isDisabled={snapshotValidation.disabledNext}
footer={
<CustomWizardFooter disableNext={false} optional={true} />

View file

@ -20,6 +20,7 @@ import {
RHEL_9_MAINTENANCE_SUPPORT,
RHEL_10_BETA,
ON_PREM_RELEASES,
FEDORA_RELEASES,
} from '../../../../constants';
import { useAppDispatch, useAppSelector } from '../../../../store/hooks';
import { Distributions } from '../../../../store/imageBuilderApi';
@ -30,7 +31,10 @@ import {
} from '../../../../store/wizardSlice';
import isRhel from '../../../../Utilities/isRhel';
import { toMonthAndYear } from '../../../../Utilities/time';
import { useFlag } from '../../../../Utilities/useGetEnvironment';
import {
useFlag,
useGetEnvironment,
} from '../../../../Utilities/useGetEnvironment';
const ReleaseSelect = () => {
// What the UI refers to as the "release" is referred to as the "distribution" in the API.
@ -39,12 +43,18 @@ const ReleaseSelect = () => {
const distribution = useAppSelector(selectDistribution);
const dispatch = useAppDispatch();
const [isOpen, setIsOpen] = useState(false);
const [showDevelopmentOptions, setShowDevelopmentOptions] = useState(false);
const { isFedoraEnv } = useGetEnvironment();
const [showDevelopmentOptions, setShowDevelopmentOptions] =
useState(isFedoraEnv);
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 releases = isFedoraEnv
? FEDORA_RELEASES
: process.env.IS_ON_PREMISE
? ON_PREM_RELEASES
: RELEASES;
const handleSelect = (_event: React.MouseEvent, selection: Distributions) => {
if (selection !== ('loader' as Distributions)) {

View file

@ -28,18 +28,25 @@ import {
selectDistribution,
selectImageTypes,
} from '../../../../store/wizardSlice';
import { useFlag } from '../../../../Utilities/useGetEnvironment';
import isRhel from '../../../../Utilities/isRhel';
import {
useFlag,
useGetEnvironment,
} from '../../../../Utilities/useGetEnvironment';
const TargetEnvironment = () => {
const arch = useAppSelector(selectArchitecture);
const environments = useAppSelector(selectImageTypes);
const distribution = useAppSelector(selectDistribution);
const { isFedoraEnv } = useGetEnvironment();
const wslFlag = useFlag('image-builder.wsl.enabled');
const { data } = useGetArchitecturesQuery({
distribution: distribution,
});
const { data } = useGetArchitecturesQuery(
{
distribution: distribution,
},
{ skip: isFedoraEnv && isRhel(distribution) }
);
// TODO: Handle isFetching state (add skeletons)
// TODO: Handle isError state (very unlikely...)
@ -51,7 +58,7 @@ const TargetEnvironment = () => {
const prefetchActivationKeys = rhsmApi.usePrefetch('listActivationKeys');
useEffect(() => {
prefetchActivationKeys();
if (!isFedoraEnv) prefetchActivationKeys();
}, []);
const supportedEnvironments = data?.find(

View file

@ -21,6 +21,7 @@ import {
useComposeBlueprintMutation,
} from '../../../../../store/imageBuilderApi';
import { selectPackages } from '../../../../../store/wizardSlice';
import { useGetEnvironment } from '../../../../../Utilities/useGetEnvironment';
type CreateDropdownProps = {
getBlueprintPayload: () => Promise<'' | CreateBlueprintRequest | undefined>;
@ -41,11 +42,12 @@ export const CreateSaveAndBuildBtn = ({
fixedCacheKey: 'createBlueprintKey',
});
const dispatch = useAppDispatch();
const { isFedoraEnv } = useGetEnvironment();
const onSaveAndBuild = async () => {
const requestBody = await getBlueprintPayload();
setIsOpen(false);
if (!process.env.IS_ON_PREMISE) {
if (!process.env.IS_ON_PREMISE && !isFedoraEnv) {
analytics.track(`${AMPLITUDE_MODULE_NAME}-blueprintCreated`, {
module: AMPLITUDE_MODULE_NAME,
isPreview: isBeta(),
@ -86,6 +88,7 @@ export const CreateSaveButton = ({
}: CreateDropdownProps) => {
const { analytics, isBeta } = useChrome();
const packages = useAppSelector(selectPackages);
const { isFedoraEnv } = useGetEnvironment();
const [createBlueprint, { isLoading }] = useCreateBlueprintMutation({
fixedCacheKey: 'createBlueprintKey',
@ -138,7 +141,7 @@ export const CreateSaveButton = ({
const requestBody = await getBlueprintPayload();
setIsOpen(false);
if (!process.env.IS_ON_PREMISE) {
if (!process.env.IS_ON_PREMISE && !isFedoraEnv) {
analytics.track(`${AMPLITUDE_MODULE_NAME}-blueprintCreated`, {
module: AMPLITUDE_MODULE_NAME,
isPreview: isBeta(),
@ -146,13 +149,11 @@ export const CreateSaveButton = ({
packages: packages.map((pkg) => pkg.name),
});
}
const blueprint =
requestBody &&
(await createBlueprint({
createBlueprintRequest: requestBody,
}).unwrap());
if (blueprint) {
dispatch(setBlueprintId(blueprint?.id));
}

View file

@ -20,6 +20,7 @@ import {
useUpdateBlueprintMutation,
} from '../../../../../store/backendApi';
import { resolveRelPath } from '../../../../../Utilities/path';
import { useGetEnvironment } from '../../../../../Utilities/useGetEnvironment';
import { mapRequestFromState } from '../../../utilities/requestMapper';
import { useIsBlueprintValid } from '../../../utilities/useValidation';
@ -33,6 +34,7 @@ const ReviewWizardFooter = () => {
useUpdateBlueprintMutation({ fixedCacheKey: 'updateBlueprintKey' });
const { auth } = useChrome();
const { composeId } = useParams();
const { isFedoraEnv } = useGetEnvironment();
const [isOpen, setIsOpen] = useState(false);
const store = useStore();
const onToggleClick = () => {
@ -50,7 +52,7 @@ const ReviewWizardFooter = () => {
}, [isUpdateSuccess, isCreateSuccess, resetCreate, resetUpdate, navigate]);
const getBlueprintPayload = async () => {
if (!process.env.IS_ON_PREMISE) {
if (!process.env.IS_ON_PREMISE && !isFedoraEnv) {
const userData = await auth?.getUser();
const orgId = userData?.identity?.internal?.org_id;
const requestBody = orgId && mapRequestFromState(store, orgId);

View file

@ -61,7 +61,10 @@ import {
selectUsers,
selectKernel,
} from '../../../../store/wizardSlice';
import { useFlag } from '../../../../Utilities/useGetEnvironment';
import {
useFlag,
useGetEnvironment,
} from '../../../../Utilities/useGetEnvironment';
const Review = () => {
const { goToStepById } = useWizardContext();
@ -196,6 +199,7 @@ const Review = () => {
const isFirstBootEnabled = useFlag('image-builder.firstboot.enabled');
const isUsersEnabled = useFlag('image-builder.users.enabled');
const { isFedoraEnv } = useGetEnvironment();
return (
<>
<ExpandableSection
@ -355,21 +359,23 @@ const Review = () => {
>
<FSCList />
</ExpandableSection>
<ExpandableSection
toggleContent={composeExpandable(
'Content',
'revisit-custom-repositories',
'wizard-custom-repositories'
)}
onToggle={(_event, isExpandedContent) =>
onToggleContent(isExpandedContent)
}
isExpanded={isExpandedContent}
isIndented
data-testid="content-expandable"
>
<ContentList />
</ExpandableSection>
{!isFedoraEnv && (
<ExpandableSection
toggleContent={composeExpandable(
'Content',
'revisit-custom-repositories',
'wizard-custom-repositories'
)}
onToggle={(_event, isExpandedContent) =>
onToggleContent(isExpandedContent)
}
isExpanded={isExpandedContent}
isIndented
data-testid="content-expandable"
>
<ContentList />
</ExpandableSection>
)}
{isUsersEnabled && users.length > 0 && (
<ExpandableSection
toggleContent={composeExpandable(

View file

@ -26,6 +26,7 @@ import {
import { FSReviewTable } from './ReviewStepTables';
import {
FEDORA_RELEASES,
ON_PREM_RELEASES,
RELEASES,
RHEL_8,
@ -80,6 +81,7 @@ import {
selectServices,
} from '../../../../store/wizardSlice';
import { toMonthAndYear, yyyyMMddFormat } from '../../../../Utilities/time';
import { useGetEnvironment } from '../../../../Utilities/useGetEnvironment';
import {
getConversionFactor,
MinimumSizePopover,
@ -100,7 +102,12 @@ const ExpirationWarning = () => {
export const ImageOutputList = () => {
const distribution = useAppSelector(selectDistribution);
const arch = useAppSelector(selectArchitecture);
const releases = process.env.IS_ON_PREMISE ? ON_PREM_RELEASES : RELEASES;
const { isFedoraEnv } = useGetEnvironment();
const releases = isFedoraEnv
? FEDORA_RELEASES
: process.env.IS_ON_PREMISE
? ON_PREM_RELEASES
: RELEASES;
return (
<TextContent>
{distribution === RHEL_8 && (

View file

@ -2,14 +2,19 @@ import { useChrome } from '@redhat-cloud-services/frontend-components/useChrome'
import { useFlag as useUnleashFlag } from '@unleash/proxy-client-react';
export const useGetEnvironment = process.env.IS_ON_PREMISE
? () => ({ isBeta: () => false, isProd: () => true })
? () => ({ isBeta: () => false, isProd: () => true, isFedoraEnv: false })
: () => {
const { isBeta, isProd, getEnvironment } = useChrome();
const { isBeta, isProd, getEnvironment, getEnvironmentDetails } =
useChrome();
// Expose beta features in the ephemeral environment
const isFedoraEnv: boolean =
getEnvironmentDetails()?.url.some((x: string) =>
x.includes('fedora')
) ?? false;
if (isBeta() || getEnvironment() === 'qa') {
return { isBeta: () => true, isProd: isProd };
return { isBeta: () => true, isProd: isProd, isFedoraEnv };
}
return { isBeta: () => false, isProd: isProd };
return { isBeta: () => false, isProd: isProd, isFedoraEnv };
};
/**
@ -47,4 +52,12 @@ const onPremFlag = (flag: string): boolean => {
// Since some of these flags are only relevant to
// the service, we need a way of bypassing this for on-prem
export const useFlag = !process.env.IS_ON_PREMISE ? useUnleashFlag : onPremFlag;
export const useFlag = (flag: string) => {
const { isFedoraEnv } = useGetEnvironment();
const onPremFlagValue = onPremFlag(flag);
const unleashFlagValue = useUnleashFlag(flag);
const shouldUseOnPrem = process.env.IS_ON_PREMISE || isFedoraEnv;
return shouldUseOnPrem ? onPremFlagValue : unleashFlagValue;
};

View file

@ -95,6 +95,12 @@ export const ON_PREM_RELEASES = new Map([
[RHEL_10, 'Red Hat Enterprise Linux (RHEL) 10'],
]);
export const FEDORA_RELEASES = new Map([
[FEDORA_40, 'Fedora Linux 40'],
[FEDORA_41, 'Fedora Linux 41'],
[CENTOS_9, 'CentOS Stream 9'],
]);
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'];

View file

@ -2,6 +2,7 @@ import '@testing-library/jest-dom';
import { configure } from '@testing-library/react';
import { server } from './mocks/server';
import 'vitest-canvas-mock';
// scrollTo is not defined in jsdom - needed for the navigation to the wizard
@ -31,6 +32,9 @@ vi.mock('@redhat-cloud-services/frontend-components/useChrome', () => ({
isBeta: () => true,
isProd: () => true,
getEnvironment: () => 'prod',
getEnvironmentDetails: () => ({
url: ['https://console.redhat.com'],
}),
}),
default: () => ({
analytics: {