Skip to content

Commit

Permalink
Merge pull request #21 from theohbrothers/refactor/generate-dockerfil…
Browse files Browse the repository at this point in the history
…es-with-hardcoded-checksums-for-repeatable-builds

Refactor: Generate Dockerfiles with hardcoded checksums for repeatable builds
  • Loading branch information
leojonathanoh authored Apr 19, 2023
2 parents 764296a + 1dbf749 commit 3f3dbb8
Show file tree
Hide file tree
Showing 5 changed files with 305 additions and 116 deletions.
149 changes: 149 additions & 0 deletions generate/definitions/VARIANTS.ps1
Original file line number Diff line number Diff line change
Expand Up @@ -76,3 +76,152 @@ $VARIANTS_SHARED = @{
}
}
}

# Global cache for checksums
$global:CHECKSUMS = @{}
function global:Set-Checksums($k, $url) {
$global:CHECKSUMS[$k] = if ($global:CHECKSUMS[$k]) { $global:CHECKSUMS[$k] } else { [System.Text.Encoding]::UTF8.GetString( (Invoke-WebRequest $url).Content ) -split "`n" }
}
function global:Get-ChecksumsFile ($k, $keyword) {
$global:CHECKSUMS[$k] | ? { $_ -match $keyword } | % { $_ -split "\s" } | Select-Object -Last 1 | % { $_.TrimStart('*') }
}
function global:Get-ChecksumsSha ($k, $keyword) {
$global:CHECKSUMS[$k] | ? { $_ -match $keyword } | % { $_ -split "\s" } | Select-Object -First 1
}

# Global functions
function global:Generate-DownloadBinary ($o) {
Set-StrictMode -Version Latest

$releaseUrl = "https://$( $o['project'] )/releases/download/$( $o['version'] )"
$checksumsUrl = "$releaseUrl/$( $o['checksums'] )"
Set-Checksums $o['binary'] $checksumsUrl

$binaryUpper = $o['binary'].ToUpper()
@"
# Install $( $o['binary'] )
RUN set -eux; \
export $( $binaryUpper )_VERSION="$( $o['version'] )"; \
case "`$( uname -m )" in \
"@
foreach ($a in ($o['architectures'] -split ',') ) {
$split = $a -split '/'
$os = $split[0]
$arch = $split[1]
$archv = if ($split.Count -gt 2) { $split[2] } else { '' }
switch ($a) {
"$os/386" {
$regex = "$os[-_](i?$arch|x86)[-_]?$archv$( [regex]::Escape($o['archiveformat']) )$"
$hardware = 'x86'
}
"$os/amd64" {
$regex = "$os[-_]($arch|x86_64)[-_]?$archv$( [regex]::Escape($o['archiveformat']) )$"
$hardware = 'x86_64'
}
"$os/arm/v6" {
$regex = "$os[-_]($arch|arm)[-_]?($archv)?$( [regex]::Escape($o['archiveformat']) )$"
$hardware = 'armhf'
}
"$os/arm/v7" {
$regex = "$os[-_]($arch|arm)[-_]?($archv)?$( [regex]::Escape($o['archiveformat']) )$"
$hardware = 'armv7l'
}
"$os/arm64" {
$regex = "$os[-_]($arch|aarch64)[-_]?$archv$( [regex]::Escape($o['archiveformat']) )$"
$hardware = 'aarch64'
}
"$os/ppc64le" {
$regex = "$os[-_]$arch[-_]?$archv$( [regex]::Escape($o['archiveformat']) )$"
$hardware = 'ppc64le'
}
"$os/riscv64" {
$regex = "$os[-_]$arch[-_]?$archv$( [regex]::Escape($o['archiveformat']) )$"
$hardware = 'riscv64'
}
"$os/s390x" {
$regex = "$os[-_]$arch[-_]?$archv$( [regex]::Escape($o['archiveformat']) )$"
$hardware = 's390x'
}
default {
throw "Unsupported architecture: $a"
}
}

@"
'$hardware') \
URL=$releaseUrl/$( Get-ChecksumsFile $o['binary'] $regex ); \
SHA256=$( Get-ChecksumsSha $o['binary'] $regex ); \
;; \
"@
}

@"
*) \
echo "Architecture not supported"; \
exit 1; \
;; \
esac; \
"@

@"
FILE=$( $o['binary'] )$( $o['archiveformat'] ); \
wget -q "`$URL" -O "`$FILE"; \
echo "`$SHA256 `$FILE" | sha256sum -c -; \
"@


if ($o['archiveformat'] -match '\.tar\.gz|\.tgz') {
if ($o['archivefiles'].Count -gt 0) {
@"
tar -xvf "`$FILE" --no-same-owner --no-same-permissions -- $( $o['archivefiles'] -join ' ' ); \
rm -f "`$FILE"; \
"@
}else {
@"
tar -xvf "`$FILE" --no-same-owner --no-same-permissions; \
rm -f "`$FILE"; \
"@
}
}elseif ($o['archiveformat'] -match '\.bz2') {
@"
bzip2 -d "`$FILE"; \
"@
}elseif ($o['archiveformat'] -match '\.gz') {
@"
gzip -d "`$FILE"; \
"@
}else {
throw "Invalid 'archiveformat'. Supported formats: .tar.gz, .tgz, .bz2, .gz"
}

@"
mv -v $( $o['binary'] ) /usr/local/bin/$( $o['binary'] ); \
chmod +x /usr/local/bin/$( $o['binary'] ); \
$( $o['binary'] ) $( $o['versionSubcommand'] ); \
"@

if ($o.Contains('archivefiles')) {
if ($license = $o['archivefiles'] | ? { $_ -match 'LICENSE' }) {
@"
mkdir -p /licenses; \
mv -v $license /licenses/$license; \
"@
}
}

@"
:
"@
}
70 changes: 22 additions & 48 deletions generate/templates/Dockerfile.ps1
Original file line number Diff line number Diff line change
Expand Up @@ -32,57 +32,31 @@ RUN set -eux; \

foreach ($c in $VARIANT['_metadata']['components']) {
if ($c -eq 'pingme') {
@'
# Install pingme
RUN set -eux; \
export PINGME_VERSION="0.2.5"; \
OS=$( uname -o ); \
# The naming conventions of the binaries is not consistent, hence the need for ARCH workaround
ARCH=$( \
if [ "$TARGETARCH" = 'amd64' ]; then \
uname -m; \
elif [ "$TARGETARCH" = '386' ]; then \
echo "i$TARGETARCH"; \
else \
echo "$TARGETARCH"; \
fi; \
); \
FILE=pingme_${OS}_${ARCH}${TARGETVARIANT}.tar.gz; \
wget https://github.com/kha7iq/pingme/releases/download/v$PINGME_VERSION/pingme_checksums.txt; \
wget -q https://github.com/kha7iq/pingme/releases/download/v${PINGME_VERSION}/$FILE; \
cat pingme_checksums.txt | grep "$FILE" | sha256sum -c -; \
tar -xvf "$FILE" -- pingme LICENSE.md; \
chmod +x pingme; \
mv pingme /usr/local/bin/pingme; \
mv LICENSE.md /usr/local/bin/pingme.LICENSE; \
pingme --version | grep "$PINGME_VERSION"; \
rm -f pingme_checksums.txt; \
rm -f "$FILE";
'@
Generate-DownloadBinary @{
project = 'github.com/kha7iq/pingme'
version = 'v0.2.5'
binary = 'pingme'
archiveformat = '.tar.gz'
archivefiles = @(
'pingme'
'LICENSE.md'
)
checksums = 'pingme_checksums.txt'
architectures = $VARIANT['_metadata']['platforms']
versionSubcommand = '--version'
}
}

if ($c -eq 'restic') {
@'
# Install restic
# These packages are needed for all restic features to work. See: https://github.com/restic/restic/blob/0.15.1/docker/Dockerfile
RUN apk add --update --no-cache ca-certificates fuse openssh-client tzdata jq
RUN set -eux; \
RESTIC_VERSION=0.15.1; \
FILE=restic_${RESTIC_VERSION}_${TARGETOS}_${TARGETARCH}.bz2; \
wget -q https://github.com/restic/restic/releases/download/v${RESTIC_VERSION}/$FILE; \
wget -q https://github.com/restic/restic/releases/download/v${RESTIC_VERSION}/SHA256SUMS; \
SHA=$( sha256sum "$FILE" ); \
cat SHA256SUMS | grep "$FILE" | sha256sum -c -; \
rm -f SHA256SUMS; \
bzip2 -d "$FILE"; \
mv restic_${RESTIC_VERSION}_${TARGETOS}_${TARGETARCH} /usr/local/bin/restic; \
chmod +x /usr/local/bin/restic; \
restic version | grep "^restic $RESTIC_VERSION";
'@
Generate-DownloadBinary @{
project = 'github.com/restic/restic'
version = 'v0.15.1'
binary = 'restic'
archiveformat = '.bz2'
checksums = 'SHA256SUMS'
architectures = $VARIANT['_metadata']['platforms']
versionSubcommand = 'version'
}
}
}

Expand Down
57 changes: 34 additions & 23 deletions variants/1.4.4-pingme/Dockerfile
Original file line number Diff line number Diff line change
Expand Up @@ -28,29 +28,40 @@ RUN set -eux; \

# Install pingme
RUN set -eux; \
export PINGME_VERSION="0.2.5"; \
OS=$( uname -o ); \
# The naming conventions of the binaries is not consistent, hence the need for ARCH workaround
ARCH=$( \
if [ "$TARGETARCH" = 'amd64' ]; then \
uname -m; \
elif [ "$TARGETARCH" = '386' ]; then \
echo "i$TARGETARCH"; \
else \
echo "$TARGETARCH"; \
fi; \
); \
FILE=pingme_${OS}_${ARCH}${TARGETVARIANT}.tar.gz; \
wget https://github.com/kha7iq/pingme/releases/download/v$PINGME_VERSION/pingme_checksums.txt; \
wget -q https://github.com/kha7iq/pingme/releases/download/v${PINGME_VERSION}/$FILE; \
cat pingme_checksums.txt | grep "$FILE" | sha256sum -c -; \
tar -xvf "$FILE" -- pingme LICENSE.md; \
chmod +x pingme; \
mv pingme /usr/local/bin/pingme; \
mv LICENSE.md /usr/local/bin/pingme.LICENSE; \
pingme --version | grep "$PINGME_VERSION"; \
rm -f pingme_checksums.txt; \
rm -f "$FILE";
export PINGME_VERSION="v0.2.5"; \
case "$( uname -m )" in \
'x86') \
URL=https://github.com/kha7iq/pingme/releases/download/v0.2.5/pingme_Linux_i386.tar.gz; \
SHA256=5a14e80693800284f11daf7d5ba71a7cbe78e18948579584f36069d7a2f31d4a; \
;; \
'x86_64') \
URL=https://github.com/kha7iq/pingme/releases/download/v0.2.5/pingme_Linux_x86_64.tar.gz; \
SHA256=93133b9c978d5a579526261255c2a7a9ca6dfc5ab42ef65e1de4fab15d8ac808; \
;; \
'armv7l') \
URL=https://github.com/kha7iq/pingme/releases/download/v0.2.5/pingme_Linux_armv7.tar.gz; \
SHA256=6f26a3926e6ed038ca132b4d1985cd2f6c0ccf037fbc78f710bdc2cc76b3fc5a; \
;; \
'aarch64') \
URL=https://github.com/kha7iq/pingme/releases/download/v0.2.5/pingme_Linux_arm64.tar.gz; \
SHA256=496bb93402611d5710bc66b26f64f13fc0f888d0b3cc1f4d7960c7c631860dd3; \
;; \
*) \
echo "Architecture not supported"; \
exit 1; \
;; \
esac; \
FILE=pingme.tar.gz; \
wget -q "$URL" -O "$FILE"; \
echo "$SHA256 $FILE" | sha256sum -c -; \
tar -xvf "$FILE" --no-same-owner --no-same-permissions -- pingme LICENSE.md; \
rm -f "$FILE"; \
mv -v pingme /usr/local/bin/pingme; \
chmod +x /usr/local/bin/pingme; \
pingme --version; \
mkdir -p /licenses; \
mv -v LICENSE.md /licenses/LICENSE.md; \
:

# Install notification tools
RUN apk add --no-cache curl jq
Expand Down
Loading

0 comments on commit 3f3dbb8

Please sign in to comment.