Skip to content

Commit ee33a21

Browse files
committed
Add initial jq-based templating engine
1 parent aaecc90 commit ee33a21

13 files changed

+337
-72
lines changed

.gitattributes

+3
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,3 @@
1+
/*.*/**/Dockerfile* linguist-generated
2+
/*.*/**/docker-entrypoint.sh linguist-generated
3+
Dockerfile* linguist-language=Dockerfile
+22
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,22 @@
1+
name: Verify Templating
2+
3+
on:
4+
pull_request:
5+
push:
6+
7+
defaults:
8+
run:
9+
shell: 'bash -Eeuo pipefail -x {0}'
10+
11+
jobs:
12+
apply-templates:
13+
name: Check For Uncomitted Changes
14+
runs-on: ubuntu-latest
15+
steps:
16+
- uses: actions/checkout@v2
17+
- name: Apply Templates
18+
run: ./apply-templates.sh
19+
- name: Check Git Status
20+
run: |
21+
status="$(git status --short)"
22+
[ -z "$status" ]

.gitignore

+1
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
.jq-template.awk

5.6/Dockerfile renamed to 5.6/Dockerfile.debian

+16-7
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

5.7/Dockerfile renamed to 5.7/Dockerfile.debian

+16-7
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

8.0/Dockerfile renamed to 8.0/Dockerfile.debian

+13-2
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

apply-templates.sh

+45
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,45 @@
1+
#!/usr/bin/env bash
2+
set -Eeuo pipefail
3+
4+
[ -f versions.json ] # run "versions.sh" first
5+
6+
cd "$(dirname "$(readlink -f "$BASH_SOURCE")")"
7+
8+
jqt='.jq-template.awk'
9+
if [ -n "${BASHBREW_SCRIPTS:-}" ]; then
10+
jqt="$BASHBREW_SCRIPTS/jq-template.awk"
11+
elif [ "$BASH_SOURCE" -nt "$jqt" ]; then
12+
wget -qO "$jqt" 'https://github.com/docker-library/bashbrew/raw/5f0c26381fb7cc78b2d217d58007800bdcfbcfa1/scripts/jq-template.awk'
13+
fi
14+
15+
if [ "$#" -eq 0 ]; then
16+
versions="$(jq -r 'keys | map(@sh) | join(" ")' versions.json)"
17+
eval "set -- $versions"
18+
fi
19+
20+
generated_warning() {
21+
cat <<-EOH
22+
#
23+
# NOTE: THIS DOCKERFILE IS GENERATED VIA "apply-templates.sh"
24+
#
25+
# PLEASE DO NOT EDIT IT DIRECTLY.
26+
#
27+
28+
EOH
29+
}
30+
31+
for version; do
32+
export version
33+
34+
debianVersion="$(jq -r '.[env.version].debian // ""' versions.json)"
35+
if [ -n "$debianVersion" ]; then
36+
dockerfile='Dockerfile.debian'
37+
38+
{
39+
generated_warning
40+
gawk -f "$jqt" "template/$dockerfile"
41+
} > "$version/$dockerfile"
42+
fi
43+
44+
cp -a template/docker-entrypoint.sh "$version/docker-entrypoint.sh"
45+
done

generate-stackbrew-library.sh

+20-13
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
1-
#!/bin/bash
2-
set -eu
1+
#!/usr/bin/env bash
2+
set -Eeuo pipefail
33

44
declare -A aliases=(
55
[5.7]='5'
@@ -9,31 +9,35 @@ declare -A aliases=(
99
self="$(basename "$BASH_SOURCE")"
1010
cd "$(dirname "$(readlink -f "$BASH_SOURCE")")"
1111

12-
versions=( */ )
13-
versions=( "${versions[@]%/}" )
12+
if [ "$#" -eq 0 ]; then
13+
versions="$(jq -r 'keys | map(@sh) | join(" ")' versions.json)"
14+
eval "set -- $versions"
15+
fi
1416

1517
# sort version numbers with highest first
16-
IFS=$'\n'; versions=( $(echo "${versions[*]}" | sort -rV) ); unset IFS
18+
IFS=$'\n'; set -- $(sort -rV <<<"$*"); unset IFS
1719

1820
# get the most recent commit which modified any of "$@"
1921
fileCommit() {
2022
git log -1 --format='format:%H' HEAD -- "$@"
2123
}
2224

23-
# get the most recent commit which modified "$1/Dockerfile" or any file COPY'd from "$1/Dockerfile"
25+
# get the most recent commit which modified "dir/dockerfile" or any file COPY'd from it
2426
dirCommit() {
2527
local dir="$1"; shift
28+
local df="$1"; shift
2629
(
2730
cd "$dir"
28-
fileCommit \
29-
Dockerfile \
30-
$(git show HEAD:./Dockerfile | awk '
31+
local files; files="$(
32+
git show "HEAD:./$df" | awk '
3133
toupper($1) == "COPY" {
3234
for (i = 2; i < NF; i++) {
3335
print $i
3436
}
3537
}
36-
')
38+
'
39+
)"
40+
fileCommit "$df" $files
3741
)
3842
}
3943

@@ -52,10 +56,12 @@ join() {
5256
echo "${out#$sep}"
5357
}
5458

55-
for version in "${versions[@]}"; do
56-
commit="$(dirCommit "$version")"
59+
for version; do
60+
export version
61+
df='Dockerfile.debian'
62+
commit="$(dirCommit "$version" "$df")"
5763

58-
fullVersion="$(git show "$commit":"$version/Dockerfile" | awk '$1 == "ENV" && $2 == "MYSQL_VERSION" { gsub(/-[0-9].*$/, "", $3); print $3; exit }')"
64+
fullVersion="$(jq -r '.[env.version].version' versions.json)"
5965

6066
versionAliases=()
6167
while [ "$fullVersion" != "$version" -a "${fullVersion%[.-]*}" != "$fullVersion" ]; do
@@ -72,5 +78,6 @@ for version in "${versions[@]}"; do
7278
Tags: $(join ', ' "${versionAliases[@]}")
7379
GitCommit: $commit
7480
Directory: $version
81+
File: $df
7582
EOE
7683
done

template/Dockerfile.debian

+110
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,110 @@
1+
FROM debian:{{ .debian.suite }}-slim
2+
3+
# add our user and group first to make sure their IDs get assigned consistently, regardless of whatever dependencies get added
4+
RUN groupadd -r mysql && useradd -r -g mysql mysql
5+
6+
RUN apt-get update && apt-get install -y --no-install-recommends gnupg dirmngr && rm -rf /var/lib/apt/lists/*
7+
8+
# add gosu for easy step-down from root
9+
# https://github.com/tianon/gosu/releases
10+
ENV GOSU_VERSION 1.12
11+
RUN set -eux; \
12+
savedAptMark="$(apt-mark showmanual)"; \
13+
apt-get update; \
14+
apt-get install -y --no-install-recommends ca-certificates wget; \
15+
rm -rf /var/lib/apt/lists/*; \
16+
dpkgArch="$(dpkg --print-architecture | awk -F- '{ print $NF }')"; \
17+
wget -O /usr/local/bin/gosu "https://github.com/tianon/gosu/releases/download/$GOSU_VERSION/gosu-$dpkgArch"; \
18+
wget -O /usr/local/bin/gosu.asc "https://github.com/tianon/gosu/releases/download/$GOSU_VERSION/gosu-$dpkgArch.asc"; \
19+
export GNUPGHOME="$(mktemp -d)"; \
20+
gpg --batch --keyserver hkps://keys.openpgp.org --recv-keys B42F6819007F00F88E364FD4036A9C25BF357DD4; \
21+
gpg --batch --verify /usr/local/bin/gosu.asc /usr/local/bin/gosu; \
22+
gpgconf --kill all; \
23+
rm -rf "$GNUPGHOME" /usr/local/bin/gosu.asc; \
24+
apt-mark auto '.*' > /dev/null; \
25+
[ -z "$savedAptMark" ] || apt-mark manual $savedAptMark > /dev/null; \
26+
apt-get purge -y --auto-remove -o APT::AutoRemove::RecommendsImportant=false; \
27+
chmod +x /usr/local/bin/gosu; \
28+
gosu --version; \
29+
gosu nobody true
30+
31+
RUN mkdir /docker-entrypoint-initdb.d
32+
33+
RUN apt-get update && apt-get install -y --no-install-recommends \
34+
# for MYSQL_RANDOM_ROOT_PASSWORD
35+
pwgen \
36+
{{
37+
if env.version != "5.6" then (
38+
-}}
39+
# for mysql_ssl_rsa_setup
40+
openssl \
41+
{{ ) else "" end -}}
42+
# FATAL ERROR: please install the following Perl modules before executing /usr/local/mysql/scripts/mysql_install_db:
43+
# File::Basename
44+
# File::Copy
45+
# Sys::Hostname
46+
# Data::Dumper
47+
perl \
48+
# install "xz-utils" for .sql.xz docker-entrypoint-initdb.d files
49+
xz-utils \
50+
&& rm -rf /var/lib/apt/lists/*
51+
52+
RUN set -ex; \
53+
# gpg: key 5072E1F5: public key "MySQL Release Engineering <[email protected]>" imported
54+
key='A4A9406876FCBD3C456770C88C718D3B5072E1F5'; \
55+
export GNUPGHOME="$(mktemp -d)"; \
56+
gpg --batch --keyserver ha.pool.sks-keyservers.net --recv-keys "$key"; \
57+
gpg --batch --export "$key" > /etc/apt/trusted.gpg.d/mysql.gpg; \
58+
gpgconf --kill all; \
59+
rm -rf "$GNUPGHOME"; \
60+
apt-key list > /dev/null
61+
62+
ENV MYSQL_MAJOR {{ env.version }}
63+
ENV MYSQL_VERSION {{ .debian.version }}
64+
65+
RUN echo 'deb http://repo.mysql.com/apt/debian/ {{ .debian.suite }} mysql-{{ env.version }}' > /etc/apt/sources.list.d/mysql.list
66+
67+
# the "/var/lib/mysql" stuff here is because the mysql-server postinst doesn't have an explicit way to disable the mysql_install_db codepath besides having a database already "configured" (ie, stuff in /var/lib/mysql/mysql)
68+
# also, we set debconf keys to make APT a little quieter
69+
RUN { \
70+
echo mysql-community-server mysql-community-server/data-dir select ''; \
71+
echo mysql-community-server mysql-community-server/root-pass password ''; \
72+
echo mysql-community-server mysql-community-server/re-root-pass password ''; \
73+
echo mysql-community-server mysql-community-server/remove-test-db select false; \
74+
} | debconf-set-selections \
75+
&& apt-get update \
76+
&& apt-get install -y \
77+
{{ if env.version == "5.6" or env.version == "5.7" then ( -}}
78+
mysql-server="${MYSQL_VERSION}" \
79+
# comment out a few problematic configuration values
80+
&& find /etc/mysql/ -name '*.cnf' -print0 \
81+
| xargs -0 grep -lZE '^(bind-address|log)' \
82+
| xargs -rt -0 sed -Ei 's/^(bind-address|log)/#&/' \
83+
# don't reverse lookup hostnames, they are usually another container
84+
&& echo '[mysqld]\nskip-host-cache\nskip-name-resolve' > /etc/mysql/conf.d/docker.cnf \
85+
{{ ) else ( -}}
86+
mysql-community-client="${MYSQL_VERSION}" \
87+
mysql-community-server-core="${MYSQL_VERSION}" \
88+
{{ ) end -}}
89+
&& rm -rf /var/lib/apt/lists/* \
90+
&& rm -rf /var/lib/mysql && mkdir -p /var/lib/mysql /var/run/mysqld \
91+
&& chown -R mysql:mysql /var/lib/mysql /var/run/mysqld \
92+
# ensure that /var/run/mysqld (used for socket and lock files) is writable regardless of the UID our mysqld instance ends up having at runtime
93+
&& chmod 1777 /var/run/mysqld /var/lib/mysql
94+
95+
VOLUME /var/lib/mysql
96+
97+
{{ if env.version != "5.6" and env.version != "5.7" then ( -}}
98+
# Config files
99+
COPY config/ /etc/mysql/
100+
{{ ) else "" end -}}
101+
COPY docker-entrypoint.sh /usr/local/bin/
102+
RUN ln -s usr/local/bin/docker-entrypoint.sh /entrypoint.sh # backwards compat
103+
ENTRYPOINT ["docker-entrypoint.sh"]
104+
105+
{{ if env.version != "5.6" then ( -}}
106+
EXPOSE 3306 33060
107+
{{ ) else ( -}}
108+
EXPOSE 3306
109+
{{ ) end -}}
110+
CMD ["mysqld"]
File renamed without changes.

0 commit comments

Comments
 (0)