Skip to content

Commit 9ccf235

Browse files
thegreydjoepvd
andauthored
ART-10946 rhcos_sync nightlies to dev dir (#4295)
Co-authored-by: Joep van Delft <[email protected]>
1 parent 4bdf44b commit 9ccf235

File tree

4 files changed

+123
-88
lines changed

4 files changed

+123
-88
lines changed

jobs/build/rhcos_sync/Jenkinsfile

Lines changed: 52 additions & 27 deletions
Original file line numberDiff line numberDiff line change
@@ -65,28 +65,46 @@ node {
6565
}
6666

6767
tag = params.RELEASE_TAG
68-
image = "quay.io/openshift-release-dev/ocp-release:${tag}"
69-
if (tag.contains("/")) {
70-
// assume instead of a tag it's a pullspec e.g. to registry.ci
71-
if (!tag.contains(":")) error("RELEASE_TAG pullspec must include a :tag")
72-
image = tag
73-
tag = tag.split(":")[-1]
74-
}
75-
76-
name = commonlib.shell(
77-
returnStdout: true,
78-
script: "oc adm release info -o template --template '{{ .metadata.version }}' ${image}"
79-
)
8068

8169
(major, minor) = commonlib.extractMajorMinorVersionNumbers(tag)
8270
ocpVersion = "$major.$minor"
8371

8472
(arch, priv) = releaselib.getReleaseTagArchPriv(tag)
8573
suffix = releaselib.getArchPrivSuffix(arch, priv)
8674

75+
pullspec = ""
76+
if (tag.contains("/")) {
77+
// assume instead of a tag it's a pullspec e.g. to registry.ci
78+
if (!tag.contains(":")) error("RELEASE_TAG pullspec must include a :tag")
79+
pullspec = tag
80+
tag = tag.split(":")[-1]
81+
}
82+
if (pullspec == "") {
83+
if (tag.contains("nightly")) {
84+
pullspec = "registry.ci.openshift.org/ocp${suffix}/release${suffix}:${tag}"
85+
} else {
86+
pullspec = "quay.io/openshift-release-dev/ocp-release:${tag}"
87+
}
88+
}
89+
90+
onlyIfDifferent = false
91+
noLatest = params.NO_LATEST
92+
// for nightlies, sync them to dev dir
93+
// This is a special case. see: ART-10946
94+
if (tag.contains("nightly")) {
95+
name = "dev-${ocpVersion}"
96+
noLatest = true
97+
onlyIfDifferent = true
98+
} else {
99+
name = commonlib.shell(
100+
returnStdout: true,
101+
script: "oc adm release info -o template --template '{{ .metadata.version }}' ${pullspec}"
102+
)
103+
}
104+
87105
cmd = """
88106
tmp=\$(mktemp -d /tmp/tmp.XXXXXX)
89-
oc image extract --path /manifests/:\$tmp \$(oc adm release info --image-for installer ${image})
107+
oc image extract --path /manifests/:\$tmp \$(oc adm release info --image-for installer ${pullspec})
90108
cat \$tmp/coreos-bootimages.yaml | yq -r .data.stream | jq -r .architectures.${arch}.artifacts.qemu.release
91109
rm -rf \$tmp
92110
"""
@@ -101,23 +119,25 @@ node {
101119

102120
print("RHCOS build: $rhcosBuild, arch: $arch, mirror prefix: $mirrorPrefix")
103121

104-
echo("Initializing RHCOS-${params.MIRROR_PREFIX} sync: #${currentBuild.number}")
122+
echo("Initializing RHCOS-${mirrorPrefix} sync: #${currentBuild.number}")
105123
rhcoslib.initialize(ocpVersion, rhcosBuild, arch, name, mirrorPrefix)
106124

107125
try {
108126
stage("Get/Generate sync list") {
109127
rhcoslib.rhcosSyncPrintArtifacts()
110128
}
111129
stage("Mirror artifacts") {
112-
rhcoslib.rhcosSyncMirrorArtifacts(mirrorPrefix, arch, rhcosBuild, name)
130+
rhcoslib.rhcosSyncMirrorArtifacts(mirrorPrefix, arch, rhcosBuild, name, noLatest, onlyIfDifferent)
113131
}
114132
stage("Slack notification to release channel") {
115-
slacklib.to(ocpVersion).say("""
116-
*:white_check_mark: rhcos_sync (${mirrorPrefix}) successful*
117-
https://mirror.openshift.com/pub/openshift-v4/${arch}/dependencies/rhcos/${mirrorPrefix}/${name}/
133+
if ( !params.DRY_RUN ) {
134+
slacklib.to(ocpVersion).say("""
135+
*:white_check_mark: rhcos_sync (${mirrorPrefix}) successful*
136+
https://mirror.openshift.com/pub/openshift-v4/${arch}/dependencies/rhcos/${mirrorPrefix}/${name}/
118137
119-
buildvm job: ${commonlib.buildURL('console')}
120-
""")
138+
buildvm job: ${commonlib.buildURL('console')}
139+
""")
140+
}
121141
}
122142

123143
// only run for x86_64 since no AMIs for other arches
@@ -136,9 +156,11 @@ node {
136156
}
137157
}
138158
stage("Slack notification to release channel") {
139-
slacklib.to(ocpVersion).say("""
140-
*:white_check_mark: rosa_sync (${name}) successful*
141-
""")
159+
if ( !params.DRY_RUN ) {
160+
slacklib.to(ocpVersion).say("""
161+
*:white_check_mark: rosa_sync (${name}) successful*
162+
""")
163+
}
142164
}
143165
}
144166

@@ -158,10 +180,13 @@ node {
158180
}
159181
}
160182
} catch ( err ) {
161-
slacklib.to(ocpVersion).say("""
162-
*:heavy_exclamation_mark: rhcos_sync ${mirrorPrefix} failed*
163-
buildvm job: ${commonlib.buildURL('console')}
164-
""")
183+
if ( !params.DRY_RUN ) {
184+
slacklib.to(ocpVersion).say("""
185+
*:heavy_exclamation_mark: rhcos_sync ${mirrorPrefix} failed*
186+
buildvm job: ${commonlib.buildURL('console')}
187+
""")
188+
}
189+
throw (err)
165190
} finally {
166191
commonlib.safeArchiveArtifacts(rhcoslib.artifacts)
167192
buildlib.cleanWorkspace()

jobs/build/rhcos_sync/S3-rhcossync.sh

Lines changed: 30 additions & 28 deletions
Original file line numberDiff line numberDiff line change
@@ -38,8 +38,8 @@ EOF
3838
}
3939

4040
function downloadImages() {
41-
for img in $(<${SYNCLIST}); do
42-
curl -L --fail --retry 5 -O $img
41+
for img in $(<"${SYNCLIST}"); do
42+
curl -L --fail --silent --retry 5 -O "$img"
4343
done
4444
# rename files to indicate the release they match (including arch suffix by tradition).
4545
# also create an unversioned symlink to enable consistent incoming links.
@@ -49,15 +49,15 @@ function downloadImages() {
4949
# name like "rhcos-buildid-qemu..."
5050
file="${name/$BUILDID/$release}" # rhcos-release-qemu...
5151
link="${name/-$BUILDID/}" # rhcos-qemu...
52-
[[ $name == $file ]] && continue # skip files that aren't named that way
52+
[[ $name == "$file" ]] && continue # skip files that aren't named that way
5353
mv "$name" "$file"
5454
ln --symbolic "$file" "$link"
5555
done
5656
# Some customer portals point to the deprecated `rhcos-installer` names rather than `rhcos-live`.
5757
# Fix those links.
58-
for f in $(find . -maxdepth 1 -type l -name 'rhcos-live-*'); do
59-
ln -s "$(readlink $f)" "${f/rhcos-live-/rhcos-installer-}"
60-
done
58+
find . -maxdepth 1 -type l -name 'rhcos-live-*' -exec sh -c '
59+
ln -s "$(readlink $1)" "${1/rhcos-live-/rhcos-installer-}"
60+
' sh {} \;
6161
}
6262

6363
function genSha256() {
@@ -67,19 +67,19 @@ function genSha256() {
6767
}
6868

6969
function genRhcosIdTxt() {
70-
echo ${BUILDID} > rhcos-id.txt
70+
echo "${BUILDID}" > rhcos-id.txt
7171
}
7272

7373
function emulateSymlinks() {
7474
S3_SOURCE="$1"
75-
MAJOR_MINOR=$(echo ${VERSION} |awk -F '[.-]' '{print $1 "." $2}') # e.g. 4.3.0-0.nightly-2019-11-08-080321 -> 4.3
75+
MAJOR_MINOR=$(echo "${VERSION}" |awk -F '[.-]' '{print $1 "." $2}') # e.g. 4.3.0-0.nightly-2019-11-08-080321 -> 4.3
7676
# We also need to know what Y stream comes after this one.
77-
MAJOR_NEXT_MINOR=$(echo ${MAJOR_MINOR} |awk -F '[.-]' '{print $1 "." $2+1}') # e.g. 4.3 -> 4.4
77+
MAJOR_NEXT_MINOR=$(echo "${MAJOR_MINOR}" |awk -F '[.-]' '{print $1 "." $2+1}') # e.g. 4.3 -> 4.4
7878

7979
if [[ "${RHCOS_MIRROR_PREFIX}" == "pre-release" ]]; then
8080
MAJOR_MINOR_LATEST="latest-${MAJOR_MINOR}"
81-
aws s3 sync --no-progress --delete --exact-timestamps ${S3_SOURCE} s3://art-srv-enterprise${BASEDIR}/${RHCOS_MIRROR_PREFIX}/${MAJOR_MINOR_LATEST}/
82-
aws s3 sync --no-progress --delete --exact-timestamps ${S3_SOURCE} s3://art-srv-enterprise${BASEDIR}/${RHCOS_MIRROR_PREFIX}/${MAJOR_MINOR_LATEST}/ --profile cloudflare --endpoint-url ${CLOUDFLARE_ENDPOINT}
81+
"${SYNC_CMD[@]}" "${S3_SOURCE}" "s3://art-srv-enterprise${BASEDIR}/${RHCOS_MIRROR_PREFIX}/${MAJOR_MINOR_LATEST}/"
82+
"${SYNC_CMD[@]}" "${S3_SOURCE}" "s3://art-srv-enterprise${BASEDIR}/${RHCOS_MIRROR_PREFIX}/${MAJOR_MINOR_LATEST}/" "${CLOUDFLARE_OPTS[@]}"
8383

8484
# Is this major.minor the latest Y stream? If it is, we need to set
8585
# the overall 'latest'.
@@ -98,8 +98,8 @@ function emulateSymlinks() {
9898
# LATEST_LINK will end up being something like 4.9.0-fc.0 if the next major exists or "" if it does not.
9999

100100
if [[ -z "${LATEST_LINK}" ]]; then
101-
aws s3 sync --no-progress --delete --exact-timestamps ${S3_SOURCE} s3://art-srv-enterprise${BASEDIR}/${RHCOS_MIRROR_PREFIX}/latest/
102-
aws s3 sync --no-progress --delete --exact-timestamps ${S3_SOURCE} s3://art-srv-enterprise${BASEDIR}/${RHCOS_MIRROR_PREFIX}/latest/ --profile cloudflare --endpoint-url ${CLOUDFLARE_ENDPOINT}
101+
"${SYNC_CMD[@]}" "${S3_SOURCE}" "s3://art-srv-enterprise${BASEDIR}/${RHCOS_MIRROR_PREFIX}/latest/"
102+
"${SYNC_CMD[@]}" "${S3_SOURCE}" "s3://art-srv-enterprise${BASEDIR}/${RHCOS_MIRROR_PREFIX}/latest/" "${CLOUDFLARE_OPTS[@]}"
103103
fi
104104

105105
else
@@ -109,8 +109,8 @@ function emulateSymlinks() {
109109
LATEST_CONTENT=$(aws s3 ls "s3://art-srv-enterprise${BASEDIR}/${MAJOR_NEXT_MINOR}/" | grep PRE || true)
110110

111111
if [[ -z "${LATEST_CONTENT}" ]]; then
112-
aws s3 sync --no-progress --delete --exact-timestamps ${S3_SOURCE} s3://art-srv-enterprise${BASEDIR}/latest/
113-
aws s3 sync --no-progress --delete --exact-timestamps ${S3_SOURCE} s3://art-srv-enterprise${BASEDIR}/latest/ --profile cloudflare --endpoint-url ${CLOUDFLARE_ENDPOINT}
112+
"${SYNC_CMD[@]}" "${S3_SOURCE}" "s3://art-srv-enterprise${BASEDIR}/latest/"
113+
"${SYNC_CMD[@]}" "${S3_SOURCE}" "s3://art-srv-enterprise${BASEDIR}/latest/" "${CLOUDFLARE_OPTS[@]}"
114114
fi
115115
fi
116116

@@ -125,7 +125,7 @@ if [ "${#}" -lt "8" ]; then
125125
exit 1
126126
fi
127127

128-
while [ $1 ]; do
128+
while [ "$1" ]; do
129129
case "$1" in
130130
"--prefix")
131131
shift
@@ -159,6 +159,14 @@ while [ $1 ]; do
159159
shift
160160
done
161161

162+
DRY_RUN_FLAG=""
163+
if [ $TEST -eq 1 ]; then
164+
DRY_RUN_FLAG="--dryrun"
165+
fi
166+
167+
SYNC_CMD=(aws s3 sync --no-progress --exact-timestamps --delete ${DRY_RUN_FLAG})
168+
CLOUDFLARE_OPTS=(--profile cloudflare --endpoint-url ${CLOUDFLARE_ENDPOINT})
169+
162170
DESTDIR="${PWD}/staging-${VERSION}"
163171
mkdir -p "${DESTDIR}"
164172

@@ -170,28 +178,22 @@ Sync List: ${SYNCLIST}
170178
Basedir: ${BASEDIR}
171179
EOF
172180

173-
pushd $DESTDIR
181+
pushd "${DESTDIR}"
174182
downloadImages
175183
genSha256
176184
genRhcosIdTxt
177185

178-
if [ $TEST -eq 1 ]; then
179-
echo Would have copied out to ${BASEDIR}/${RHCOS_MIRROR_PREFIX}/${VERSION}/:
180-
ls
181-
exit 0
182-
fi
183-
184186
# Copy the files out to their main location
185-
aws s3 sync --no-progress --delete --exact-timestamps ./ "s3://art-srv-enterprise${BASEDIR}/${RHCOS_MIRROR_PREFIX}/${VERSION}/"
186-
aws s3 sync --no-progress --delete --exact-timestamps ./ "s3://art-srv-enterprise${BASEDIR}/${RHCOS_MIRROR_PREFIX}/${VERSION}/" --profile cloudflare --endpoint-url ${CLOUDFLARE_ENDPOINT}
187+
"${SYNC_CMD[@]}" ./ "s3://art-srv-enterprise${BASEDIR}/${RHCOS_MIRROR_PREFIX}/${VERSION}/"
188+
"${SYNC_CMD[@]}" ./ "s3://art-srv-enterprise${BASEDIR}/${RHCOS_MIRROR_PREFIX}/${VERSION}/" "${CLOUDFLARE_OPTS[@]}"
187189
if [ $NOLATEST -eq 0 ]; then
188-
aws s3 sync --no-progress --delete --exact-timestamps ./ "s3://art-srv-enterprise${BASEDIR}/${RHCOS_MIRROR_PREFIX}/latest/"
189-
aws s3 sync --no-progress --delete --exact-timestamps ./ "s3://art-srv-enterprise${BASEDIR}/${RHCOS_MIRROR_PREFIX}/latest/" --profile cloudflare --endpoint-url ${CLOUDFLARE_ENDPOINT}
190+
"${SYNC_CMD[@]}" ./ "s3://art-srv-enterprise${BASEDIR}/${RHCOS_MIRROR_PREFIX}/latest/"
191+
"${SYNC_CMD[@]}" ./ "s3://art-srv-enterprise${BASEDIR}/${RHCOS_MIRROR_PREFIX}/latest/" "${CLOUDFLARE_OPTS[@]}"
190192
# CloudFlare does not support the full S3 API and we encountered unimplemented APIs using the AWS CLI to sync from one area of R2 to another area.
191193
# We therefore re-copy from local content to R2, which does not hit these limitations. This is technically slower, but works with R2.
192194
emulateSymlinks "./"
193195
else
194196
echo "INFO: Not updating 'latest' symlink because --nolatest was given"
195197
fi
196198
popd
197-
rm -rf $DESTDIR
199+
rm -rf "${DESTDIR}"

jobs/build/rhcos_sync/rhcoslib.groovy

Lines changed: 28 additions & 32 deletions
Original file line numberDiff line numberDiff line change
@@ -3,7 +3,6 @@ buildlib = releaselib.buildlib
33
commonlib = releaselib.commonlib
44
rhcosWorking = "rhcos_working"
55
logLevel = ""
6-
dryRun = ""
76
artifacts = []
87
baseUrl = ""
98
metaUrl = ""
@@ -17,41 +16,15 @@ rhcos_allowlist = [ "gcp", "initramfs", "iso", "kernel", "metal", "openstack", "
1716
def initialize(ocpVersion, rhcosBuild, arch, name, mirrorPrefix) {
1817
buildlib.cleanWorkdir(rhcosWorking)
1918

20-
// Example URL paths (visit https://releases-rhcos-art.apps.ocp-virt.prod.psi.redhat.com/ to view yourself):
21-
// 4.1 with x86 arch: releases/rhcos-4.1/410.81.20200213.0/meta.json (we do not plan to release a new 4.1 bootimage ever)
22-
// 4.1 with non-x86 arch: N/A
19+
baseUrl = buildlib.doozer("--quiet --group=openshift-${ocpVersion} config:read-group urls.rhcos_release_base.multi --default ''", [capture: true]).trim()
20+
baseUrl = "${baseUrl}/${rhcosBuild}/${arch}"
2321

24-
// 4.2 introduced an arch arch suffix
25-
// 4.2 with x86 arch: releases/rhcos-4.2/42.81.20200213.0/meta.json
26-
// 4.2 with non-x86 arch: releases/rhcos-4.2-s390x/42s390x.81.20200131.0/meta.json
27-
28-
// 4.3 introduced an arch subdirectory
29-
// 4.3 with x86 arch: releases/rhcos-4.3/43.81.202002130953.0/x86_64/meta.json
30-
// 4.3 with non-x86 arch: releases/rhcos-4.3-s390x/43.81.202001300441.0/s390x/meta.json
31-
32-
// Sub in some vars according to params
33-
def archSuffix = commonlib.brewSuffixForArch(arch)
34-
def archDir = ocpVersion == "4.2" ? "" : "/${arch}"
35-
baseUrl = "https://art-rhcos-ci.s3.amazonaws.com/releases/rhcos-${ocpVersion}${archSuffix}/${rhcosBuild}${archDir}"
36-
// Since 4.9+, rhcos meta is placed at a different location.
37-
def (major, minor) = commonlib.extractMajorMinorVersionNumbers(ocpVersion)
38-
if (major > 4 || (major == 4 && minor >=9)) {
39-
baseUrl = "https://releases-rhcos-art.apps.ocp-virt.prod.psi.redhat.com/storage/prod/streams/$ocpVersion/builds/$rhcosBuild/$arch"
40-
if (minor >= 16) {
41-
baseUrl = "https://releases-rhcos-art.apps.ocp-virt.prod.psi.redhat.com/storage/prod/streams/$ocpVersion-9.4/builds/$rhcosBuild/$arch"
42-
} else if (minor >= 13) {
43-
baseUrl = "https://releases-rhcos-art.apps.ocp-virt.prod.psi.redhat.com/storage/prod/streams/$ocpVersion-9.2/builds/$rhcosBuild/$arch"
44-
}
45-
}
4622
s3MirrorBaseDir = "/pub/openshift-v4/${arch}/dependencies/rhcos"
47-
// Actual meta.json
48-
metaUrl = baseUrl + "/meta.json"
23+
metaUrl = "${baseUrl}/meta.json"
4924

5025
currentBuild.displayName = "${name} - ${rhcosBuild}:${arch} - ${mirrorPrefix}"
5126
currentBuild.description = "Meta JSON: ${metaUrl}"
52-
5327
if ( params.DRY_RUN ) {
54-
dryRun = "--dry-run=true"
5528
currentBuild.displayName += " [DRY_RUN]"
5629
}
5730

@@ -77,7 +50,30 @@ def rhcosSyncPrintArtifacts() {
7750
writeFile file: syncList, text: "${imageUrls.join('\n')}"
7851
}
7952

80-
def rhcosSyncMirrorArtifacts(rhcosMirrorPrefix, arch, rhcosBuild, name) {
53+
def getRhcosBuildFromMirror(rhcosMirrorPrefix, name) {
54+
def rhcosIdUrl = "https://mirror.openshift.com${s3MirrorBaseDir}/${rhcosMirrorPrefix}/${name}/rhcos-id.txt"
55+
def res = commonlib.shell(script: "curl --fail --silent --retry 3 --retry-delay 10 -L ${rhcosIdUrl}", returnAll: true)
56+
def rhcosId = "[NOT FOUND]"
57+
if (res.returnStatus == 0) {
58+
rhcosId = res.stdout.trim()
59+
}
60+
return rhcosId
61+
}
62+
63+
def rhcosSyncMirrorArtifacts(rhcosMirrorPrefix, arch, rhcosBuild, name, noLatest, onlyIfDifferent) {
64+
// check if rhcos-id is already on the mirror
65+
def rhcosBuildOnMirror = getRhcosBuildFromMirror(rhcosMirrorPrefix, name)
66+
echo("RHCOS build requested to sync: ${rhcosBuild}")
67+
echo("RHCOS build on mirror: ${rhcosBuildOnMirror}")
68+
if (rhcosBuildOnMirror == rhcosBuild) {
69+
if (!params.FORCE && onlyIfDifferent) {
70+
echo("RHCOS build is already on mirror, skipping sync")
71+
return
72+
}
73+
} else {
74+
echo("RHCOS build ${rhcosBuild} not on mirror, syncing")
75+
}
76+
8177
def invokeOpts = " --prefix ${rhcosMirrorPrefix}" +
8278
" --arch ${arch}" +
8379
" --buildid ${rhcosBuild}" +
@@ -86,7 +82,7 @@ def rhcosSyncMirrorArtifacts(rhcosMirrorPrefix, arch, rhcosBuild, name) {
8682
if ( params.DRY_RUN ) {
8783
invokeOpts += " --test"
8884
}
89-
if ( params.NO_LATEST ) {
85+
if ( noLatest ) {
9086
invokeOpts += " --nolatest"
9187
}
9288

scheduled-jobs/build/poll-payload/Jenkinsfile

Lines changed: 13 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -18,7 +18,9 @@ import groovy.json.JsonOutput
1818
"4-dev-preview-ppc64le": [this.&setDevPreviewLatest],
1919
"4-dev-preview-arm64": [this.&setDevPreviewLatest],
2020

21-
"4.18.0-0.nightly": [this.&startBuildMicroshiftJob, this.&publishRPMsEl9, this.&publishRPMsEl8],
21+
"4.19.0-0.nightly": [this.&startRhcosSyncJob],
22+
23+
"4.18.0-0.nightly": [this.&startBuildMicroshiftJob, this.&publishRPMsEl9, this.&publishRPMsEl8, this.&startRhcosSyncJob],
2224
"4.18.0-0.nightly-arm64": [this.&publishRPMsEl9, this.&publishRPMsEl8],
2325

2426
"4.17.0-0.nightly": [this.&startBuildMicroshiftJob, this.&publishRPMsEl9, this.&publishRPMsEl8],
@@ -34,6 +36,16 @@ import groovy.json.JsonOutput
3436
"4.14.0-0.nightly-arm64": [this.&publishRPMsEl9],
3537
]
3638

39+
def startRhcosSyncJob(String releaseStream, Map latestRelease, Map previousRelease) {
40+
build(
41+
job: '/aos-cd-builds/build%2Frhcos_sync',
42+
propagate: false,
43+
parameters: [
44+
string(name: 'RELEASE_TAG', value: latestRelease.name),
45+
],
46+
)
47+
}
48+
3749
def setDevPreviewLatest(String releaseStream, Map latestRelease, Map previousRelease) {
3850
def buildVersion = commonlib.extractMajorMinorVersion(latestRelease.name)
3951
def arch = commonlib.extractArchFromReleaseName(releaseStream)

0 commit comments

Comments
 (0)