1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
|
// Builds are driven by the tag name. The pipeline does nothing at all unless
// the checkout is a tag of the form
//
// fedora-<fedora_ver>-kernel-<upstream_ver>-patchset-<patchset_ver>
//
// e.g. fedora-45-kernel-7.2.3-patchset-1.
//
// The Fedora version picks the build container and the bucket prefix. The
// kernel and patchset versions are asserted against the spec rather than fed
// into it, so the spec stays the one place they are defined and a mistyped tag
// fails the build instead of publishing something that disagrees with its name.
TAG_PATTERN = /^fedora-(\d+)-kernel-(.+)-patchset-(\d+)$/
// The container image is the one field that has to be known before the agent
// exists, so it cannot be read out of the shell below. Everything between
// `fedora-` and `-kernel-` is the Fedora version, and it never contains a dash.
def fedoraVersionFromTag() {
def tag = env.TAG_NAME ?: ''
tag ==~ TAG_PATTERN ? tag.split('-')[1] : null
}
pipeline {
agent none
options {
timestamps()
}
environment {
B2_ENDPOINT = 'https://s3.eu-central-003.backblazeb2.com'
AWS_DEFAULT_REGION = 'eu-central-003'
RPM_BUCKET = 'dist-sayagit-fedora-rpm'
// awscli2 sends CRC32 checksums by default, which B2 rejects. Ask for
// them only where the S3 API requires them.
AWS_REQUEST_CHECKSUM_CALCULATION = 'when_required'
AWS_RESPONSE_CHECKSUM_VALIDATION = 'when_required'
}
stages {
stage('Build and publish kernel-surface RPM (ARM64)') {
when {
beforeAgent true
allOf {
buildingTag()
expression { env.TAG_NAME ==~ TAG_PATTERN }
}
}
agent {
kubernetes {
defaultContainer 'rpmbuild'
yaml """
apiVersion: v1
kind: Pod
metadata:
namespace: jenkins
spec:
nodeSelector:
kubernetes.io/arch: arm64
containers:
- name: rpmbuild
image: fedora:${fedoraVersionFromTag()}
imagePullPolicy: Always
command: [ 'sleep' ]
args: [ 'infinity' ]
tty: true
resources:
requests:
cpu: "4"
memory: 5Gi
ephemeral-storage: 40Gi
limits:
memory: 7Gi
ephemeral-storage: 100Gi
"""
}
}
steps {
checkout scm
container('rpmbuild') {
withCredentials([usernamePassword(
credentialsId: 'backblaze-b2-dist-rpm',
usernameVariable: 'AWS_ACCESS_KEY_ID',
passwordVariable: 'AWS_SECRET_ACCESS_KEY')]) {
sh '''
set -eux
dnf --assumeyes install \\
git rpm-build rpmdevtools dnf5-plugins awscli2 curl tar \\
createrepo_c
git config --global --add safe.directory '*'
git submodule update --init overlay
rest=${TAG_NAME#fedora-*-kernel-}
tag_fedora=${TAG_NAME#fedora-}
tag_fedora=${tag_fedora%%-kernel-*}
tag_kernel=${rest%-patchset-*}
tag_patchset=${rest##*-patchset-}
fedora_version=${tag_fedora}
# The tag drives the build: these override the
# spec's own %global defaults, and make-sources.sh
# reads them out of the environment so the patch
# tarball it assembles is the one Source1 names.
export UPSTREAM_VER=${tag_kernel}
export PATCHSET_VER=${tag_patchset}
# A numbered tag has to agree with the container it
# selected, which is what stamps %{?dist} onto the
# release.
container_fedora=$(rpm --eval '%{fedora}')
if [ "${tag_fedora}" != "${container_fedora}" ]; then
echo "tag names Fedora ${tag_fedora}, container is ${container_fedora}" >&2
exit 1
fi
rpmdev-setuptree
# The published file name is whatever the spec
# resolves to under the tag's versions, so the two
# cannot drift. A kernel build is expensive; if this
# exact NEVRA is already in the bucket, skip
# straight to the metadata.
rpm_file=$(rpmspec -q \\
--define "upstream_ver ${UPSTREAM_VER}" \\
--define "patchset_ver ${PATCHSET_VER}" \\
--queryformat '%{NAME}-%{VERSION}-%{RELEASE}.%{ARCH}.rpm\\n' \\
kernel-surface.spec | head -n1)
dest="s3://${RPM_BUCKET}/fedora/${fedora_version}/aarch64/${rpm_file}"
skip_build=false
if aws s3 ls --endpoint-url "${B2_ENDPOINT}" "${dest}"; then
echo "${rpm_file} already published, skipping build"
skip_build=true
fi
if [ "${skip_build}" = false ]; then
./make-sources.sh
dnf --assumeyes builddep kernel-surface.spec
rpmbuild -bb \\
--define "upstream_ver ${UPSTREAM_VER}" \\
--define "patchset_ver ${PATCHSET_VER}" \\
--define '_smp_mflags -j4' \\
kernel-surface.spec
built="${HOME}/rpmbuild/RPMS/aarch64/${rpm_file}"
test -f "${built}"
aws s3 cp --endpoint-url "${B2_ENDPOINT}" \\
"${built}" "${dest}"
fi
repo_url="s3://${RPM_BUCKET}/fedora/${fedora_version}/aarch64"
repo="${WORKSPACE}/repo"
mkdir -p "${repo}"
aws s3 sync --endpoint-url "${B2_ENDPOINT}" \\
--exclude '*' --include '*.rpm' \\
"${repo_url}/" "${repo}/"
createrepo_c --update "${repo}"
aws s3 sync --endpoint-url "${B2_ENDPOINT}" \\
--exclude 'repomd.xml*' \\
"${repo}/repodata/" "${repo_url}/repodata/"
aws s3 cp --endpoint-url "${B2_ENDPOINT}" \\
"${repo}/repodata/repomd.xml" \\
"${repo_url}/repodata/repomd.xml"
# Served next to the repository so that consumers
# can `dnf config-manager --add-repo` the URL.
sed "s|[$]releasever|${fedora_version}|g" \\
kernel-sp12in.repo > "${WORKSPACE}/published.repo"
aws s3 cp --endpoint-url "${B2_ENDPOINT}" \\
"${WORKSPACE}/published.repo" \\
"s3://${RPM_BUCKET}/fedora/${fedora_version}/kernel-sp12in.repo"
'''
}
}
}
}
}
}
|