Skip to content

mantle/aws: rework AWS Windows LI image creation #4237

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 1 commit into from
Aug 11, 2025
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
125 changes: 54 additions & 71 deletions mantle/cmd/ore/aws/upload.go
Original file line number Diff line number Diff line change
Expand Up @@ -47,29 +47,27 @@ After a successful run, the final line of output will be a line of JSON describi
SilenceUsage: true,
}

uploadSourceObject string
uploadBucket string
uploadImageName string
uploadImageArchitecture string
uploadFile string
uploadDiskSizeGiB uint
uploadDiskSizeInspect bool
uploadDeleteObject bool
uploadForce bool
uploadSourceSnapshot string
uploadObjectFormat aws.EC2ImageFormat
uploadAMIName string
uploadAMIDescription string
uploadPublic bool
uploadGrantUsers []string
uploadGrantUsersSnapshot []string
uploadTags []string
uploadIMDSv2Only bool
uploadVolumeType string
uploadX86BootMode string
uploadCreateWinLIAMI bool
uploadWinLIwindowsServerAMI string
uploadWinLIInstanceType string
uploadSourceObject string
uploadBucket string
uploadImageName string
uploadImageArchitecture string
uploadFile string
uploadDiskSizeGiB uint
uploadDiskSizeInspect bool
uploadDeleteObject bool
uploadForce bool
uploadSourceSnapshot string
uploadObjectFormat aws.EC2ImageFormat
uploadAMIName string
uploadAMIDescription string
uploadPublic bool
uploadGrantUsers []string
uploadGrantUsersSnapshot []string
uploadTags []string
uploadIMDSv2Only bool
uploadVolumeType string
uploadX86BootMode string
uploadBillingProductCode string
)

func init() {
Expand All @@ -94,9 +92,7 @@ func init() {
cmdUpload.Flags().BoolVar(&uploadIMDSv2Only, "imdsv2-only", false, "enable IMDSv2-only support")
cmdUpload.Flags().StringVar(&uploadVolumeType, "volume-type", "gp3", "EBS volume type (gp3, gp2, io1, st1, sc1, standard, etc.)")
cmdUpload.Flags().StringVar(&uploadX86BootMode, "x86-boot-mode", "uefi-preferred", "Set boot mode (uefi-preferred, uefi)")
cmdUpload.Flags().BoolVar(&uploadCreateWinLIAMI, "winli", false, "Create a Windows LI AMI")
cmdUpload.Flags().StringVar(&uploadWinLIwindowsServerAMI, "windows-ami", "", "Windows Server AMI used to create a Windows LI AMI")
cmdUpload.Flags().StringVar(&uploadWinLIInstanceType, "winli-instance-type", "t2.large", "ec2 instance type used to create a Windows LI AMI")
cmdUpload.Flags().StringVar(&uploadBillingProductCode, "billing-product-code", "", "set billing product code")
}

func defaultBucketNameForRegion(region string) string {
Expand Down Expand Up @@ -140,10 +136,18 @@ func runUpload(cmd *cobra.Command, args []string) error {
fmt.Fprintf(os.Stderr, "Unrecognized args in aws upload cmd: %v\n", args)
os.Exit(2)
}
if uploadSourceObject != "" && uploadSourceSnapshot != "" {
fmt.Fprintf(os.Stderr, "At most one of --source-object and --source-snapshot may be specified.\n")
os.Exit(2)
}
if uploadDiskSizeInspect && (uploadSourceObject != "" || uploadSourceSnapshot != "") {
fmt.Fprintf(os.Stderr, "--disk-size-inspect cannot be used with --source-object or --source-snapshot.\n")
os.Exit(2)
}
if uploadFile == "" {
fmt.Fprintf(os.Stderr, "specify --file\n")
os.Exit(2)
}
if uploadImageName == "" {
fmt.Fprintf(os.Stderr, "unknown image name; specify --name\n")
os.Exit(2)
Expand All @@ -152,27 +156,31 @@ func runUpload(cmd *cobra.Command, args []string) error {
fmt.Fprintf(os.Stderr, "unknown AMI name; specify --ami-name\n")
os.Exit(2)
}
if uploadCreateWinLIAMI {
if uploadWinLIwindowsServerAMI == "" {
fmt.Fprintf(os.Stderr, "--windows-ami must be provided with --winli\n")
os.Exit(2)
}
if uploadSourceSnapshot == "" {
fmt.Fprintf(os.Stderr, "--source-snapshot must be provided with --winli\n")
os.Exit(2)

var err error
if uploadDiskSizeInspect {
imageInfo, err := util.GetImageInfo(uploadFile)
if err != nil {
fmt.Fprintf(os.Stderr, "Unable to query size of disk: %v\n", err)
os.Exit(1)
}
} else {
if uploadSourceObject != "" && uploadSourceSnapshot != "" {
fmt.Fprintf(os.Stderr, "At most one of --source-object and --source-snapshot may be specified.\n")
os.Exit(2)
plog.Debugf("Image size: %v\n", imageInfo.VirtualSize)
const GiB = 1024 * 1024 * 1024
uploadDiskSizeGiB = uint(imageInfo.VirtualSize / GiB)
// Round up if there's leftover
if imageInfo.VirtualSize%GiB > 0 {
uploadDiskSizeGiB += 1
}
if uploadFile == "" {
fmt.Fprintf(os.Stderr, "specify --file\n")
os.Exit(2)
}

if uploadSourceSnapshot != "" {
uploadDiskSizeGiB, err = API.FindSnapshotDiskSizeGiB(uploadSourceSnapshot)
if err != nil {
fmt.Fprintf(os.Stderr, "Unable to query size of disk from snapshot: %v\n", err)
os.Exit(1)
}
}

var err error
var s3URL *url.URL
if uploadSourceObject != "" {
s3URL, err = url.Parse(uploadSourceObject)
Expand All @@ -191,21 +199,6 @@ func runUpload(cmd *cobra.Command, args []string) error {
s3BucketName := s3URL.Host
s3ObjectPath := strings.TrimPrefix(s3URL.Path, "/")

if uploadDiskSizeInspect {
imageInfo, err := util.GetImageInfo(uploadFile)
if err != nil {
fmt.Fprintf(os.Stderr, "Unable to query size of disk: %v\n", err)
os.Exit(1)
}
plog.Debugf("Image size: %v\n", imageInfo.VirtualSize)
const GiB = 1024 * 1024 * 1024
uploadDiskSizeGiB = uint(imageInfo.VirtualSize / GiB)
// Round up if there's leftover
if imageInfo.VirtualSize%GiB > 0 {
uploadDiskSizeGiB += 1
}
}

if uploadForce {
err := API.RemoveImage(uploadAMIName)
if err != nil {
Expand Down Expand Up @@ -275,20 +268,10 @@ func runUpload(cmd *cobra.Command, args []string) error {
}
}

// create AMIs and grant permissions
var amiID string
if uploadWinLIwindowsServerAMI == "" {
amiID, err = API.CreateHVMImage(sourceSnapshot, uploadDiskSizeGiB, uploadAMIName, uploadAMIDescription, uploadImageArchitecture, uploadVolumeType, uploadIMDSv2Only, uploadX86BootMode)
if err != nil {
fmt.Fprintf(os.Stderr, "unable to create HVM image: %v\n", err)
os.Exit(1)
}
} else {
amiID, sourceSnapshot, err = API.CreateWinLiImage(sourceSnapshot, uploadAMIName, uploadAMIDescription, uploadImageArchitecture, uploadWinLIwindowsServerAMI, uploadWinLIInstanceType, uploadVolumeType)
if err != nil {
fmt.Fprintf(os.Stderr, "unable to create WinLI image: %v\n", err)
os.Exit(1)
}
amiID, err = API.CreateHVMImage(sourceSnapshot, uploadDiskSizeGiB, uploadAMIName, uploadAMIDescription, uploadImageArchitecture, uploadVolumeType, uploadIMDSv2Only, uploadX86BootMode, uploadBillingProductCode)
if err != nil {
fmt.Fprintf(os.Stderr, "unable to create HVM image: %v\n", err)
os.Exit(1)
}

if len(uploadGrantUsers) > 0 {
Expand Down
Loading
Loading