Skip to content

Commit 34038e8

Browse files
committed
libcloud: build and replicate aws-winli images for supported streams
Expand the replicate to clouds functionality to build AWS Windows License Included (winli) images for streams that support it before replicating AMIs to other regions. `cosa aws-replicate` will now replicate both traditional AMIs and aws-winli AMIs if present in the metadata. See: coreos/coreos-assembler#4069 Also add `create_and_replicate_winli_ami` as a stream level knob to the pipeline config to enable building and replicating the AMIs for specific streams.
1 parent edce783 commit 34038e8

File tree

2 files changed

+90
-0
lines changed

2 files changed

+90
-0
lines changed

docs/config.yaml

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -119,6 +119,8 @@ streams:
119119
# When mechanical streams have `scheduled` on, then
120120
# `build-mechanical` will only build those streams
121121
scheduled: true
122+
# OPTIONAL: Create and replicate AWS Windows License Included images for this stream.
123+
create_and_replicate_winli_ami: true
122124

123125
# REQUIRED: architectures to build for other than x86_64
124126
additional_arches: [aarch64, ppc64le, s390x]

libcloud.groovy

Lines changed: 88 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -6,7 +6,9 @@ def replicate_to_clouds(pipecfg, basearch, buildID, stream) {
66
cosa meta --build=${buildID} --arch=${basearch} --dump
77
"""))
88
def replicators = [:]
9+
def builders = [:]
910
def credentials
11+
def stream_info = pipecfg.streams[stream]
1012

1113
credentials = [file(variable: "ALIYUN_IMAGE_UPLOAD_CONFIG",
1214
credentialsId: "aliyun-image-upload-config")]
@@ -46,10 +48,95 @@ def replicate_to_clouds(pipecfg, basearch, buildID, stream) {
4648
""")
4749
}
4850
}
51+
// A closure to build the aws-winli AMI. This will be called before replicating to
52+
// all regions, if the option is set for the current stream. `cosa aws-replicate`
53+
// will handle both traditional AMIs and aws-winli AMIs if present in the metadata.
54+
// aws-winli is only supported on x86_64.
55+
def awsWinLIBuildClosure = { config, aws_image_name, credentialId ->
56+
def creds = [file(variable: "AWS_CONFIG_FILE", credentialsId: credentialId)]
57+
withCredentials(creds) {
58+
utils.syncCredentialsIfInRemoteSession(["AWS_CONFIG_FILE"])
59+
def c = config
60+
61+
// Since we are not uploading anything, let's just touch the vmdk image
62+
// file to satisfy the cosa ore wrapper, which still requires the file
63+
// in the cosa working dir.
64+
def aws_image_path = "builds/${buildID}/${basearch}/${aws_image_name}"
65+
shwrap("""
66+
touch ${aws_image_path}
67+
""")
68+
69+
// Discover the latest Windows Server AMI to use as the winli-builder instance.
70+
// The AMI rotates frequently with Windows updates and is not persistant in AWS
71+
// for very long, so we need to find the most recent AMI ID.
72+
// Windows Server 2022 was selected here because the Windows Server 2025 AMI does
73+
// not allow legacy bios. WS2022 has an EOL date of 2026-10-13.
74+
// https://learn.microsoft.com/en-us/lifecycle/products/windows-server-2022
75+
// If WS2022 becomes inaccessible in the future and we still need BIOS for our
76+
// winli images then we can just use one of our own previously created winli
77+
// images and pass that to `--windows-ami` below.
78+
def windows_server_ami_name = ""
79+
windows_server_ami_name = "Windows_Server-2022-English-Full-Base-*"
80+
def windows_server_ami = shwrapCapture("""
81+
aws ec2 describe-images \
82+
--region=${c.primary_region} \
83+
--owners="amazon" \
84+
--filters="Name=name,Values=${windows_server_ami_name}" \
85+
--query="sort_by(Images, &CreationDate)[-1].ImageId" \
86+
--output text
87+
""")
88+
89+
// validate that we did actually get an AMI ID returned.
90+
if (!(windows_server_ami_name != /^ami-[0-9][a-f]{17}$/)) {
91+
error("Invalid Windows Server AMI ID: ${windows_server_ami}")
92+
}
93+
94+
def extraArgs = []
95+
if (c.grant_users) {
96+
extraArgs += c.grant_users.collect{"--grant-user=${it}"}
97+
extraArgs += c.grant_users.collect{"--grant-user-snapshot=${it}"}
98+
}
99+
if (c.tags) {
100+
extraArgs += c.tags.collect { "--tags=${it}" }
101+
}
102+
if (c.public) {
103+
extraArgs += "--public"
104+
}
105+
shwrap("""
106+
cosa imageupload-aws \
107+
--upload \
108+
--winli \
109+
--windows-ami=${windows_server_ami} \
110+
--arch=${basearch} \
111+
--build=${buildID} \
112+
--region=${c.primary_region} \
113+
--credentials-file=\${AWS_CONFIG_FILE} \
114+
${extraArgs.join(' ')}
115+
""")
116+
117+
// remove the false vmdk file from the builds directory so it doesn't get
118+
// uploaded by some other process
119+
shwrap("""
120+
rm ${aws_image_path}
121+
""")
122+
}
123+
}
49124
if (meta.amis) {
50125
credentials = [file(variable: "UNUSED", credentialsId: "aws-build-upload-config")]
51126
if (pipecfg.clouds?.aws &&
52127
utils.credentialsExist(credentials)) {
128+
129+
// grab the aws vmdk image name from the metadata to pass to the winli closure.
130+
// the cosa ore wrapper still requires the image to exist, but we dont upload
131+
// anything so we'll just touch the file in the cosa working dir.
132+
def aws_image_name = meta.images.aws.path
133+
// aws-winli is only supported on x86_64
134+
if ((basearch == "x86_64") && (stream_info.create_and_replicate_winli_ami)) {
135+
builders["☁️ 🔨:aws-winli"] = {
136+
awsWinLIBuildClosure.call(pipecfg.clouds.aws, aws_image_name,
137+
"aws-build-upload-config")
138+
}
139+
}
53140
replicators["☁️ 🔄:aws"] = {
54141
awsReplicateClosure.call(pipecfg.clouds.aws,
55142
"aws-build-upload-config")
@@ -92,6 +179,7 @@ def replicate_to_clouds(pipecfg, basearch, buildID, stream) {
92179
}
93180
}
94181

182+
parallel builders
95183
parallel replicators
96184
}
97185
// Upload artifacts to clouds

0 commit comments

Comments
 (0)