Skip to content

Commit 0791319

Browse files
committed
mantle/platform/aws: add CreateWinLiImage
Add an API method to create AWS Windows License Included CoreOS images. The image creation flow is essentially: - create Windows Server ec2 instance - stop windows instance - remove windows root volume - create a new root volume from an existing CoreOS snapshot - attach new root volume to windows instance - create image/snapshot from modified windows instance The result is an image that will function exactly like CoreOS AWS AMI, that also includes Windows LI billing code metadata. See: https://issues.redhat.com/browse/COS-3042
1 parent d2bed6c commit 0791319

File tree

1 file changed

+71
-0
lines changed

1 file changed

+71
-0
lines changed

‎mantle/platform/api/aws/images.go

Lines changed: 71 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -338,6 +338,77 @@ func (a *API) CreateImportRole(bucket string) error {
338338
return nil
339339
}
340340

341+
func (a *API) CreateWinLiImage(snapshotID string, name string, description string, architecture string, windowsAMI string, instanceType string, volumetype string) (string, string, error) {
342+
//var awsArch string
343+
if architecture != "x86_64" {
344+
return "", "", fmt.Errorf("unsupported WinLi architecture %q", architecture)
345+
}
346+
347+
opts := *a.opts
348+
opts.AMI = windowsAMI
349+
opts.InstanceType = instanceType
350+
opts.SecurityGroup = "winli-builder"
351+
aa, err := New(&opts)
352+
if err != nil {
353+
return "", "", err
354+
}
355+
356+
instanceName := util.RandomName("winli-builder")
357+
keyname := ""
358+
userdata := ""
359+
count := 1
360+
minDiskSize := 0
361+
useInstanceProfile := false
362+
363+
insts, err := aa.CreateInstances(instanceName, keyname, userdata, uint64(count), int64(minDiskSize), useInstanceProfile)
364+
if err != nil {
365+
return "", "", fmt.Errorf("failed to create windows server instance %q", err)
366+
}
367+
368+
winliInstanceId := *insts[0].InstanceId
369+
370+
// stop the instance in order to replace the root volume
371+
err = aa.StopInstances([]string{winliInstanceId})
372+
if err != nil {
373+
return "", "", fmt.Errorf("stop instances failed: %v", err)
374+
}
375+
376+
// create a new root volume from the CoreOS snapshot
377+
availabilityZone := *insts[0].Placement.AvailabilityZone
378+
newRootVolumeName := name + "-winli-root-volume"
379+
newRootVolumeID, err := aa.CreateVolumeFromSnapshot(newRootVolumeName, snapshotID, volumetype, availabilityZone)
380+
if err != nil {
381+
return "", "", fmt.Errorf("error creating volume from snapshot: %v", err)
382+
}
383+
384+
rootVolumeDevName := "/dev/sda1"
385+
err = aa.ReplaceRootVolume(winliInstanceId, rootVolumeDevName, newRootVolumeID)
386+
if err != nil {
387+
return "", "", fmt.Errorf("error replacing root volume: %v", err)
388+
}
389+
390+
// if we made it here, we have a windows instance with an CoreOS root volume.
391+
// create an image based on the modified instance and return the ImageId
392+
params := &ec2.CreateImageInput{
393+
Name: aws.String(name),
394+
Description: aws.String(description),
395+
InstanceId: aws.String(winliInstanceId),
396+
}
397+
398+
// create AMI from the modified windows instance
399+
imageID, snapshotID, err := aa.CreateImageFromInstance(params)
400+
401+
// delete the windows instance
402+
terminateErr := aa.TerminateInstances([]string{winliInstanceId})
403+
if terminateErr != nil {
404+
// log the failure and continue
405+
plog.Infof("failed to terminate instance %v: %v", winliInstanceId, terminateErr)
406+
}
407+
408+
return imageID, snapshotID, err
409+
410+
}
411+
341412
func (a *API) CreateHVMImage(snapshotID string, diskSizeGiB uint, name string, description string, architecture string, volumetype string, imdsv2Only bool, X86BootMode string) (string, error) {
342413
var awsArch string
343414
var bootmode string

0 commit comments

Comments
 (0)