Skip to content

Commit 3f3dbb8

Browse files
Merge pull request #21 from theohbrothers/refactor/generate-dockerfiles-with-hardcoded-checksums-for-repeatable-builds
Refactor: Generate Dockerfiles with hardcoded checksums for repeatable builds
2 parents 764296a + 1dbf749 commit 3f3dbb8

File tree

5 files changed

+305
-116
lines changed

5 files changed

+305
-116
lines changed

generate/definitions/VARIANTS.ps1

Lines changed: 149 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -76,3 +76,152 @@ $VARIANTS_SHARED = @{
7676
}
7777
}
7878
}
79+
80+
# Global cache for checksums
81+
$global:CHECKSUMS = @{}
82+
function global:Set-Checksums($k, $url) {
83+
$global:CHECKSUMS[$k] = if ($global:CHECKSUMS[$k]) { $global:CHECKSUMS[$k] } else { [System.Text.Encoding]::UTF8.GetString( (Invoke-WebRequest $url).Content ) -split "`n" }
84+
}
85+
function global:Get-ChecksumsFile ($k, $keyword) {
86+
$global:CHECKSUMS[$k] | ? { $_ -match $keyword } | % { $_ -split "\s" } | Select-Object -Last 1 | % { $_.TrimStart('*') }
87+
}
88+
function global:Get-ChecksumsSha ($k, $keyword) {
89+
$global:CHECKSUMS[$k] | ? { $_ -match $keyword } | % { $_ -split "\s" } | Select-Object -First 1
90+
}
91+
92+
# Global functions
93+
function global:Generate-DownloadBinary ($o) {
94+
Set-StrictMode -Version Latest
95+
96+
$releaseUrl = "https://$( $o['project'] )/releases/download/$( $o['version'] )"
97+
$checksumsUrl = "$releaseUrl/$( $o['checksums'] )"
98+
Set-Checksums $o['binary'] $checksumsUrl
99+
100+
$binaryUpper = $o['binary'].ToUpper()
101+
@"
102+
# Install $( $o['binary'] )
103+
RUN set -eux; \
104+
export $( $binaryUpper )_VERSION="$( $o['version'] )"; \
105+
case "`$( uname -m )" in \
106+
107+
"@
108+
foreach ($a in ($o['architectures'] -split ',') ) {
109+
$split = $a -split '/'
110+
$os = $split[0]
111+
$arch = $split[1]
112+
$archv = if ($split.Count -gt 2) { $split[2] } else { '' }
113+
switch ($a) {
114+
"$os/386" {
115+
$regex = "$os[-_](i?$arch|x86)[-_]?$archv$( [regex]::Escape($o['archiveformat']) )$"
116+
$hardware = 'x86'
117+
}
118+
"$os/amd64" {
119+
$regex = "$os[-_]($arch|x86_64)[-_]?$archv$( [regex]::Escape($o['archiveformat']) )$"
120+
$hardware = 'x86_64'
121+
}
122+
"$os/arm/v6" {
123+
$regex = "$os[-_]($arch|arm)[-_]?($archv)?$( [regex]::Escape($o['archiveformat']) )$"
124+
$hardware = 'armhf'
125+
}
126+
"$os/arm/v7" {
127+
$regex = "$os[-_]($arch|arm)[-_]?($archv)?$( [regex]::Escape($o['archiveformat']) )$"
128+
$hardware = 'armv7l'
129+
}
130+
"$os/arm64" {
131+
$regex = "$os[-_]($arch|aarch64)[-_]?$archv$( [regex]::Escape($o['archiveformat']) )$"
132+
$hardware = 'aarch64'
133+
}
134+
"$os/ppc64le" {
135+
$regex = "$os[-_]$arch[-_]?$archv$( [regex]::Escape($o['archiveformat']) )$"
136+
$hardware = 'ppc64le'
137+
}
138+
"$os/riscv64" {
139+
$regex = "$os[-_]$arch[-_]?$archv$( [regex]::Escape($o['archiveformat']) )$"
140+
$hardware = 'riscv64'
141+
}
142+
"$os/s390x" {
143+
$regex = "$os[-_]$arch[-_]?$archv$( [regex]::Escape($o['archiveformat']) )$"
144+
$hardware = 's390x'
145+
}
146+
default {
147+
throw "Unsupported architecture: $a"
148+
}
149+
}
150+
151+
@"
152+
'$hardware') \
153+
URL=$releaseUrl/$( Get-ChecksumsFile $o['binary'] $regex ); \
154+
SHA256=$( Get-ChecksumsSha $o['binary'] $regex ); \
155+
;; \
156+
157+
"@
158+
}
159+
160+
@"
161+
*) \
162+
echo "Architecture not supported"; \
163+
exit 1; \
164+
;; \
165+
esac; \
166+
167+
"@
168+
169+
@"
170+
FILE=$( $o['binary'] )$( $o['archiveformat'] ); \
171+
wget -q "`$URL" -O "`$FILE"; \
172+
echo "`$SHA256 `$FILE" | sha256sum -c -; \
173+
174+
"@
175+
176+
177+
if ($o['archiveformat'] -match '\.tar\.gz|\.tgz') {
178+
if ($o['archivefiles'].Count -gt 0) {
179+
@"
180+
tar -xvf "`$FILE" --no-same-owner --no-same-permissions -- $( $o['archivefiles'] -join ' ' ); \
181+
rm -f "`$FILE"; \
182+
183+
"@
184+
}else {
185+
@"
186+
tar -xvf "`$FILE" --no-same-owner --no-same-permissions; \
187+
rm -f "`$FILE"; \
188+
189+
"@
190+
}
191+
}elseif ($o['archiveformat'] -match '\.bz2') {
192+
@"
193+
bzip2 -d "`$FILE"; \
194+
195+
"@
196+
}elseif ($o['archiveformat'] -match '\.gz') {
197+
@"
198+
gzip -d "`$FILE"; \
199+
200+
"@
201+
}else {
202+
throw "Invalid 'archiveformat'. Supported formats: .tar.gz, .tgz, .bz2, .gz"
203+
}
204+
205+
@"
206+
mv -v $( $o['binary'] ) /usr/local/bin/$( $o['binary'] ); \
207+
chmod +x /usr/local/bin/$( $o['binary'] ); \
208+
$( $o['binary'] ) $( $o['versionSubcommand'] ); \
209+
210+
"@
211+
212+
if ($o.Contains('archivefiles')) {
213+
if ($license = $o['archivefiles'] | ? { $_ -match 'LICENSE' }) {
214+
@"
215+
mkdir -p /licenses; \
216+
mv -v $license /licenses/$license; \
217+
218+
"@
219+
}
220+
}
221+
222+
@"
223+
:
224+
225+
226+
"@
227+
}

generate/templates/Dockerfile.ps1

Lines changed: 22 additions & 48 deletions
Original file line numberDiff line numberDiff line change
@@ -32,57 +32,31 @@ RUN set -eux; \
3232

3333
foreach ($c in $VARIANT['_metadata']['components']) {
3434
if ($c -eq 'pingme') {
35-
@'
36-
# Install pingme
37-
RUN set -eux; \
38-
export PINGME_VERSION="0.2.5"; \
39-
OS=$( uname -o ); \
40-
# The naming conventions of the binaries is not consistent, hence the need for ARCH workaround
41-
ARCH=$( \
42-
if [ "$TARGETARCH" = 'amd64' ]; then \
43-
uname -m; \
44-
elif [ "$TARGETARCH" = '386' ]; then \
45-
echo "i$TARGETARCH"; \
46-
else \
47-
echo "$TARGETARCH"; \
48-
fi; \
49-
); \
50-
FILE=pingme_${OS}_${ARCH}${TARGETVARIANT}.tar.gz; \
51-
wget https://github.com/kha7iq/pingme/releases/download/v$PINGME_VERSION/pingme_checksums.txt; \
52-
wget -q https://github.com/kha7iq/pingme/releases/download/v${PINGME_VERSION}/$FILE; \
53-
cat pingme_checksums.txt | grep "$FILE" | sha256sum -c -; \
54-
tar -xvf "$FILE" -- pingme LICENSE.md; \
55-
chmod +x pingme; \
56-
mv pingme /usr/local/bin/pingme; \
57-
mv LICENSE.md /usr/local/bin/pingme.LICENSE; \
58-
pingme --version | grep "$PINGME_VERSION"; \
59-
rm -f pingme_checksums.txt; \
60-
rm -f "$FILE";
61-
62-
63-
'@
35+
Generate-DownloadBinary @{
36+
project = 'github.com/kha7iq/pingme'
37+
version = 'v0.2.5'
38+
binary = 'pingme'
39+
archiveformat = '.tar.gz'
40+
archivefiles = @(
41+
'pingme'
42+
'LICENSE.md'
43+
)
44+
checksums = 'pingme_checksums.txt'
45+
architectures = $VARIANT['_metadata']['platforms']
46+
versionSubcommand = '--version'
47+
}
6448
}
6549

6650
if ($c -eq 'restic') {
67-
@'
68-
# Install restic
69-
# These packages are needed for all restic features to work. See: https://github.com/restic/restic/blob/0.15.1/docker/Dockerfile
70-
RUN apk add --update --no-cache ca-certificates fuse openssh-client tzdata jq
71-
RUN set -eux; \
72-
RESTIC_VERSION=0.15.1; \
73-
FILE=restic_${RESTIC_VERSION}_${TARGETOS}_${TARGETARCH}.bz2; \
74-
wget -q https://github.com/restic/restic/releases/download/v${RESTIC_VERSION}/$FILE; \
75-
wget -q https://github.com/restic/restic/releases/download/v${RESTIC_VERSION}/SHA256SUMS; \
76-
SHA=$( sha256sum "$FILE" ); \
77-
cat SHA256SUMS | grep "$FILE" | sha256sum -c -; \
78-
rm -f SHA256SUMS; \
79-
bzip2 -d "$FILE"; \
80-
mv restic_${RESTIC_VERSION}_${TARGETOS}_${TARGETARCH} /usr/local/bin/restic; \
81-
chmod +x /usr/local/bin/restic; \
82-
restic version | grep "^restic $RESTIC_VERSION";
83-
84-
85-
'@
51+
Generate-DownloadBinary @{
52+
project = 'github.com/restic/restic'
53+
version = 'v0.15.1'
54+
binary = 'restic'
55+
archiveformat = '.bz2'
56+
checksums = 'SHA256SUMS'
57+
architectures = $VARIANT['_metadata']['platforms']
58+
versionSubcommand = 'version'
59+
}
8660
}
8761
}
8862

variants/1.4.4-pingme/Dockerfile

Lines changed: 34 additions & 23 deletions
Original file line numberDiff line numberDiff line change
@@ -28,29 +28,40 @@ RUN set -eux; \
2828

2929
# Install pingme
3030
RUN set -eux; \
31-
export PINGME_VERSION="0.2.5"; \
32-
OS=$( uname -o ); \
33-
# The naming conventions of the binaries is not consistent, hence the need for ARCH workaround
34-
ARCH=$( \
35-
if [ "$TARGETARCH" = 'amd64' ]; then \
36-
uname -m; \
37-
elif [ "$TARGETARCH" = '386' ]; then \
38-
echo "i$TARGETARCH"; \
39-
else \
40-
echo "$TARGETARCH"; \
41-
fi; \
42-
); \
43-
FILE=pingme_${OS}_${ARCH}${TARGETVARIANT}.tar.gz; \
44-
wget https://github.com/kha7iq/pingme/releases/download/v$PINGME_VERSION/pingme_checksums.txt; \
45-
wget -q https://github.com/kha7iq/pingme/releases/download/v${PINGME_VERSION}/$FILE; \
46-
cat pingme_checksums.txt | grep "$FILE" | sha256sum -c -; \
47-
tar -xvf "$FILE" -- pingme LICENSE.md; \
48-
chmod +x pingme; \
49-
mv pingme /usr/local/bin/pingme; \
50-
mv LICENSE.md /usr/local/bin/pingme.LICENSE; \
51-
pingme --version | grep "$PINGME_VERSION"; \
52-
rm -f pingme_checksums.txt; \
53-
rm -f "$FILE";
31+
export PINGME_VERSION="v0.2.5"; \
32+
case "$( uname -m )" in \
33+
'x86') \
34+
URL=https://github.com/kha7iq/pingme/releases/download/v0.2.5/pingme_Linux_i386.tar.gz; \
35+
SHA256=5a14e80693800284f11daf7d5ba71a7cbe78e18948579584f36069d7a2f31d4a; \
36+
;; \
37+
'x86_64') \
38+
URL=https://github.com/kha7iq/pingme/releases/download/v0.2.5/pingme_Linux_x86_64.tar.gz; \
39+
SHA256=93133b9c978d5a579526261255c2a7a9ca6dfc5ab42ef65e1de4fab15d8ac808; \
40+
;; \
41+
'armv7l') \
42+
URL=https://github.com/kha7iq/pingme/releases/download/v0.2.5/pingme_Linux_armv7.tar.gz; \
43+
SHA256=6f26a3926e6ed038ca132b4d1985cd2f6c0ccf037fbc78f710bdc2cc76b3fc5a; \
44+
;; \
45+
'aarch64') \
46+
URL=https://github.com/kha7iq/pingme/releases/download/v0.2.5/pingme_Linux_arm64.tar.gz; \
47+
SHA256=496bb93402611d5710bc66b26f64f13fc0f888d0b3cc1f4d7960c7c631860dd3; \
48+
;; \
49+
*) \
50+
echo "Architecture not supported"; \
51+
exit 1; \
52+
;; \
53+
esac; \
54+
FILE=pingme.tar.gz; \
55+
wget -q "$URL" -O "$FILE"; \
56+
echo "$SHA256 $FILE" | sha256sum -c -; \
57+
tar -xvf "$FILE" --no-same-owner --no-same-permissions -- pingme LICENSE.md; \
58+
rm -f "$FILE"; \
59+
mv -v pingme /usr/local/bin/pingme; \
60+
chmod +x /usr/local/bin/pingme; \
61+
pingme --version; \
62+
mkdir -p /licenses; \
63+
mv -v LICENSE.md /licenses/LICENSE.md; \
64+
:
5465

5566
# Install notification tools
5667
RUN apk add --no-cache curl jq

0 commit comments

Comments
 (0)