wizard: allow the creation of aarch64 images
This commit extends the supported architectures to aarch64. In the image output step (the first one of the wizard) the user is now faced with a new select choices to pickup the architecture they want to build. Now the set of compatible targets to build is dynamically loaded from the backend and the UX changes what's accessible on the fly depending on what's the user has been selected. Refs HMS-1135
This commit is contained in:
parent
d91727bf38
commit
938340b360
8 changed files with 374 additions and 199 deletions
|
|
@ -112,7 +112,7 @@ const onSave = (values) => {
|
|||
image_description: values?.['image-description'],
|
||||
image_requests: [
|
||||
{
|
||||
architecture: 'x86_64',
|
||||
architecture: values['arch'],
|
||||
image_type: 'aws',
|
||||
upload_request: {
|
||||
type: 'aws',
|
||||
|
|
@ -151,7 +151,7 @@ const onSave = (values) => {
|
|||
image_description: values?.['image-description'],
|
||||
image_requests: [
|
||||
{
|
||||
architecture: 'x86_64',
|
||||
architecture: values['arch'],
|
||||
image_type: 'gcp',
|
||||
upload_request: {
|
||||
type: 'gcp',
|
||||
|
|
@ -182,7 +182,7 @@ const onSave = (values) => {
|
|||
image_description: values?.['image-description'],
|
||||
image_requests: [
|
||||
{
|
||||
architecture: 'x86_64',
|
||||
architecture: values['arch'],
|
||||
image_type: 'azure',
|
||||
upload_request: {
|
||||
type: 'azure',
|
||||
|
|
@ -205,7 +205,7 @@ const onSave = (values) => {
|
|||
image_description: values?.['image-description'],
|
||||
image_requests: [
|
||||
{
|
||||
architecture: 'x86_64',
|
||||
architecture: values['arch'],
|
||||
image_type: 'vsphere',
|
||||
upload_request: {
|
||||
type: 'aws.s3',
|
||||
|
|
@ -225,7 +225,7 @@ const onSave = (values) => {
|
|||
image_description: values?.['image-description'],
|
||||
image_requests: [
|
||||
{
|
||||
architecture: 'x86_64',
|
||||
architecture: values['arch'],
|
||||
image_type: 'vsphere-ova',
|
||||
upload_request: {
|
||||
type: 'aws.s3',
|
||||
|
|
@ -245,7 +245,7 @@ const onSave = (values) => {
|
|||
image_description: values?.['image-description'],
|
||||
image_requests: [
|
||||
{
|
||||
architecture: 'x86_64',
|
||||
architecture: values['arch'],
|
||||
image_type: 'guest-image',
|
||||
upload_request: {
|
||||
type: 'aws.s3',
|
||||
|
|
@ -265,7 +265,7 @@ const onSave = (values) => {
|
|||
image_description: values?.['image-description'],
|
||||
image_requests: [
|
||||
{
|
||||
architecture: 'x86_64',
|
||||
architecture: values['arch'],
|
||||
image_type: 'image-installer',
|
||||
upload_request: {
|
||||
type: 'aws.s3',
|
||||
|
|
@ -285,7 +285,7 @@ const onSave = (values) => {
|
|||
image_description: values?.['image-description'],
|
||||
image_requests: [
|
||||
{
|
||||
architecture: 'x86_64',
|
||||
architecture: values['arch'],
|
||||
image_type: 'wsl',
|
||||
upload_request: {
|
||||
type: 'aws.s3',
|
||||
|
|
@ -330,6 +330,7 @@ const requestToState = (composeRequest, distroInfo, isProd, enableOscap) => {
|
|||
formState['image-description'] = composeRequest.image_description;
|
||||
|
||||
formState.release = composeRequest?.distribution;
|
||||
formState.arch = imageRequest.architecture;
|
||||
// set defaults for target environment first
|
||||
formState['target-environment'] = {
|
||||
aws: false,
|
||||
|
|
|
|||
|
|
@ -31,6 +31,7 @@
|
|||
|
||||
.tile {
|
||||
flex: 1 0 0px;
|
||||
max-width: 250px;
|
||||
}
|
||||
|
||||
.pf-c-tile:focus {
|
||||
|
|
|
|||
|
|
@ -8,6 +8,7 @@ import { Spinner } from '@patternfly/react-core';
|
|||
import PropTypes from 'prop-types';
|
||||
|
||||
import ActivationKeys from './formComponents/ActivationKeys';
|
||||
import ArchSelect from './formComponents/ArchSelect';
|
||||
import { AWSSourcesSelect } from './formComponents/AWSSourcesSelect';
|
||||
import AzureAuthButton from './formComponents/AzureAuthButton';
|
||||
import AzureResourceGroups from './formComponents/AzureResourceGroups';
|
||||
|
|
@ -74,6 +75,7 @@ const ImageCreator = ({
|
|||
'azure-resource-groups': AzureResourceGroups,
|
||||
'gallery-layout': GalleryLayout,
|
||||
'oscap-profile-selector': Oscap,
|
||||
'image-output-arch-select': ArchSelect,
|
||||
registration: Registration,
|
||||
...customComponentMapper,
|
||||
}}
|
||||
|
|
|
|||
|
|
@ -0,0 +1,64 @@
|
|||
import React, { useState } from 'react';
|
||||
|
||||
import { FormSpy } from '@data-driven-forms/react-form-renderer';
|
||||
import useFieldApi from '@data-driven-forms/react-form-renderer/use-field-api';
|
||||
import useFormApi from '@data-driven-forms/react-form-renderer/use-form-api';
|
||||
import { FormGroup } from '@patternfly/react-core';
|
||||
import {
|
||||
Select,
|
||||
SelectOption,
|
||||
SelectVariant,
|
||||
} from '@patternfly/react-core/deprecated';
|
||||
import PropTypes from 'prop-types';
|
||||
|
||||
import { ARCHS } from '../../../constants';
|
||||
|
||||
const ArchSelect = ({ label, isRequired, ...props }) => {
|
||||
const { change, getState } = useFormApi();
|
||||
const { input } = useFieldApi(props);
|
||||
const [isOpen, setIsOpen] = useState(false);
|
||||
|
||||
const setArch = (_, selection) => {
|
||||
change(input.name, selection);
|
||||
setIsOpen(false);
|
||||
};
|
||||
|
||||
const setSelectOptions = () => {
|
||||
var options = [];
|
||||
ARCHS.forEach((arch) => {
|
||||
options.push(
|
||||
<SelectOption key={arch} value={arch}>
|
||||
{arch}
|
||||
</SelectOption>
|
||||
);
|
||||
});
|
||||
|
||||
return options;
|
||||
};
|
||||
|
||||
return (
|
||||
<FormSpy>
|
||||
{() => (
|
||||
<FormGroup isRequired={isRequired} label={label}>
|
||||
<Select
|
||||
ouiaId="arch_select"
|
||||
variant={SelectVariant.single}
|
||||
onToggle={() => setIsOpen(!isOpen)}
|
||||
onSelect={setArch}
|
||||
selections={getState()?.values?.[input.name]}
|
||||
isOpen={isOpen}
|
||||
>
|
||||
{setSelectOptions()}
|
||||
</Select>
|
||||
</FormGroup>
|
||||
)}
|
||||
</FormSpy>
|
||||
);
|
||||
};
|
||||
|
||||
ArchSelect.propTypes = {
|
||||
label: PropTypes.node,
|
||||
isRequired: PropTypes.bool,
|
||||
};
|
||||
|
||||
export default ArchSelect;
|
||||
|
|
@ -25,7 +25,7 @@ import {
|
|||
RepositoriesTable,
|
||||
} from './ReviewStepTables';
|
||||
|
||||
import { RELEASES, UNIT_GIB } from '../../../constants';
|
||||
import { ARCHS, RELEASES, UNIT_GIB } from '../../../constants';
|
||||
import { extractProvisioningList } from '../../../store/helpers';
|
||||
import { useGetSourceListQuery } from '../../../store/provisioningApi';
|
||||
import { useShowActivationKeyQuery } from '../../../store/rhsmApi';
|
||||
|
|
@ -57,7 +57,9 @@ export const ImageOutputList = () => {
|
|||
<TextListItem component={TextListItemVariants.dt}>
|
||||
Architecture
|
||||
</TextListItem>
|
||||
<TextListItem component={TextListItemVariants.dd}>x86_64</TextListItem>
|
||||
<TextListItem component={TextListItemVariants.dd}>
|
||||
{getState()?.values?.arch}
|
||||
</TextListItem>
|
||||
</TextList>
|
||||
<br />
|
||||
</TextContent>
|
||||
|
|
|
|||
|
|
@ -3,10 +3,13 @@ import React, { useEffect, useState } from 'react';
|
|||
import useFieldApi from '@data-driven-forms/react-form-renderer/use-field-api';
|
||||
import useFormApi from '@data-driven-forms/react-form-renderer/use-form-api';
|
||||
import {
|
||||
Alert,
|
||||
Bullseye,
|
||||
Checkbox,
|
||||
FormGroup,
|
||||
Popover,
|
||||
Radio,
|
||||
Spinner,
|
||||
Text,
|
||||
TextContent,
|
||||
TextVariants,
|
||||
|
|
@ -14,11 +17,34 @@ import {
|
|||
} from '@patternfly/react-core';
|
||||
import { HelpIcon } from '@patternfly/react-icons';
|
||||
import PropTypes from 'prop-types';
|
||||
import { useField } from 'react-final-form';
|
||||
|
||||
import { RHEL_8, CENTOS_8 } from '../../../constants.js';
|
||||
import { useGetArchitecturesQuery } from '../../../store/imageBuilderApi';
|
||||
import { provisioningApi } from '../../../store/provisioningApi';
|
||||
import { useGetEnvironment } from '../../../Utilities/useGetEnvironment';
|
||||
|
||||
const useGetAllowedTargets = ({ architecture, release }) => {
|
||||
const { data, isFetching, isSuccess, isError } = useGetArchitecturesQuery({
|
||||
distribution: release,
|
||||
});
|
||||
|
||||
let image_types = [];
|
||||
if (isSuccess && data) {
|
||||
data.forEach((elem) => {
|
||||
if (elem.arch === architecture) {
|
||||
image_types = elem.image_types;
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
return {
|
||||
data: image_types,
|
||||
isFetching: isFetching,
|
||||
isSuccess: isSuccess,
|
||||
isError: isError,
|
||||
};
|
||||
};
|
||||
|
||||
const TargetEnvironment = ({ label, isRequired, ...props }) => {
|
||||
const { getState, change } = useFormApi();
|
||||
const { input } = useFieldApi({ label, isRequired, ...props });
|
||||
|
|
@ -52,17 +78,67 @@ const TargetEnvironment = ({ label, isRequired, ...props }) => {
|
|||
return newEnv;
|
||||
});
|
||||
|
||||
// hack, wsl isn't supported in el9, causes a rerender
|
||||
if (environment.wsl && ![RHEL_8, CENTOS_8].includes(release)) {
|
||||
handleSetEnvironment('wsl', false);
|
||||
}
|
||||
|
||||
const handleKeyDown = (e, env, checked) => {
|
||||
if (e.key === ' ') {
|
||||
handleSetEnvironment(env, checked);
|
||||
}
|
||||
};
|
||||
|
||||
// Load all the allowed targets from the backend
|
||||
const architecture = useField('arch').input.value;
|
||||
|
||||
const {
|
||||
data: allowedTargets,
|
||||
isFetching,
|
||||
isSuccess,
|
||||
isError,
|
||||
} = useGetAllowedTargets({
|
||||
architecture: architecture,
|
||||
release: release,
|
||||
});
|
||||
|
||||
if (isFetching) {
|
||||
return (
|
||||
<Bullseye>
|
||||
<Spinner size="lg" />
|
||||
</Bullseye>
|
||||
);
|
||||
}
|
||||
|
||||
if (isError || !isSuccess) {
|
||||
return (
|
||||
<Alert
|
||||
variant={'danger'}
|
||||
isPlain
|
||||
isInline
|
||||
title={'Allowed targets unavailable'}
|
||||
>
|
||||
Allowed targets cannot be reached, try again later.
|
||||
</Alert>
|
||||
);
|
||||
}
|
||||
|
||||
// If the user already made a choice for some targets but then changes their
|
||||
// architecture or distribution, only keep the target choices that are still
|
||||
// compatible.
|
||||
const allTargets = [
|
||||
'aws',
|
||||
'gcp',
|
||||
'azure',
|
||||
'vsphere',
|
||||
'vsphere-ova',
|
||||
'guest-image',
|
||||
'image-installer',
|
||||
'wsl',
|
||||
];
|
||||
allTargets.forEach((target) => {
|
||||
if (environment[target] && !allowedTargets.includes(target)) {
|
||||
handleSetEnvironment(target, false);
|
||||
}
|
||||
});
|
||||
|
||||
// each item the user can select is depending on what's compatible with the
|
||||
// architecture and the distribution they previously selected
|
||||
return (
|
||||
<FormGroup
|
||||
isRequired={isRequired}
|
||||
|
|
@ -74,195 +150,208 @@ const TargetEnvironment = ({ label, isRequired, ...props }) => {
|
|||
data-testid="target-public"
|
||||
>
|
||||
<div className="tiles">
|
||||
<Tile
|
||||
className="tile pf-u-mr-sm"
|
||||
data-testid="upload-aws"
|
||||
title="Amazon Web Services"
|
||||
icon={
|
||||
<img
|
||||
className="provider-icon"
|
||||
src={'/apps/frontend-assets/partners-icons/aws.svg'}
|
||||
alt="Amazon Web Services logo"
|
||||
/>
|
||||
}
|
||||
onClick={() => handleSetEnvironment('aws', !environment.aws)}
|
||||
onKeyDown={(e) => handleKeyDown(e, 'aws', !environment.aws)}
|
||||
onMouseEnter={() => prefetchSources({ provider: 'aws' })}
|
||||
isSelected={environment.aws}
|
||||
isStacked
|
||||
isDisplayLarge
|
||||
/>
|
||||
<Tile
|
||||
className="tile pf-u-mr-sm"
|
||||
data-testid="upload-google"
|
||||
title="Google Cloud Platform"
|
||||
icon={
|
||||
<img
|
||||
className="provider-icon"
|
||||
src={
|
||||
'/apps/frontend-assets/partners-icons/google-cloud-short.svg'
|
||||
}
|
||||
alt="Google Cloud Platform logo"
|
||||
/>
|
||||
}
|
||||
onClick={() => handleSetEnvironment('gcp', !environment.gcp)}
|
||||
isSelected={environment.gcp}
|
||||
onKeyDown={(e) => handleKeyDown(e, 'gcp', !environment.gcp)}
|
||||
onMouseEnter={() => prefetchSources({ provider: 'gcp' })}
|
||||
isStacked
|
||||
isDisplayLarge
|
||||
/>
|
||||
<Tile
|
||||
className="tile pf-u-mr-sm"
|
||||
data-testid="upload-azure"
|
||||
title="Microsoft Azure"
|
||||
icon={
|
||||
<img
|
||||
className="provider-icon"
|
||||
src={
|
||||
'/apps/frontend-assets/partners-icons/microsoft-azure-short.svg'
|
||||
}
|
||||
alt="Microsoft Azure logo"
|
||||
/>
|
||||
}
|
||||
onClick={() => handleSetEnvironment('azure', !environment.azure)}
|
||||
onKeyDown={(e) => handleKeyDown(e, 'azure', !environment.azure)}
|
||||
onMouseEnter={() => prefetchSources({ provider: 'azure' })}
|
||||
isSelected={environment.azure}
|
||||
isStacked
|
||||
isDisplayLarge
|
||||
/>
|
||||
{allowedTargets.includes('aws') && (
|
||||
<Tile
|
||||
className="tile pf-u-mr-sm"
|
||||
data-testid="upload-aws"
|
||||
title="Amazon Web Services"
|
||||
icon={
|
||||
<img
|
||||
className="provider-icon"
|
||||
src={'/apps/frontend-assets/partners-icons/aws.svg'}
|
||||
alt="Amazon Web Services logo"
|
||||
/>
|
||||
}
|
||||
onClick={() => handleSetEnvironment('aws', !environment.aws)}
|
||||
onKeyDown={(e) => handleKeyDown(e, 'aws', !environment.aws)}
|
||||
onMouseEnter={() => prefetchSources({ provider: 'aws' })}
|
||||
isSelected={environment.aws}
|
||||
isStacked
|
||||
isDisplayLarge
|
||||
/>
|
||||
)}
|
||||
{allowedTargets.includes('gcp') && (
|
||||
<Tile
|
||||
className="tile pf-u-mr-sm"
|
||||
data-testid="upload-google"
|
||||
title="Google Cloud Platform"
|
||||
icon={
|
||||
<img
|
||||
className="provider-icon"
|
||||
src={
|
||||
'/apps/frontend-assets/partners-icons/google-cloud-short.svg'
|
||||
}
|
||||
alt="Google Cloud Platform logo"
|
||||
/>
|
||||
}
|
||||
onClick={() => handleSetEnvironment('gcp', !environment.gcp)}
|
||||
isSelected={environment.gcp}
|
||||
onKeyDown={(e) => handleKeyDown(e, 'gcp', !environment.gcp)}
|
||||
onMouseEnter={() => prefetchSources({ provider: 'gcp' })}
|
||||
isStacked
|
||||
isDisplayLarge
|
||||
/>
|
||||
)}
|
||||
{allowedTargets.includes('azure') && (
|
||||
<Tile
|
||||
className="tile pf-u-mr-sm"
|
||||
data-testid="upload-azure"
|
||||
title="Microsoft Azure"
|
||||
icon={
|
||||
<img
|
||||
className="provider-icon"
|
||||
src={
|
||||
'/apps/frontend-assets/partners-icons/microsoft-azure-short.svg'
|
||||
}
|
||||
alt="Microsoft Azure logo"
|
||||
/>
|
||||
}
|
||||
onClick={() => handleSetEnvironment('azure', !environment.azure)}
|
||||
onKeyDown={(e) => handleKeyDown(e, 'azure', !environment.azure)}
|
||||
onMouseEnter={() => prefetchSources({ provider: 'azure' })}
|
||||
isSelected={environment.azure}
|
||||
isStacked
|
||||
isDisplayLarge
|
||||
/>
|
||||
)}
|
||||
</div>
|
||||
</FormGroup>
|
||||
<FormGroup
|
||||
label={<Text component={TextVariants.small}>Private cloud</Text>}
|
||||
className="pf-u-mt-sm"
|
||||
data-testid="target-private"
|
||||
>
|
||||
<Checkbox
|
||||
label="VMWare vSphere"
|
||||
isChecked={environment.vsphere || environment['vsphere-ova']}
|
||||
onChange={(_event, checked) => {
|
||||
handleSetEnvironment('vsphere-ova', checked);
|
||||
handleSetEnvironment('vsphere', false);
|
||||
}}
|
||||
aria-label="VMWare checkbox"
|
||||
id="checkbox-vmware"
|
||||
name="VMWare"
|
||||
data-testid="checkbox-vmware"
|
||||
/>
|
||||
</FormGroup>
|
||||
<FormGroup
|
||||
className="pf-u-mt-sm pf-u-mb-sm pf-u-ml-xl"
|
||||
data-testid="target-private-vsphere-radio"
|
||||
>
|
||||
<Radio
|
||||
name="vsphere-radio"
|
||||
aria-label="VMWare vSphere radio button OVA"
|
||||
id="vsphere-radio-ova"
|
||||
label={
|
||||
<>
|
||||
Open virtualization format (.ova)
|
||||
<Popover
|
||||
maxWidth="30rem"
|
||||
position="right"
|
||||
bodyContent={
|
||||
<TextContent>
|
||||
<Text>
|
||||
An OVA file is a virtual appliance used by virtualization
|
||||
platforms such as VMWare vSphere. It is a package that
|
||||
contains files used to describe a virtual machine, which
|
||||
includes a VMDK image, OVF descriptor file and a manifest
|
||||
file.
|
||||
</Text>
|
||||
</TextContent>
|
||||
}
|
||||
>
|
||||
<HelpIcon className="pf-u-ml-sm" />
|
||||
</Popover>
|
||||
</>
|
||||
}
|
||||
onChange={(_event, checked) => {
|
||||
handleSetEnvironment('vsphere-ova', checked);
|
||||
handleSetEnvironment('vsphere', !checked);
|
||||
}}
|
||||
isChecked={environment['vsphere-ova']}
|
||||
isDisabled={!(environment.vsphere || environment['vsphere-ova'])}
|
||||
/>
|
||||
<Radio
|
||||
{allowedTargets.includes('vsphere') && (
|
||||
<FormGroup
|
||||
label={<Text component={TextVariants.small}>Private cloud</Text>}
|
||||
className="pf-u-mt-sm"
|
||||
name="vsphere-radio"
|
||||
aria-label="VMWare vSphere radio button VMDK"
|
||||
id="vsphere-radio-vmdk"
|
||||
label={
|
||||
<>
|
||||
Virtual disk (.vmdk)
|
||||
<Popover
|
||||
maxWidth="30rem"
|
||||
position="right"
|
||||
bodyContent={
|
||||
<TextContent>
|
||||
<Text>
|
||||
A VMDK file is a virtual disk that stores the contents of
|
||||
a virtual machine. This disk has to be imported into
|
||||
vSphere using govc import.vmdk, use the OVA version when
|
||||
using the vSphere UI.
|
||||
</Text>
|
||||
</TextContent>
|
||||
}
|
||||
>
|
||||
<HelpIcon className="pf-u-ml-sm" />
|
||||
</Popover>
|
||||
</>
|
||||
}
|
||||
onChange={(_event, checked) => {
|
||||
handleSetEnvironment('vsphere-ova', !checked);
|
||||
handleSetEnvironment('vsphere', checked);
|
||||
}}
|
||||
isChecked={environment.vsphere}
|
||||
isDisabled={!(environment.vsphere || environment['vsphere-ova'])}
|
||||
/>
|
||||
</FormGroup>
|
||||
data-testid="target-private"
|
||||
>
|
||||
<Checkbox
|
||||
label="VMWare vSphere"
|
||||
isChecked={environment.vsphere || environment['vsphere-ova']}
|
||||
onChange={(_event, checked) => {
|
||||
handleSetEnvironment('vsphere-ova', checked);
|
||||
handleSetEnvironment('vsphere', false);
|
||||
}}
|
||||
aria-label="VMWare checkbox"
|
||||
id="checkbox-vmware"
|
||||
name="VMWare"
|
||||
data-testid="checkbox-vmware"
|
||||
/>
|
||||
</FormGroup>
|
||||
)}
|
||||
{allowedTargets.includes('vsphere') && (
|
||||
<FormGroup
|
||||
className="pf-u-mt-sm pf-u-mb-sm pf-u-ml-xl"
|
||||
data-testid="target-private-vsphere-radio"
|
||||
>
|
||||
{allowedTargets.includes('vsphere-ova') && (
|
||||
<Radio
|
||||
name="vsphere-radio"
|
||||
aria-label="VMWare vSphere radio button OVA"
|
||||
id="vsphere-radio-ova"
|
||||
label={
|
||||
<>
|
||||
Open virtualization format (.ova)
|
||||
<Popover
|
||||
maxWidth="30rem"
|
||||
position="right"
|
||||
bodyContent={
|
||||
<TextContent>
|
||||
<Text>
|
||||
An OVA file is a virtual appliance used by
|
||||
virtualization platforms such as VMWare vSphere. It is
|
||||
a package that contains files used to describe a
|
||||
virtual machine, which includes a VMDK image, OVF
|
||||
descriptor file and a manifest file.
|
||||
</Text>
|
||||
</TextContent>
|
||||
}
|
||||
>
|
||||
<HelpIcon className="pf-u-ml-sm" />
|
||||
</Popover>
|
||||
</>
|
||||
}
|
||||
onChange={(_event, checked) => {
|
||||
handleSetEnvironment('vsphere-ova', checked);
|
||||
handleSetEnvironment('vsphere', !checked);
|
||||
}}
|
||||
isChecked={environment['vsphere-ova']}
|
||||
isDisabled={!(environment.vsphere || environment['vsphere-ova'])}
|
||||
/>
|
||||
)}
|
||||
<Radio
|
||||
className="pf-u-mt-sm"
|
||||
name="vsphere-radio"
|
||||
aria-label="VMWare vSphere radio button VMDK"
|
||||
id="vsphere-radio-vmdk"
|
||||
label={
|
||||
<>
|
||||
Virtual disk (.vmdk)
|
||||
<Popover
|
||||
maxWidth="30rem"
|
||||
position="right"
|
||||
bodyContent={
|
||||
<TextContent>
|
||||
<Text>
|
||||
A VMDK file is a virtual disk that stores the contents
|
||||
of a virtual machine. This disk has to be imported into
|
||||
vSphere using govc import.vmdk, use the OVA version when
|
||||
using the vSphere UI.
|
||||
</Text>
|
||||
</TextContent>
|
||||
}
|
||||
>
|
||||
<HelpIcon className="pf-u-ml-sm" />
|
||||
</Popover>
|
||||
</>
|
||||
}
|
||||
onChange={(_event, checked) => {
|
||||
handleSetEnvironment('vsphere-ova', !checked);
|
||||
handleSetEnvironment('vsphere', checked);
|
||||
}}
|
||||
isChecked={environment.vsphere}
|
||||
isDisabled={!(environment.vsphere || environment['vsphere-ova'])}
|
||||
/>
|
||||
</FormGroup>
|
||||
)}
|
||||
<FormGroup
|
||||
label={<Text component={TextVariants.small}>Other</Text>}
|
||||
data-testid="target-other"
|
||||
>
|
||||
<Checkbox
|
||||
label="Virtualization - Guest image (.qcow2)"
|
||||
isChecked={environment['guest-image']}
|
||||
onChange={(_event, checked) =>
|
||||
handleSetEnvironment('guest-image', checked)
|
||||
}
|
||||
aria-label="Virtualization guest image checkbox"
|
||||
id="checkbox-guest-image"
|
||||
name="Virtualization guest image"
|
||||
data-testid="checkbox-guest-image"
|
||||
/>
|
||||
<Checkbox
|
||||
label="Bare metal - Installer (.iso)"
|
||||
isChecked={environment['image-installer']}
|
||||
onChange={(_event, checked) =>
|
||||
handleSetEnvironment('image-installer', checked)
|
||||
}
|
||||
aria-label="Bare metal installer checkbox"
|
||||
id="checkbox-image-installer"
|
||||
name="Bare metal installer"
|
||||
data-testid="checkbox-image-installer"
|
||||
/>
|
||||
{[RHEL_8, CENTOS_8].includes(getState()?.values?.release) &&
|
||||
isBeta() && (
|
||||
<Checkbox
|
||||
label="WSL - Windows Subsystem for Linux (.tar.gz)"
|
||||
isChecked={environment['wsl']}
|
||||
onChange={(_event, checked) =>
|
||||
handleSetEnvironment('wsl', checked)
|
||||
}
|
||||
aria-label="windows subsystem for linux checkbox"
|
||||
id="checkbox-wsl"
|
||||
name="WSL"
|
||||
data-testid="checkbox-wsl"
|
||||
/>
|
||||
)}
|
||||
{allowedTargets.includes('guest-image') && (
|
||||
<Checkbox
|
||||
label="Virtualization - Guest image (.qcow2)"
|
||||
isChecked={environment['guest-image']}
|
||||
onChange={(_event, checked) =>
|
||||
handleSetEnvironment('guest-image', checked)
|
||||
}
|
||||
aria-label="Virtualization guest image checkbox"
|
||||
id="checkbox-guest-image"
|
||||
name="Virtualization guest image"
|
||||
data-testid="checkbox-guest-image"
|
||||
/>
|
||||
)}
|
||||
{allowedTargets.includes('image-installer') && (
|
||||
<Checkbox
|
||||
label="Bare metal - Installer (.iso)"
|
||||
isChecked={environment['image-installer']}
|
||||
onChange={(_event, checked) =>
|
||||
handleSetEnvironment('image-installer', checked)
|
||||
}
|
||||
aria-label="Bare metal installer checkbox"
|
||||
id="checkbox-image-installer"
|
||||
name="Bare metal installer"
|
||||
data-testid="checkbox-image-installer"
|
||||
/>
|
||||
)}
|
||||
{allowedTargets.includes('wsl') && isBeta && (
|
||||
<Checkbox
|
||||
label="WSL - Windows Subsystem for Linux (.tar.gz)"
|
||||
isChecked={environment['wsl']}
|
||||
onChange={(_event, checked) => handleSetEnvironment('wsl', checked)}
|
||||
aria-label="windows subsystem for linux checkbox"
|
||||
id="checkbox-wsl"
|
||||
name="WSL"
|
||||
data-testid="checkbox-wsl"
|
||||
/>
|
||||
)}
|
||||
</FormGroup>
|
||||
</FormGroup>
|
||||
);
|
||||
|
|
|
|||
|
|
@ -7,7 +7,7 @@ import { Text } from '@patternfly/react-core';
|
|||
import nextStepMapper from './imageOutputStepMapper';
|
||||
import StepTemplate from './stepTemplate';
|
||||
|
||||
import { RHEL_9 } from '../../../constants.js';
|
||||
import { RHEL_9, X86_64 } from '../../../constants.js';
|
||||
import DocumentationButton from '../../sharedComponents/DocumentationButton';
|
||||
import CustomButtons from '../formComponents/CustomButtons';
|
||||
|
||||
|
|
@ -43,6 +43,18 @@ const imageOutputStep = {
|
|||
},
|
||||
],
|
||||
},
|
||||
{
|
||||
component: 'image-output-arch-select',
|
||||
label: 'Architecture',
|
||||
name: 'arch',
|
||||
initialValue: X86_64,
|
||||
isRequired: true,
|
||||
validate: [
|
||||
{
|
||||
type: validatorTypes.REQUIRED,
|
||||
},
|
||||
],
|
||||
},
|
||||
{
|
||||
component: 'centos-acknowledgement',
|
||||
name: 'centos-acknowledgement',
|
||||
|
|
|
|||
|
|
@ -7,6 +7,8 @@ export const RHEL_8 = 'rhel-88';
|
|||
export const RHEL_9 = 'rhel-92';
|
||||
export const CENTOS_8 = 'centos-8';
|
||||
export const CENTOS_9 = 'centos-9';
|
||||
export const X86_64 = 'x86_64';
|
||||
export const AARCH64 = 'aarch64';
|
||||
|
||||
export const UNIT_KIB = 1024 ** 1;
|
||||
export const UNIT_MIB = 1024 ** 2;
|
||||
|
|
@ -19,6 +21,8 @@ export const RELEASES = new Map([
|
|||
[CENTOS_8, 'CentOS Stream 8'],
|
||||
]);
|
||||
|
||||
export const ARCHS = [X86_64, AARCH64];
|
||||
|
||||
export const DEFAULT_AWS_REGION = 'us-east-1';
|
||||
|
||||
// https://docs.aws.amazon.com/AWSEC2/latest/UserGuide/using-regions-availability-zones.html
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue