Skip to content

Commit e4f97dd

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 8761827 commit e4f97dd

2 files changed

Lines changed: 88 additions & 0 deletions

File tree

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: 86 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,93 @@ 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+
// In 4.19+ we switched the command to upload to clouds to
61+
// `cosa imageupload-<cloud>`
62+
// https://github.com/coreos/coreos-assembler/pull/4074
63+
def image_upload_cmd = "imageupload"
64+
65+
// Since we are not uploading anything, let's just touch the vmdk image
66+
// file to satisfy ore aws upload, which still requires the file in the
67+
// cosa working dir.
68+
def s3_stream_dir = pipeutils.get_s3_streams_dir(pipecfg, stream)
69+
shwrap("""
70+
touch builds/${buildID}/${basearch}/${aws_image_name}
71+
""")
72+
73+
// Discover the latest Windows Server AMI to use as the winli-builder instance.
74+
// The AMI rotates frequently with Windows updates and is not persistant in AWS
75+
// for very long, so we need to find the most recent AMI ID.
76+
// Windows Server 2022 was selected here because the Windows Server 2025 AMI does
77+
// not allow legacy bios. WS2022 has an EOL date of 2026-10-13.
78+
// https://learn.microsoft.com/en-us/lifecycle/products/windows-server-2022
79+
// If WS2022 becomes inaccessible in the future and we still need BIOS for our
80+
// winli images then we can just use one of our own previously created winli
81+
// images and pass that to `--windows-ami` below.
82+
def windows_server_ami_name = ""
83+
windows_server_ami_name = "Windows_Server-2022-English-Full-Base-*"
84+
def windows_server_ami = shwrapCapture("""
85+
aws ec2 describe-images \
86+
--region=${c.primary_region} \
87+
--owners="amazon" \
88+
--filters="Name=name,Values=${windows_server_ami_name}" \
89+
--query="sort_by(Images, &CreationDate)[-1].ImageId" \
90+
--output text
91+
""")
92+
93+
// validate that we did actually get an AMI ID returned.
94+
if (!(windows_server_ami_name != /^ami-[0-9][a-f]{17}$/)) {
95+
error("Invalid Windows Server AMI ID: ${windows_server_ami}")
96+
}
97+
98+
def extraArgs = []
99+
if (c.grant_users) {
100+
extraArgs += c.grant_users.collect{"--grant-user=${it}"}
101+
extraArgs += c.grant_users.collect{"--grant-user-snapshot=${it}"}
102+
}
103+
if (c.tags) {
104+
extraArgs += c.tags.collect { "--tags=${it}" }
105+
}
106+
if (c.public) {
107+
extraArgs += "--public"
108+
}
109+
shwrap("""
110+
cosa ${image_upload_cmd}-aws \
111+
--upload \
112+
--winli \
113+
--windows-ami=${windows_server_ami} \
114+
--arch=${basearch} \
115+
--build=${buildID} \
116+
--region=${c.primary_region} \
117+
--credentials-file=\${AWS_CONFIG_FILE} \
118+
${extraArgs.join(' ')}
119+
""")
120+
}
121+
}
49122
if (meta.amis) {
50123
credentials = [file(variable: "UNUSED", credentialsId: "aws-build-upload-config")]
51124
if (pipecfg.clouds?.aws &&
52125
utils.credentialsExist(credentials)) {
126+
127+
// grab the aws vmdk image name from the metadata to pass to the winli closure.
128+
// ore aws upload still requires the image to exist, but we dont upload anything
129+
// so we'll just touch the file in the cosa working dir.
130+
def aws_image_name = meta.images.aws.path
131+
// aws-winli is only supported on x86_64
132+
if ((basearch == "x86_64") && (stream_info.create_and_replicate_winli_ami)) {
133+
builders["☁️ 🔨:aws-winli"] = {
134+
awsWinLIBuildClosure.call(pipecfg.clouds.aws, aws_image_name,
135+
"aws-build-upload-config")
136+
}
137+
}
53138
replicators["☁️ 🔄:aws"] = {
54139
awsReplicateClosure.call(pipecfg.clouds.aws,
55140
"aws-build-upload-config")
@@ -92,6 +177,7 @@ def replicate_to_clouds(pipecfg, basearch, buildID, stream) {
92177
}
93178
}
94179

180+
parallel builders
95181
parallel replicators
96182
}
97183
// Upload artifacts to clouds

0 commit comments

Comments
 (0)