@@ -6,7 +6,9 @@ def replicate_to_clouds(pipecfg, basearch, buildID, stream) {
6
6
cosa meta --build=${ buildID} --arch=${ basearch} --dump
7
7
""" ))
8
8
def replicators = [:]
9
+ def builders = [:]
9
10
def credentials
11
+ def stream_info = pipecfg. streams[stream]
10
12
11
13
credentials = [file(variable : " ALIYUN_IMAGE_UPLOAD_CONFIG" ,
12
14
credentialsId : " aliyun-image-upload-config" )]
@@ -46,10 +48,95 @@ def replicate_to_clouds(pipecfg, basearch, buildID, stream) {
46
48
""" )
47
49
}
48
50
}
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
+ }
49
124
if (meta. amis) {
50
125
credentials = [file(variable : " UNUSED" , credentialsId : " aws-build-upload-config" )]
51
126
if (pipecfg. clouds?. aws &&
52
127
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
+ }
53
140
replicators[" ☁️ 🔄:aws" ] = {
54
141
awsReplicateClosure. call(pipecfg. clouds. aws,
55
142
" aws-build-upload-config" )
@@ -92,6 +179,7 @@ def replicate_to_clouds(pipecfg, basearch, buildID, stream) {
92
179
}
93
180
}
94
181
182
+ parallel builders
95
183
parallel replicators
96
184
}
97
185
// Upload artifacts to clouds
0 commit comments