From 090544c333cdd4aef0ffaf138f361742d453c87b Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Anna=20V=C3=ADtov=C3=A1?= Date: Mon, 11 Aug 2025 16:06:21 +0200 Subject: [PATCH] Launch: implement guidance for AWS (HMS-9002) This commit adds launch modal for guiding users through launching an AWS instance from their image. As the launch service will be decommissioned, the flag shall be turned on, the code will later be cleaned up and the Provisioning wizard removed. --- src/Components/ImagesTable/Instance.tsx | 23 ++++- src/Components/Launch/AWSLaunchModal.tsx | 104 +++++++++++++++++++++++ 2 files changed, 123 insertions(+), 4 deletions(-) create mode 100644 src/Components/Launch/AWSLaunchModal.tsx diff --git a/src/Components/ImagesTable/Instance.tsx b/src/Components/ImagesTable/Instance.tsx index 5d11cfdf..c876a6a5 100644 --- a/src/Components/ImagesTable/Instance.tsx +++ b/src/Components/ImagesTable/Instance.tsx @@ -54,7 +54,9 @@ import { isOciUploadStatus, } from '../../store/typeGuards'; import { resolveRelPath } from '../../Utilities/path'; +import { useFlag } from '../../Utilities/useGetEnvironment'; import useProvisioningPermissions from '../../Utilities/useProvisioningPermissions'; +import { AWSLaunchModal } from '../Launch/AWSLaunchModal'; type CloudInstancePropTypes = { compose: ComposesResponseItem; @@ -97,6 +99,7 @@ const ProvisioningLink = ({ compose, composeStatus, }: ProvisioningLinkPropTypes) => { + const launchEofFlag = useFlag('image-builder.launcheof'); const [userData, setUserData] = useState(undefined); const { analytics, auth } = useChrome(); @@ -111,7 +114,7 @@ const ProvisioningLink = ({ // eslint-disable-next-line react-hooks/exhaustive-deps }, []); - const [wizardOpen, setWizardOpen] = useState(false); + const [isModalOpen, setIsModalOpen] = useState(false); const [exposedScalprumModule, error] = useLoadModule( { scope: 'provisioning', @@ -182,7 +185,7 @@ const ProvisioningLink = ({ account_id: userData?.identity.internal?.account_id || 'Not found', }); - setWizardOpen(true); + setIsModalOpen(true); }} > Launch @@ -202,6 +205,10 @@ const ProvisioningLink = ({ ); + const handleModalToggle = (_event: KeyboardEvent | React.MouseEvent) => { + setIsModalOpen(!isModalOpen); + }; + return ( <> @@ -209,7 +216,15 @@ const ProvisioningLink = ({ compose.blueprint_version !== selectedBlueprintVersion ? buttonWithTooltip : btn} - {wizardOpen && ( + {launchEofFlag && isModalOpen && provider === 'aws' && ( + + )} + {!launchEofFlag && isModalOpen && ( setWizardOpen(false)} + onClose={() => setIsModalOpen(false)} image={{ name: compose.image_name || compose.id, id: compose.id, diff --git a/src/Components/Launch/AWSLaunchModal.tsx b/src/Components/Launch/AWSLaunchModal.tsx new file mode 100644 index 00000000..c33fe0b0 --- /dev/null +++ b/src/Components/Launch/AWSLaunchModal.tsx @@ -0,0 +1,104 @@ +import React from 'react'; + +import { + Button, + List, + ListComponent, + ListItem, + Modal, + ModalBody, + ModalFooter, + ModalHeader, + ModalVariant, + OrderType, +} from '@patternfly/react-core'; +import { ExternalLinkAltIcon } from '@patternfly/react-icons'; + +import { + ComposesResponseItem, + ComposeStatus, +} from '../../store/imageBuilderApi'; +import { isAwsUploadRequestOptions } from '../../store/typeGuards'; + +type LaunchProps = { + isOpen: boolean; + handleModalToggle: (event: KeyboardEvent | React.MouseEvent) => void; + compose: ComposesResponseItem; + composeStatus: ComposeStatus | undefined; +}; + +export const AWSLaunchModal = ({ + isOpen, + handleModalToggle, + compose, + composeStatus, +}: LaunchProps) => { + const options = compose.request.image_requests[0].upload_request.options; + + if (!isAwsUploadRequestOptions(options)) { + throw TypeError( + `Error: options must be of type AwsUploadRequestOptions, not ${typeof options}.`, + ); + } + + const amiId = + composeStatus?.image_status.status === 'success' && + composeStatus.image_status.upload_status?.options && + 'ami' in composeStatus.image_status.upload_status.options + ? composeStatus.image_status.upload_status.options.ami + : ''; + + return ( + + + + + + Navigate to the{' '} + {' '} + located on your AWS console. + + + Copy the image to make it a permanent copy in your account. +
+ Shared with Account{' '} + + {options.share_with_accounts?.[0]} + +
+ AMI ID: {amiId} +
+ Launch image as an instance. + + Connect to it via SSH using the following username:{' '} + ec2-user + +
+
+ + + +
+ ); +};