Skip to content

Add initial jq-based templating engine #730

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 1 commit into from
Nov 20, 2020
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
3 changes: 3 additions & 0 deletions .gitattributes
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
/*.*/**/Dockerfile* linguist-generated
/*.*/**/docker-entrypoint.sh linguist-generated
Dockerfile* linguist-language=Dockerfile
22 changes: 22 additions & 0 deletions .github/workflows/verify-templating.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,22 @@
name: Verify Templating

on:
pull_request:
push:

defaults:
run:
shell: 'bash -Eeuo pipefail -x {0}'

jobs:
apply-templates:
name: Check For Uncomitted Changes
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v2
- name: Apply Templates
run: ./apply-templates.sh
- name: Check Git Status
run: |
status="$(git status --short)"
[ -z "$status" ]
1 change: 1 addition & 0 deletions .gitignore
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
.jq-template.awk
23 changes: 16 additions & 7 deletions 5.6/Dockerfile → 5.6/Dockerfile.debian

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

23 changes: 16 additions & 7 deletions 5.7/Dockerfile → 5.7/Dockerfile.debian

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

15 changes: 13 additions & 2 deletions 8.0/Dockerfile → 8.0/Dockerfile.debian

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

45 changes: 45 additions & 0 deletions apply-templates.sh
Original file line number Diff line number Diff line change
@@ -0,0 +1,45 @@
#!/usr/bin/env bash
set -Eeuo pipefail

[ -f versions.json ] # run "versions.sh" first

cd "$(dirname "$(readlink -f "$BASH_SOURCE")")"

jqt='.jq-template.awk'
if [ -n "${BASHBREW_SCRIPTS:-}" ]; then
jqt="$BASHBREW_SCRIPTS/jq-template.awk"
elif [ "$BASH_SOURCE" -nt "$jqt" ]; then
wget -qO "$jqt" 'https://github.com/docker-library/bashbrew/raw/5f0c26381fb7cc78b2d217d58007800bdcfbcfa1/scripts/jq-template.awk'
fi

if [ "$#" -eq 0 ]; then
versions="$(jq -r 'keys | map(@sh) | join(" ")' versions.json)"
eval "set -- $versions"
fi

generated_warning() {
cat <<-EOH
#
# NOTE: THIS DOCKERFILE IS GENERATED VIA "apply-templates.sh"
#
# PLEASE DO NOT EDIT IT DIRECTLY.
#

EOH
}

for version; do
export version

debianVersion="$(jq -r '.[env.version].debian // ""' versions.json)"
if [ -n "$debianVersion" ]; then
dockerfile='Dockerfile.debian'

{
generated_warning
gawk -f "$jqt" "template/$dockerfile"
} > "$version/$dockerfile"
fi

cp -a template/docker-entrypoint.sh "$version/docker-entrypoint.sh"
done
33 changes: 20 additions & 13 deletions generate-stackbrew-library.sh
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
#!/bin/bash
set -eu
#!/usr/bin/env bash
set -Eeuo pipefail

declare -A aliases=(
[5.7]='5'
Expand All @@ -9,31 +9,35 @@ declare -A aliases=(
self="$(basename "$BASH_SOURCE")"
cd "$(dirname "$(readlink -f "$BASH_SOURCE")")"

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

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

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

# get the most recent commit which modified "$1/Dockerfile" or any file COPY'd from "$1/Dockerfile"
# get the most recent commit which modified "dir/dockerfile" or any file COPY'd from it
dirCommit() {
local dir="$1"; shift
local df="$1"; shift
(
cd "$dir"
fileCommit \
Dockerfile \
$(git show HEAD:./Dockerfile | awk '
local files; files="$(
git show "HEAD:./$df" | awk '
toupper($1) == "COPY" {
for (i = 2; i < NF; i++) {
print $i
}
}
')
'
)"
fileCommit "$df" $files
)
}

Expand All @@ -52,10 +56,12 @@ join() {
echo "${out#$sep}"
}

for version in "${versions[@]}"; do
commit="$(dirCommit "$version")"
for version; do
export version
df='Dockerfile.debian'
commit="$(dirCommit "$version" "$df")"

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

versionAliases=()
while [ "$fullVersion" != "$version" -a "${fullVersion%[.-]*}" != "$fullVersion" ]; do
Expand All @@ -72,5 +78,6 @@ for version in "${versions[@]}"; do
Tags: $(join ', ' "${versionAliases[@]}")
GitCommit: $commit
Directory: $version
File: $df
EOE
done
110 changes: 110 additions & 0 deletions template/Dockerfile.debian
Original file line number Diff line number Diff line change
@@ -0,0 +1,110 @@
FROM debian:{{ .debian.suite }}-slim

# add our user and group first to make sure their IDs get assigned consistently, regardless of whatever dependencies get added
RUN groupadd -r mysql && useradd -r -g mysql mysql

RUN apt-get update && apt-get install -y --no-install-recommends gnupg dirmngr && rm -rf /var/lib/apt/lists/*

# add gosu for easy step-down from root
# https://github.com/tianon/gosu/releases
ENV GOSU_VERSION 1.12
RUN set -eux; \
savedAptMark="$(apt-mark showmanual)"; \
apt-get update; \
apt-get install -y --no-install-recommends ca-certificates wget; \
rm -rf /var/lib/apt/lists/*; \
dpkgArch="$(dpkg --print-architecture | awk -F- '{ print $NF }')"; \
wget -O /usr/local/bin/gosu "https://github.com/tianon/gosu/releases/download/$GOSU_VERSION/gosu-$dpkgArch"; \
wget -O /usr/local/bin/gosu.asc "https://github.com/tianon/gosu/releases/download/$GOSU_VERSION/gosu-$dpkgArch.asc"; \
export GNUPGHOME="$(mktemp -d)"; \
gpg --batch --keyserver hkps://keys.openpgp.org --recv-keys B42F6819007F00F88E364FD4036A9C25BF357DD4; \
gpg --batch --verify /usr/local/bin/gosu.asc /usr/local/bin/gosu; \
gpgconf --kill all; \
rm -rf "$GNUPGHOME" /usr/local/bin/gosu.asc; \
apt-mark auto '.*' > /dev/null; \
[ -z "$savedAptMark" ] || apt-mark manual $savedAptMark > /dev/null; \
apt-get purge -y --auto-remove -o APT::AutoRemove::RecommendsImportant=false; \
chmod +x /usr/local/bin/gosu; \
gosu --version; \
gosu nobody true

RUN mkdir /docker-entrypoint-initdb.d

RUN apt-get update && apt-get install -y --no-install-recommends \
# for MYSQL_RANDOM_ROOT_PASSWORD
pwgen \
{{
if env.version != "5.6" then (
-}}
# for mysql_ssl_rsa_setup
openssl \
{{ ) else "" end -}}
# FATAL ERROR: please install the following Perl modules before executing /usr/local/mysql/scripts/mysql_install_db:
# File::Basename
# File::Copy
# Sys::Hostname
# Data::Dumper
perl \
# install "xz-utils" for .sql.xz docker-entrypoint-initdb.d files
xz-utils \
&& rm -rf /var/lib/apt/lists/*

RUN set -ex; \
# gpg: key 5072E1F5: public key "MySQL Release Engineering <[email protected]>" imported
key='A4A9406876FCBD3C456770C88C718D3B5072E1F5'; \
export GNUPGHOME="$(mktemp -d)"; \
gpg --batch --keyserver ha.pool.sks-keyservers.net --recv-keys "$key"; \
gpg --batch --export "$key" > /etc/apt/trusted.gpg.d/mysql.gpg; \
gpgconf --kill all; \
rm -rf "$GNUPGHOME"; \
apt-key list > /dev/null

ENV MYSQL_MAJOR {{ env.version }}
ENV MYSQL_VERSION {{ .debian.version }}

RUN echo 'deb http://repo.mysql.com/apt/debian/ {{ .debian.suite }} mysql-{{ env.version }}' > /etc/apt/sources.list.d/mysql.list

# 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)
# also, we set debconf keys to make APT a little quieter
RUN { \
echo mysql-community-server mysql-community-server/data-dir select ''; \
echo mysql-community-server mysql-community-server/root-pass password ''; \
echo mysql-community-server mysql-community-server/re-root-pass password ''; \
echo mysql-community-server mysql-community-server/remove-test-db select false; \
} | debconf-set-selections \
&& apt-get update \
&& apt-get install -y \
{{ if env.version == "5.6" or env.version == "5.7" then ( -}}
mysql-server="${MYSQL_VERSION}" \
# comment out a few problematic configuration values
&& find /etc/mysql/ -name '*.cnf' -print0 \
| xargs -0 grep -lZE '^(bind-address|log)' \
| xargs -rt -0 sed -Ei 's/^(bind-address|log)/#&/' \
# don't reverse lookup hostnames, they are usually another container
&& echo '[mysqld]\nskip-host-cache\nskip-name-resolve' > /etc/mysql/conf.d/docker.cnf \
{{ ) else ( -}}
mysql-community-client="${MYSQL_VERSION}" \
mysql-community-server-core="${MYSQL_VERSION}" \
{{ ) end -}}
&& rm -rf /var/lib/apt/lists/* \
&& rm -rf /var/lib/mysql && mkdir -p /var/lib/mysql /var/run/mysqld \
&& chown -R mysql:mysql /var/lib/mysql /var/run/mysqld \
# 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
&& chmod 1777 /var/run/mysqld /var/lib/mysql

VOLUME /var/lib/mysql

{{ if env.version != "5.6" and env.version != "5.7" then ( -}}
# Config files
COPY config/ /etc/mysql/
{{ ) else "" end -}}
COPY docker-entrypoint.sh /usr/local/bin/
RUN ln -s usr/local/bin/docker-entrypoint.sh /entrypoint.sh # backwards compat
ENTRYPOINT ["docker-entrypoint.sh"]

{{ if env.version != "5.6" then ( -}}
EXPOSE 3306 33060
{{ ) else ( -}}
EXPOSE 3306
{{ ) end -}}
CMD ["mysqld"]
File renamed without changes.
Loading