Skip to content

Commit 70f1779

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 70f1779

2 files changed

Lines changed: 73 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: 71 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -6,7 +6,10 @@ 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+
pipeutils = load("utils.groovy")
12+
def stream_info = pipecfg.streams[stream]
1013

1114
credentials = [file(variable: "ALIYUN_IMAGE_UPLOAD_CONFIG",
1215
credentialsId: "aliyun-image-upload-config")]
@@ -46,10 +49,77 @@ def replicate_to_clouds(pipecfg, basearch, buildID, stream) {
4649
""")
4750
}
4851
}
52+
// A closure to build the aws-winli AMI. This will be called before replicating to
53+
// all regions, if the option is set for the current stream. `cosa aws-replicate`
54+
// will handle both traditional AMIs and aws-winli AMIs if present in the metadata.
55+
// aws-winli is only supported on x86_64.
56+
def awsWinLIBuildClosure = { config, credentialId ->
57+
def creds = [file(variable: "AWS_CONFIG_FILE", credentialsId: credentialId)]
58+
withCredentials(creds) {
59+
utils.syncCredentialsIfInRemoteSession(["AWS_CONFIG_FILE"])
60+
def c = config
61+
62+
// Discover the latest Windows Server AMI to use as the winli-builder instance.
63+
// The AMI rotates frequently with Windows updates and is not persistant in AWS
64+
// for very long, so we need to find the most recent AMI ID.
65+
// Windows Server 2022 was selected here because the Windows Server 2025 AMI does
66+
// not allow legacy bios. WS2022 has an EOL date of 2026-10-13.
67+
// https://learn.microsoft.com/en-us/lifecycle/products/windows-server-2022
68+
// If WS2022 becomes inaccessible in the future and we still need BIOS for our
69+
// winli images then we can just use one of our own previously created winli
70+
// images and pass that to `--windows-ami` below.
71+
def windows_server_ami_name = ""
72+
windows_server_ami_name = "Windows_Server-2022-English-Full-Base-*"
73+
def windows_server_ami = shwrapCapture("""
74+
aws ec2 describe-images \
75+
--region=${c.primary_region} \
76+
--owners="amazon" \
77+
--filters="Name=name,Values=${windows_server_ami_name}" \
78+
--query="sort_by(Images, &CreationDate)[-1].ImageId" \
79+
--output text
80+
""")
81+
82+
// validate that we did actually get an AMI ID returned.
83+
if (!(windows_server_ami_name != /^ami-[0-9][a-f]{17}$/)) {
84+
error("Invalid Windows Server AMI ID: ${windows_server_ami}")
85+
}
86+
87+
def extraArgs = []
88+
if (c.grant_users) {
89+
extraArgs += c.grant_users.collect{"--grant-user=${it}"}
90+
extraArgs += c.grant_users.collect{"--grant-user-snapshot=${it}"}
91+
}
92+
if (c.tags) {
93+
extraArgs += c.tags.collect { "--tags=${it}" }
94+
}
95+
if (c.public) {
96+
extraArgs += "--public"
97+
}
98+
shwrap("""
99+
cosa ${image_upload_cmd}-aws \
100+
--upload \
101+
--winli \
102+
--windows-ami=${windows_server_ami} \
103+
--arch=${basearch} \
104+
--build=${buildID} \
105+
--region=${c.primary_region} \
106+
--credentials-file=\${AWS_CONFIG_FILE} \
107+
${extraArgs.join(' ')}
108+
""")
109+
}
110+
}
49111
if (meta.amis) {
50112
credentials = [file(variable: "UNUSED", credentialsId: "aws-build-upload-config")]
51113
if (pipecfg.clouds?.aws &&
52114
utils.credentialsExist(credentials)) {
115+
116+
// aws-winli is only supported on x86_64
117+
if ((basearch == "x86_64") && (stream_info.create_and_replicate_winli_ami)) {
118+
builders["☁️ 🔨:aws-winli"] = {
119+
awsWinLIBuildClosure.call(pipecfg.clouds.aws,
120+
"aws-build-upload-config")
121+
}
122+
}
53123
replicators["☁️ 🔄:aws"] = {
54124
awsReplicateClosure.call(pipecfg.clouds.aws,
55125
"aws-build-upload-config")
@@ -92,6 +162,7 @@ def replicate_to_clouds(pipecfg, basearch, buildID, stream) {
92162
}
93163
}
94164

165+
parallel builders
95166
parallel replicators
96167
}
97168
// Upload artifacts to clouds

0 commit comments

Comments
 (0)