@@ -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