Skip to content

Commit 9394939

Browse files
committed
mantle/aws: rework AWS Windows LI image creation
partially revert and rework d3688be, 0791319, a1f8d97. and 1834b07. Rework the aws-winli creation logic to use `aws ec2 register-image --billing-product` to create the AMI with the Windows License Included billing code metadata. This simplifies the creation logic and removes the need for swapping the root volume of an instance. Instead, add an ore argument `--billing-product-code` to set the billing product code during image creation. Setting billing product codes is limited to approved AWS accounts, so this will only be used to create the RHCOS aws-winli image. Also add `FindSnapshotDiskSizeGiB` to retrieve the volume size for a given snapshot ID, to be used when a snapshot is provided for AMI creation.
1 parent fcab09a commit 9394939

File tree

5 files changed

+88
-538
lines changed

5 files changed

+88
-538
lines changed

mantle/cmd/ore/aws/upload.go

Lines changed: 54 additions & 71 deletions
Original file line numberDiff line numberDiff line change
@@ -47,29 +47,27 @@ After a successful run, the final line of output will be a line of JSON describi
4747
SilenceUsage: true,
4848
}
4949

50-
uploadSourceObject string
51-
uploadBucket string
52-
uploadImageName string
53-
uploadImageArchitecture string
54-
uploadFile string
55-
uploadDiskSizeGiB uint
56-
uploadDiskSizeInspect bool
57-
uploadDeleteObject bool
58-
uploadForce bool
59-
uploadSourceSnapshot string
60-
uploadObjectFormat aws.EC2ImageFormat
61-
uploadAMIName string
62-
uploadAMIDescription string
63-
uploadPublic bool
64-
uploadGrantUsers []string
65-
uploadGrantUsersSnapshot []string
66-
uploadTags []string
67-
uploadIMDSv2Only bool
68-
uploadVolumeType string
69-
uploadX86BootMode string
70-
uploadCreateWinLIAMI bool
71-
uploadWinLIwindowsServerAMI string
72-
uploadWinLIInstanceType string
50+
uploadSourceObject string
51+
uploadBucket string
52+
uploadImageName string
53+
uploadImageArchitecture string
54+
uploadFile string
55+
uploadDiskSizeGiB uint
56+
uploadDiskSizeInspect bool
57+
uploadDeleteObject bool
58+
uploadForce bool
59+
uploadSourceSnapshot string
60+
uploadObjectFormat aws.EC2ImageFormat
61+
uploadAMIName string
62+
uploadAMIDescription string
63+
uploadPublic bool
64+
uploadGrantUsers []string
65+
uploadGrantUsersSnapshot []string
66+
uploadTags []string
67+
uploadIMDSv2Only bool
68+
uploadVolumeType string
69+
uploadX86BootMode string
70+
uploadBillingProductCode string
7371
)
7472

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

10298
func defaultBucketNameForRegion(region string) string {
@@ -140,10 +136,18 @@ func runUpload(cmd *cobra.Command, args []string) error {
140136
fmt.Fprintf(os.Stderr, "Unrecognized args in aws upload cmd: %v\n", args)
141137
os.Exit(2)
142138
}
139+
if uploadSourceObject != "" && uploadSourceSnapshot != "" {
140+
fmt.Fprintf(os.Stderr, "At most one of --source-object and --source-snapshot may be specified.\n")
141+
os.Exit(2)
142+
}
143143
if uploadDiskSizeInspect && (uploadSourceObject != "" || uploadSourceSnapshot != "") {
144144
fmt.Fprintf(os.Stderr, "--disk-size-inspect cannot be used with --source-object or --source-snapshot.\n")
145145
os.Exit(2)
146146
}
147+
if uploadFile == "" {
148+
fmt.Fprintf(os.Stderr, "specify --file\n")
149+
os.Exit(2)
150+
}
147151
if uploadImageName == "" {
148152
fmt.Fprintf(os.Stderr, "unknown image name; specify --name\n")
149153
os.Exit(2)
@@ -152,27 +156,31 @@ func runUpload(cmd *cobra.Command, args []string) error {
152156
fmt.Fprintf(os.Stderr, "unknown AMI name; specify --ami-name\n")
153157
os.Exit(2)
154158
}
155-
if uploadCreateWinLIAMI {
156-
if uploadWinLIwindowsServerAMI == "" {
157-
fmt.Fprintf(os.Stderr, "--windows-ami must be provided with --winli\n")
158-
os.Exit(2)
159-
}
160-
if uploadSourceSnapshot == "" {
161-
fmt.Fprintf(os.Stderr, "--source-snapshot must be provided with --winli\n")
162-
os.Exit(2)
159+
160+
var err error
161+
if uploadDiskSizeInspect {
162+
imageInfo, err := util.GetImageInfo(uploadFile)
163+
if err != nil {
164+
fmt.Fprintf(os.Stderr, "Unable to query size of disk: %v\n", err)
165+
os.Exit(1)
163166
}
164-
} else {
165-
if uploadSourceObject != "" && uploadSourceSnapshot != "" {
166-
fmt.Fprintf(os.Stderr, "At most one of --source-object and --source-snapshot may be specified.\n")
167-
os.Exit(2)
167+
plog.Debugf("Image size: %v\n", imageInfo.VirtualSize)
168+
const GiB = 1024 * 1024 * 1024
169+
uploadDiskSizeGiB = uint(imageInfo.VirtualSize / GiB)
170+
// Round up if there's leftover
171+
if imageInfo.VirtualSize%GiB > 0 {
172+
uploadDiskSizeGiB += 1
168173
}
169-
if uploadFile == "" {
170-
fmt.Fprintf(os.Stderr, "specify --file\n")
171-
os.Exit(2)
174+
}
175+
176+
if uploadSourceSnapshot != "" {
177+
uploadDiskSizeGiB, err = API.FindSnapshotDiskSizeGiB(uploadSourceSnapshot)
178+
if err != nil {
179+
fmt.Fprintf(os.Stderr, "Unable to query size of disk from snapshot: %v\n", err)
180+
os.Exit(1)
172181
}
173182
}
174183

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

194-
if uploadDiskSizeInspect {
195-
imageInfo, err := util.GetImageInfo(uploadFile)
196-
if err != nil {
197-
fmt.Fprintf(os.Stderr, "Unable to query size of disk: %v\n", err)
198-
os.Exit(1)
199-
}
200-
plog.Debugf("Image size: %v\n", imageInfo.VirtualSize)
201-
const GiB = 1024 * 1024 * 1024
202-
uploadDiskSizeGiB = uint(imageInfo.VirtualSize / GiB)
203-
// Round up if there's leftover
204-
if imageInfo.VirtualSize%GiB > 0 {
205-
uploadDiskSizeGiB += 1
206-
}
207-
}
208-
209202
if uploadForce {
210203
err := API.RemoveImage(uploadAMIName)
211204
if err != nil {
@@ -275,20 +268,10 @@ func runUpload(cmd *cobra.Command, args []string) error {
275268
}
276269
}
277270

278-
// create AMIs and grant permissions
279-
var amiID string
280-
if uploadWinLIwindowsServerAMI == "" {
281-
amiID, err = API.CreateHVMImage(sourceSnapshot, uploadDiskSizeGiB, uploadAMIName, uploadAMIDescription, uploadImageArchitecture, uploadVolumeType, uploadIMDSv2Only, uploadX86BootMode)
282-
if err != nil {
283-
fmt.Fprintf(os.Stderr, "unable to create HVM image: %v\n", err)
284-
os.Exit(1)
285-
}
286-
} else {
287-
amiID, sourceSnapshot, err = API.CreateWinLiImage(sourceSnapshot, uploadAMIName, uploadAMIDescription, uploadImageArchitecture, uploadWinLIwindowsServerAMI, uploadWinLIInstanceType, uploadVolumeType)
288-
if err != nil {
289-
fmt.Fprintf(os.Stderr, "unable to create WinLI image: %v\n", err)
290-
os.Exit(1)
291-
}
271+
amiID, err = API.CreateHVMImage(sourceSnapshot, uploadDiskSizeGiB, uploadAMIName, uploadAMIDescription, uploadImageArchitecture, uploadVolumeType, uploadIMDSv2Only, uploadX86BootMode, uploadBillingProductCode)
272+
if err != nil {
273+
fmt.Fprintf(os.Stderr, "unable to create HVM image: %v\n", err)
274+
os.Exit(1)
292275
}
293276

294277
if len(uploadGrantUsers) > 0 {

0 commit comments

Comments
 (0)