Skip to content

Commit 2cb9141

Browse files
authored
Merge pull request #34 from dokku-community/fix-package-building
fix: use new triggers for image cache management
2 parents 314e6d2 + 97602e3 commit 2cb9141

4 files changed

+214
-97
lines changed

builder-create-dokku-image

+63
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,63 @@
1+
#!/usr/bin/env bash
2+
set -eo pipefail
3+
[[ $DOKKU_TRACE ]] && set -x
4+
export DOCKER_BIN=${DOCKER_BIN:="docker"}
5+
source "$PLUGIN_CORE_AVAILABLE_PATH/common/functions"
6+
source "$PLUGIN_AVAILABLE_PATH/apt/internal-functions"
7+
8+
hook-apt-builder-create-dokku-image() {
9+
declare BUILDER_TYPE="$1" APP="$2" SOURCECODE_WORK_DIR="$3" DOKKU_IMAGE="$4"
10+
local IMAGE="dokku/$APP" DIR=/tmp/apt
11+
local COMMAND CONTENT_SHA DOCKER_COMMIT_LABEL_ARGS DOCKER_RUN_LABEL_ARGS
12+
13+
if [[ -f "$SOURCECODE_WORK_DIR/dpkg-packages" ]]; then
14+
dokku_log_info1 "Rebuilding extended app image due to dpkg-packages usage"
15+
return
16+
fi
17+
18+
CONTENT_SHA="$(fn-apt-fetch-sha "$SOURCECODE_WORK_DIR")"
19+
if [[ -z "$CONTENT_SHA" ]]; then
20+
return
21+
fi
22+
23+
local TMP_WORK_DIR=$(mktemp -d "/tmp/dokku-${DOKKU_PID}-${FUNCNAME[0]}.XXXXXX")
24+
trap "rm -rf '$TMP_WORK_DIR' >/dev/null" RETURN
25+
fn-apt-populate-work-dir "$SOURCECODE_WORK_DIR" "$TMP_WORK_DIR"
26+
27+
if [[ "$("$DOCKER_BIN" images --quiet "dokku/$APP:$CONTENT_SHA" 2>/dev/null)" != "" ]]; then
28+
dokku_log_info1 "Compatible extended app image found, skipping system package installation"
29+
fn-clean-extended-app-images "$APP" "dokku/$APP:$CONTENT_SHA"
30+
return
31+
fi
32+
33+
dokku_log_info1 "Creating extended app image with custom system packages"
34+
pushd "$TMP_WORK_DIR" >/dev/null
35+
CID=$(tar -c . | "$DOCKER_BIN" run "${DOCKER_RUN_LABEL_ARGS[@]}" $DOKKU_GLOBAL_RUN_ARGS -i -a stdin "$DOKKU_IMAGE" /bin/bash -c "mkdir -p /tmp/apt && tar -xC /tmp/apt")
36+
popd >/dev/null
37+
if test "$("$DOCKER_BIN" wait "$CID")" -ne 0; then
38+
dokku_log_warn "Failure extracting apt files"
39+
return 1
40+
fi
41+
42+
DOCKER_COMMIT_LABEL_ARGS=("--change" "LABEL org.label-schema.schema-version=1.0" "--change" "LABEL org.label-schema.vendor=dokku" "--change" "LABEL com.dokku.app-name=$APP" "--change" "LABEL $DOKKU_CONTAINER_LABEL=")
43+
"$DOCKER_BIN" commit "${DOCKER_COMMIT_LABEL_ARGS[@]}" "$CID" "$IMAGE:apt" >/dev/null
44+
"$DOCKER_BIN" rm "$CID" &>/dev/null || true
45+
46+
COMMAND="$(fn-apt-command "$APP" "$DOKKU_IMAGE" "/tmp/apt")"
47+
DOCKER_RUN_LABEL_ARGS="--label=com.dokku.app-name=$APP"
48+
CID=$("$DOCKER_BIN" run "${DOCKER_RUN_LABEL_ARGS[@]}" $DOKKU_GLOBAL_RUN_ARGS -d "$IMAGE:apt" /bin/bash -e -c "$COMMAND")
49+
50+
"$DOCKER_BIN" attach "$CID"
51+
if test "$("$DOCKER_BIN" wait "$CID")" -ne 0; then
52+
dokku_log_warn "Failure installing system packages"
53+
return 1
54+
fi
55+
56+
DOCKER_COMMIT_LABEL_ARGS=("--change" "LABEL org.label-schema.schema-version=1.0" "--change" "LABEL org.label-schema.vendor=dokku" "--change" "LABEL com.dokku.app-name=sha-$APP" "--change" "LABEL $DOKKU_CONTAINER_LABEL=")
57+
"$DOCKER_BIN" commit "${DOCKER_COMMIT_LABEL_ARGS[@]}" "$CID" "dokku/$APP:$CONTENT_SHA" >/dev/null
58+
"$DOCKER_BIN" rm "$CID" &>/dev/null || true
59+
"$DOCKER_BIN" rmi "$IMAGE:apt" &>/dev/null || true
60+
fn-clean-extended-app-images "$APP" "dokku/$APP:$CONTENT_SHA"
61+
}
62+
63+
hook-apt-builder-create-dokku-image "$@"

builder-dokku-image

+27
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,27 @@
1+
#!/usr/bin/env bash
2+
set -eo pipefail
3+
[[ $DOKKU_TRACE ]] && set -x
4+
export DOCKER_BIN=${DOCKER_BIN:="docker"}
5+
source "$PLUGIN_AVAILABLE_PATH/apt/internal-functions"
6+
7+
hook-apt-builder-dokku-image() {
8+
declare BUILDER_TYPE="$1" APP="$2" SOURCECODE_WORK_DIR="$3"
9+
local IMAGE="dokku/$APP"
10+
local CONTENT_SHA
11+
12+
if [[ -f "$SOURCECODE_WORK_DIR/dpkg-packages" ]]; then
13+
return
14+
fi
15+
16+
CONTENT_SHA="$(fn-apt-fetch-sha "$SOURCECODE_WORK_DIR")"
17+
if [[ -z "$CONTENT_SHA" ]]; then
18+
return
19+
fi
20+
21+
if [[ "$("$DOCKER_BIN" images --quiet "$IMAGE:$CONTENT_SHA" 2>/dev/null)" != "" ]]; then
22+
echo "$IMAGE:$CONTENT_SHA"
23+
return
24+
fi
25+
}
26+
27+
hook-apt-builder-dokku-image "$@"

internal-functions

+111
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,111 @@
1+
#!/usr/bin/env bash
2+
set -eo pipefail
3+
[[ $DOKKU_TRACE ]] && set -x
4+
export DOCKER_BIN=${DOCKER_BIN:="docker"}
5+
source "$PLUGIN_CORE_AVAILABLE_PATH/common/functions"
6+
7+
fn-clean-extended-app-images() {
8+
declare APP="$1" IMAGE="$2"
9+
local images
10+
11+
# remove dangling extended app images
12+
"$DOCKER_BIN" rmi $("$DOCKER_BIN" images --format 'dangling=true' --format "label=com.dokku.app-name=sha-$APP" --quiet) &>/dev/null || true
13+
14+
images="$("$DOCKER_BIN" images --filter "label=com.dokku.app-name=sha-$APP" --quiet)"
15+
for image in $images; do
16+
if [[ "$("$DOCKER_BIN" inspect --format '{{(index .RepoTags 0)}}' "$image" 2>/dev/null)" != "$IMAGE" ]]; then
17+
"$DOCKER_BIN" rmi "$image" &>/dev/null || true
18+
fi
19+
done
20+
}
21+
22+
fn-apt-fetch-sha() {
23+
declare SOURCECODE_WORK_DIR="$1"
24+
local APT_FILES CONTENT INJECT_PACKAGES file
25+
26+
if [[ -f "$SOURCECODE_WORK_DIR/dpkg-packages" ]]; then
27+
return
28+
fi
29+
30+
APT_FILES=('apt-env' 'apt-preferences' 'apt-sources-list' 'apt-repositories' 'apt-debconf' 'apt-packages')
31+
for file in "${APT_FILES[@]}"; do
32+
if [[ -f "$SOURCECODE_WORK_DIR/$file" ]]; then
33+
INJECT_PACKAGES=true
34+
local file_contents=$(<$SOURCECODE_WORK_DIR/$file)
35+
CONTENT="${CONTENT}\n${file}\n${file_contents}"
36+
fi
37+
done
38+
39+
if [[ "$INJECT_PACKAGES" != "true" ]]; then
40+
return
41+
fi
42+
43+
echo -n "$(<$PLUGIN_AVAILABLE_PATH/apt/plugin.toml)$CONTENT" | sha256sum | cut -d " " -f 1
44+
}
45+
46+
fn-apt-populate-work-dir() {
47+
declare SOURCECODE_WORK_DIR="$1" TMP_WORK_DIR="$2"
48+
local APT_FILES file
49+
50+
APT_FILES=('apt-env' 'apt-preferences' 'apt-sources-list' 'apt-repositories' 'apt-debconf' 'apt-packages')
51+
for file in "${APT_FILES[@]}"; do
52+
if [[ -f "$SOURCECODE_WORK_DIR/$file" ]]; then
53+
cp "$SOURCECODE_WORK_DIR/$file" "$TMP_WORK_DIR/$file"
54+
fi
55+
done
56+
}
57+
58+
fn-apt-command() {
59+
declare APP="$1" DOKKU_IMAGE="$2" DIR="$3"
60+
cat <<EOF
61+
# $APP $DOKKU_IMAGE
62+
sleep 2
63+
export DEBIAN_FRONTEND=noninteractive
64+
if [ -f $DIR/apt-env ]; then
65+
echo "-----> Sourcing apt env"
66+
source $DIR/apt-env
67+
fi
68+
if [ -d $DIR/apt-preferences ]; then
69+
echo "-----> Injecting apt preferences"
70+
mv -v $DIR/apt-preferences /etc/apt/preferences.d/90customizations
71+
fi
72+
if [ -f $DIR/apt-sources-list ]; then
73+
echo "-----> Using customized sources.list"
74+
mv -v $DIR/apt-sources-list /etc/apt/sources.list
75+
fi
76+
if [ -f $DIR/apt-repositories ]; then
77+
echo "-----> Updating package list"
78+
apt-get update >/dev/null
79+
echo "-----> Installing required apt transport packages"
80+
apt-get install -y software-properties-common apt-transport-https
81+
echo "-----> Installing custom apt repositories"
82+
cat "$DIR/apt-repositories" | while read repository; do
83+
if [ -n "\$repository" ]; then
84+
add-apt-repository -y "\$repository"
85+
fi
86+
done
87+
fi
88+
if [ -f $DIR/apt-debconf ]; then
89+
cat "$DIR/apt-debconf" | while read conf; do
90+
if [ -n "\$conf" ]; then
91+
echo \$conf | debconf-set-selections
92+
fi
93+
done
94+
fi
95+
if [ -f $DIR/apt-packages ]; then
96+
PACKAGES=\$(cat "$DIR/apt-packages" | tr "\\n" " ")
97+
echo "-----> Updating package list"
98+
apt-get update >/dev/null
99+
echo "-----> Injecting packages: \$PACKAGES"
100+
apt-get install -y \$PACKAGES
101+
fi
102+
if [ -d $DIR/dpkg-packages ]; then
103+
for pkg in $DIR/dpkg-packages/*.deb; do
104+
echo "-----> Injecting package: \$pkg"
105+
dpkg -i \$pkg
106+
done
107+
fi
108+
rm -rf /tmp/apt
109+
sleep 1 # wait so that docker run has not exited before docker attach
110+
EOF
111+
}

pre-build-buildpack

+13-97
Original file line numberDiff line numberDiff line change
@@ -3,122 +3,38 @@ set -eo pipefail
33
[[ $DOKKU_TRACE ]] && set -x
44
export DOCKER_BIN=${DOCKER_BIN:="docker"}
55
source "$PLUGIN_CORE_AVAILABLE_PATH/common/functions"
6-
7-
fn-clean-extended-app-images() {
8-
declare APP="$1" IMAGE="$2"
9-
local images
10-
11-
# remove dangling extended app images
12-
"$DOCKER_BIN" rmi $("$DOCKER_BIN" images --format 'dangling=true' --format "label=com.dokku.app-name=sha-$APP" --quiet) &>/dev/null || true
13-
14-
images="$("$DOCKER_BIN" images --filter "label=com.dokku.app-name=sha-$APP" --quiet)"
15-
for image in $images; do
16-
if [[ "$("$DOCKER_BIN" inspect --format '{{(index .RepoTags 0)}}' "$image" 2>/dev/null)" != "$IMAGE" ]]; then
17-
"$DOCKER_BIN" rmi "$image" &>/dev/null || true
18-
fi
19-
done
20-
}
6+
source "$PLUGIN_AVAILABLE_PATH/apt/internal-functions"
217

228
hook-apt-pre-build-buildpack() {
239
declare APP="$1" SOURCECODE_WORK_DIR="$2"
2410
local IMAGE="dokku/$APP" DIR=/app
25-
local COMMAND CONTENT CONTENT_SHA INJECT_PACKAGES
11+
local CID COMMAND DOCKER_COMMIT_LABEL_ARGS
2612

2713
if [[ -n "$SOURCECODE_WORK_DIR" ]]; then
2814
pushd "$SOURCECODE_WORK_DIR" >/dev/null
2915
fi
3016

31-
local APT_FILES=('apt-env' 'apt-preferences' 'apt-sources-list' 'apt-repositories' 'apt-debconf' 'apt-packages' 'dpkg-packages')
32-
for file in "${APT_FILES[@]}"; do
33-
if [[ -f "$file" ]]; then
34-
INJECT_PACKAGES=true
35-
local file_contents=$(<$file)
36-
CONTENT="${CONTENT}\n${file}\n${file_contents}"
37-
if [[ "$file" == "dpkg-packages" ]]; then
38-
CONTENT="${CONTENT}$(date +%s)"
39-
fi
40-
fi
41-
done
17+
if [[ ! -f "dpkg-packages" ]]; then
18+
return
19+
fi
4220

4321
if [[ -n "$SOURCECODE_WORK_DIR" ]]; then
4422
popd >/dev/null
4523
fi
4624

47-
if [[ "$INJECT_PACKAGES" != "true" ]]; then
48-
return
49-
fi
50-
51-
COMMAND=$(
52-
cat <<EOF
53-
# $APP $IMAGE
54-
sleep 2
55-
export DEBIAN_FRONTEND=noninteractive
56-
if [ -f $DIR/apt-env ]; then
57-
echo "-----> Sourcing apt env"
58-
source $DIR/apt-env
59-
fi
60-
if [ -d $DIR/apt-preferences ]; then
61-
echo "-----> Injecting apt preferences"
62-
mv -v $DIR/apt-preferences /etc/apt/preferences.d/90customizations
63-
fi
64-
if [ -f $DIR/apt-sources-list ]; then
65-
echo "-----> Using customized sources.list"
66-
mv -v $DIR/apt-sources-list /etc/apt/sources.list
67-
fi
68-
if [ -f $DIR/apt-repositories ]; then
69-
echo "-----> Updating package list"
70-
apt-get update >/dev/null
71-
echo "-----> Installing required apt transport packages"
72-
apt-get install -y software-properties-common apt-transport-https
73-
echo "-----> Installing custom apt repositories"
74-
cat "$DIR/apt-repositories" | while read repository; do
75-
if [ -n "\$repository" ]; then
76-
add-apt-repository -y "\$repository"
77-
fi
78-
done
79-
fi
80-
if [ -f $DIR/apt-debconf ]; then
81-
cat "$DIR/apt-debconf" | while read conf; do
82-
if [ -n "\$conf" ]; then
83-
echo \$conf | debconf-set-selections
84-
fi
85-
done
86-
fi
87-
if [ -f $DIR/apt-packages ]; then
88-
PACKAGES=\$(cat "$DIR/apt-packages" | tr "\\n" " ")
89-
echo "-----> Updating package list"
90-
apt-get update >/dev/null
91-
echo "-----> Injecting packages: \$PACKAGES"
92-
apt-get install -y \$PACKAGES
93-
fi
94-
if [ -d $DIR/dpkg-packages ]; then
95-
for pkg in $DIR/dpkg-packages/*.deb; do
96-
echo "-----> Injecting package: \$pkg"
97-
dpkg -i \$pkg
98-
done
99-
fi
100-
sleep 1 # wait so that docker run has not exited before docker attach
101-
EOF
102-
)
25+
dokku_log_info1 "Creating extended app image with custom system packages"
26+
COMMAND="$(fn-apt-command "$APP" "$IMAGE" "$DIR")"
27+
CID=$(docker run -d "$IMAGE" /bin/bash -e -c "$COMMAND")
10328

104-
CONTENT_SHA="$(echo -n "$CONTENT" | sha256sum | cut -d " " -f 1)"
105-
if [[ "$("$DOCKER_BIN" images --quiet "dokku/$APP:$CONTENT_SHA" 2>/dev/null)" != "" ]]; then
106-
dokku_log_info1 "Compatible extended app image found, skipping system package installation"
107-
"$DOCKER_BIN" tag "dokku/$APP:$CONTENT_SHA" "$IMAGE"
108-
fn-clean-extended-app-images "$APP" "dokku/$APP:$CONTENT_SHA"
109-
return
29+
"$DOCKER_BIN" attach "$CID"
30+
if test "$("$DOCKER_BIN" wait "$CID")" -ne 0; then
31+
dokku_log_warn "Failure installing system packages"
32+
return 1
11033
fi
11134

112-
dokku_log_info1 "Extending app image with custom system packages"
113-
CID=$("$DOCKER_BIN" run -d "$IMAGE" /bin/bash -e -c "$COMMAND")
114-
local DOCKER_COMMIT_LABEL_ARGS=("--change" "LABEL org.label-schema.schema-version=1.0" "--change" "LABEL org.label-schema.vendor=dokku" "--change" "LABEL com.dokku.app-name=sha-$APP" "--change" "LABEL $DOKKU_CONTAINER_LABEL=")
115-
116-
"$DOCKER_BIN" attach "$CID"
117-
test "$("$DOCKER_BIN" wait "$CID")" -eq 0
35+
DOCKER_COMMIT_LABEL_ARGS=("--change" "LABEL org.label-schema.schema-version=1.0" "--change" "LABEL org.label-schema.vendor=dokku" "--change" "LABEL com.dokku.app-name=$APP" "--change" "LABEL $DOKKU_CONTAINER_LABEL=")
11836
"$DOCKER_BIN" commit "${DOCKER_COMMIT_LABEL_ARGS[@]}" "$CID" "$IMAGE" >/dev/null
11937
"$DOCKER_BIN" rm "$CID" &>/dev/null || true
120-
"$DOCKER_BIN" tag "$IMAGE" "dokku/$APP:$CONTENT_SHA"
121-
fn-clean-extended-app-images "$APP" "dokku/$APP:$CONTENT_SHA"
12238
}
12339

12440
hook-apt-pre-build-buildpack "$@"

0 commit comments

Comments
 (0)