Skip to content

Commit

Permalink
mvn-entrypoint: substantial speed-up
Browse files Browse the repository at this point in the history
Copying a reference tree with ca. 7600 files and ~410MiB
currently takes about 47 (!) seconds and thusly delays
container creation substantially.

Rewrite the copying script to address this:
1) by being less verbose in the log file and doing fewer
   parameter expansions, we shave off about 1 second
2) using cp's --reflink=auto we bring this down to about
   42 seconds, in addition to decreasing disk space used
   (where the underlying file system supports this)
3) using find's
   -exec <command> {} +
   syntax, rather than
   -exec <command> {} ;
   we're now at 32 seconds
4) using sh instead of bash, time goes down to about 22
   seconds
5) as a final optimisation, if the target directory is
   empty, we can just copy everything in one go, bringing
   the time down to under 2 seconds.

All of the above numbers are for the debian-slim version,
using alpine linux, step 4) takes about 15 seconds and
the time taken in step 5) doesn't change, as alpine's
busybox cp doesn't support --reflink=auto at the moment.
  • Loading branch information
André Draszik committed Jul 23, 2018
1 parent f581ea0 commit 7b4d1f0
Show file tree
Hide file tree
Showing 14 changed files with 462 additions and 308 deletions.
55 changes: 33 additions & 22 deletions ibmjava-8-alpine/mvn-entrypoint.sh
Original file line number Diff line number Diff line change
@@ -1,39 +1,50 @@
#! /bin/bash -eu

set -o pipefail
#! /bin/sh -eu

# Copy files from /usr/share/maven/ref into ${MAVEN_CONFIG}
# So the initial ~/.m2 is set with expected content.
# Don't override, as this is just a reference setup
copy_reference_file() {
local root="${1}"
local f="${2%/}"
local logfile="${3}"
local rel="${f/${root}/}" # path relative to /usr/share/maven/ref/
echo "$f" >> "$logfile"
echo " $f -> $rel" >> "$logfile"
if [[ ! -e ${MAVEN_CONFIG}/${rel} || $f = *.override ]]
then
echo "copy $rel to ${MAVEN_CONFIG}" >> "$logfile"
mkdir -p "${MAVEN_CONFIG}/$(dirname "${rel}")"
cp -r "${f}" "${MAVEN_CONFIG}/${rel}";
fi;
}

copy_reference_files() {
local log="$MAVEN_CONFIG/copy_reference_file.log"
local ref="/usr/share/maven/ref"

if (sh -c "mkdir -p \"$MAVEN_CONFIG\" && touch \"${log}\"" > /dev/null 2>&1)
then
echo "--- Copying files at $(date)" >> "$log"
find /usr/share/maven/ref/ -type f -exec bash -eu -c 'copy_reference_file /usr/share/maven/ref/ "$1" "$2"' _ {} "$log" \;
if mkdir -p "${MAVEN_CONFIG}/repository" && touch "${log}" > /dev/null 2>&1 ; then
cd "${ref}"
local reflink=""
if cp --help 2>&1 | grep -q reflink ; then
reflink="--reflink=auto"
fi
if [ -n "$(find "${MAVEN_CONFIG}/repository" -maxdepth 0 -type d -empty 2>/dev/null)" ] ; then
# destination is empty...
echo "--- Copying all files to ${MAVEN_CONFIG} at $(date)" >> "${log}"
cp -rv ${reflink} . "${MAVEN_CONFIG}" >> "${log}"
else
# destination is non-empty, copy file-by-file
echo "--- Copying individual files to ${MAVEN_CONFIG} at $(date)" >> "${log}"
find . -type f -exec sh -eu -c '
log="${1}"
shift
reflink="${1}"
shift
for f in "$@" ; do
if [ ! -e "${MAVEN_CONFIG}/${f}" ] || [ -e "${f}.override" ] ; then
mkdir -p "${MAVEN_CONFIG}/$(dirname "${f}")"
cp -rv ${reflink} "${f}" "${MAVEN_CONFIG}/${f}" >> "${log}"
fi
done
' _ "${log}" "${reflink}" {} +
fi
echo >> "${log}"
else
echo "Can not write to ${log}. Wrong volume permissions? Carrying on ..."
fi
}

export -f copy_reference_file
owd="$(pwd)"
copy_reference_files
unset MAVEN_CONFIG

cd "${owd}"
unset owd

exec "$@"
55 changes: 33 additions & 22 deletions ibmjava-8/mvn-entrypoint.sh
Original file line number Diff line number Diff line change
@@ -1,39 +1,50 @@
#! /bin/bash -eu

set -o pipefail
#! /bin/sh -eu

# Copy files from /usr/share/maven/ref into ${MAVEN_CONFIG}
# So the initial ~/.m2 is set with expected content.
# Don't override, as this is just a reference setup
copy_reference_file() {
local root="${1}"
local f="${2%/}"
local logfile="${3}"
local rel="${f/${root}/}" # path relative to /usr/share/maven/ref/
echo "$f" >> "$logfile"
echo " $f -> $rel" >> "$logfile"
if [[ ! -e ${MAVEN_CONFIG}/${rel} || $f = *.override ]]
then
echo "copy $rel to ${MAVEN_CONFIG}" >> "$logfile"
mkdir -p "${MAVEN_CONFIG}/$(dirname "${rel}")"
cp -r "${f}" "${MAVEN_CONFIG}/${rel}";
fi;
}

copy_reference_files() {
local log="$MAVEN_CONFIG/copy_reference_file.log"
local ref="/usr/share/maven/ref"

if (sh -c "mkdir -p \"$MAVEN_CONFIG\" && touch \"${log}\"" > /dev/null 2>&1)
then
echo "--- Copying files at $(date)" >> "$log"
find /usr/share/maven/ref/ -type f -exec bash -eu -c 'copy_reference_file /usr/share/maven/ref/ "$1" "$2"' _ {} "$log" \;
if mkdir -p "${MAVEN_CONFIG}/repository" && touch "${log}" > /dev/null 2>&1 ; then
cd "${ref}"
local reflink=""
if cp --help 2>&1 | grep -q reflink ; then
reflink="--reflink=auto"
fi
if [ -n "$(find "${MAVEN_CONFIG}/repository" -maxdepth 0 -type d -empty 2>/dev/null)" ] ; then
# destination is empty...
echo "--- Copying all files to ${MAVEN_CONFIG} at $(date)" >> "${log}"
cp -rv ${reflink} . "${MAVEN_CONFIG}" >> "${log}"
else
# destination is non-empty, copy file-by-file
echo "--- Copying individual files to ${MAVEN_CONFIG} at $(date)" >> "${log}"
find . -type f -exec sh -eu -c '
log="${1}"
shift
reflink="${1}"
shift
for f in "$@" ; do
if [ ! -e "${MAVEN_CONFIG}/${f}" ] || [ -e "${f}.override" ] ; then
mkdir -p "${MAVEN_CONFIG}/$(dirname "${f}")"
cp -rv ${reflink} "${f}" "${MAVEN_CONFIG}/${f}" >> "${log}"
fi
done
' _ "${log}" "${reflink}" {} +
fi
echo >> "${log}"
else
echo "Can not write to ${log}. Wrong volume permissions? Carrying on ..."
fi
}

export -f copy_reference_file
owd="$(pwd)"
copy_reference_files
unset MAVEN_CONFIG

cd "${owd}"
unset owd

exec "$@"
55 changes: 33 additions & 22 deletions jdk-10-slim/mvn-entrypoint.sh
Original file line number Diff line number Diff line change
@@ -1,39 +1,50 @@
#! /bin/bash -eu

set -o pipefail
#! /bin/sh -eu

# Copy files from /usr/share/maven/ref into ${MAVEN_CONFIG}
# So the initial ~/.m2 is set with expected content.
# Don't override, as this is just a reference setup
copy_reference_file() {
local root="${1}"
local f="${2%/}"
local logfile="${3}"
local rel="${f/${root}/}" # path relative to /usr/share/maven/ref/
echo "$f" >> "$logfile"
echo " $f -> $rel" >> "$logfile"
if [[ ! -e ${MAVEN_CONFIG}/${rel} || $f = *.override ]]
then
echo "copy $rel to ${MAVEN_CONFIG}" >> "$logfile"
mkdir -p "${MAVEN_CONFIG}/$(dirname "${rel}")"
cp -r "${f}" "${MAVEN_CONFIG}/${rel}";
fi;
}

copy_reference_files() {
local log="$MAVEN_CONFIG/copy_reference_file.log"
local ref="/usr/share/maven/ref"

if (sh -c "mkdir -p \"$MAVEN_CONFIG\" && touch \"${log}\"" > /dev/null 2>&1)
then
echo "--- Copying files at $(date)" >> "$log"
find /usr/share/maven/ref/ -type f -exec bash -eu -c 'copy_reference_file /usr/share/maven/ref/ "$1" "$2"' _ {} "$log" \;
if mkdir -p "${MAVEN_CONFIG}/repository" && touch "${log}" > /dev/null 2>&1 ; then
cd "${ref}"
local reflink=""
if cp --help 2>&1 | grep -q reflink ; then
reflink="--reflink=auto"
fi
if [ -n "$(find "${MAVEN_CONFIG}/repository" -maxdepth 0 -type d -empty 2>/dev/null)" ] ; then
# destination is empty...
echo "--- Copying all files to ${MAVEN_CONFIG} at $(date)" >> "${log}"
cp -rv ${reflink} . "${MAVEN_CONFIG}" >> "${log}"
else
# destination is non-empty, copy file-by-file
echo "--- Copying individual files to ${MAVEN_CONFIG} at $(date)" >> "${log}"
find . -type f -exec sh -eu -c '
log="${1}"
shift
reflink="${1}"
shift
for f in "$@" ; do
if [ ! -e "${MAVEN_CONFIG}/${f}" ] || [ -e "${f}.override" ] ; then
mkdir -p "${MAVEN_CONFIG}/$(dirname "${f}")"
cp -rv ${reflink} "${f}" "${MAVEN_CONFIG}/${f}" >> "${log}"
fi
done
' _ "${log}" "${reflink}" {} +
fi
echo >> "${log}"
else
echo "Can not write to ${log}. Wrong volume permissions? Carrying on ..."
fi
}

export -f copy_reference_file
owd="$(pwd)"
copy_reference_files
unset MAVEN_CONFIG

cd "${owd}"
unset owd

exec "$@"
55 changes: 33 additions & 22 deletions jdk-10/mvn-entrypoint.sh
Original file line number Diff line number Diff line change
@@ -1,39 +1,50 @@
#! /bin/bash -eu

set -o pipefail
#! /bin/sh -eu

# Copy files from /usr/share/maven/ref into ${MAVEN_CONFIG}
# So the initial ~/.m2 is set with expected content.
# Don't override, as this is just a reference setup
copy_reference_file() {
local root="${1}"
local f="${2%/}"
local logfile="${3}"
local rel="${f/${root}/}" # path relative to /usr/share/maven/ref/
echo "$f" >> "$logfile"
echo " $f -> $rel" >> "$logfile"
if [[ ! -e ${MAVEN_CONFIG}/${rel} || $f = *.override ]]
then
echo "copy $rel to ${MAVEN_CONFIG}" >> "$logfile"
mkdir -p "${MAVEN_CONFIG}/$(dirname "${rel}")"
cp -r "${f}" "${MAVEN_CONFIG}/${rel}";
fi;
}

copy_reference_files() {
local log="$MAVEN_CONFIG/copy_reference_file.log"
local ref="/usr/share/maven/ref"

if (sh -c "mkdir -p \"$MAVEN_CONFIG\" && touch \"${log}\"" > /dev/null 2>&1)
then
echo "--- Copying files at $(date)" >> "$log"
find /usr/share/maven/ref/ -type f -exec bash -eu -c 'copy_reference_file /usr/share/maven/ref/ "$1" "$2"' _ {} "$log" \;
if mkdir -p "${MAVEN_CONFIG}/repository" && touch "${log}" > /dev/null 2>&1 ; then
cd "${ref}"
local reflink=""
if cp --help 2>&1 | grep -q reflink ; then
reflink="--reflink=auto"
fi
if [ -n "$(find "${MAVEN_CONFIG}/repository" -maxdepth 0 -type d -empty 2>/dev/null)" ] ; then
# destination is empty...
echo "--- Copying all files to ${MAVEN_CONFIG} at $(date)" >> "${log}"
cp -rv ${reflink} . "${MAVEN_CONFIG}" >> "${log}"
else
# destination is non-empty, copy file-by-file
echo "--- Copying individual files to ${MAVEN_CONFIG} at $(date)" >> "${log}"
find . -type f -exec sh -eu -c '
log="${1}"
shift
reflink="${1}"
shift
for f in "$@" ; do
if [ ! -e "${MAVEN_CONFIG}/${f}" ] || [ -e "${f}.override" ] ; then
mkdir -p "${MAVEN_CONFIG}/$(dirname "${f}")"
cp -rv ${reflink} "${f}" "${MAVEN_CONFIG}/${f}" >> "${log}"
fi
done
' _ "${log}" "${reflink}" {} +
fi
echo >> "${log}"
else
echo "Can not write to ${log}. Wrong volume permissions? Carrying on ..."
fi
}

export -f copy_reference_file
owd="$(pwd)"
copy_reference_files
unset MAVEN_CONFIG

cd "${owd}"
unset owd

exec "$@"
55 changes: 33 additions & 22 deletions jdk-11-slim/mvn-entrypoint.sh
Original file line number Diff line number Diff line change
@@ -1,39 +1,50 @@
#! /bin/bash -eu

set -o pipefail
#! /bin/sh -eu

# Copy files from /usr/share/maven/ref into ${MAVEN_CONFIG}
# So the initial ~/.m2 is set with expected content.
# Don't override, as this is just a reference setup
copy_reference_file() {
local root="${1}"
local f="${2%/}"
local logfile="${3}"
local rel="${f/${root}/}" # path relative to /usr/share/maven/ref/
echo "$f" >> "$logfile"
echo " $f -> $rel" >> "$logfile"
if [[ ! -e ${MAVEN_CONFIG}/${rel} || $f = *.override ]]
then
echo "copy $rel to ${MAVEN_CONFIG}" >> "$logfile"
mkdir -p "${MAVEN_CONFIG}/$(dirname "${rel}")"
cp -r "${f}" "${MAVEN_CONFIG}/${rel}";
fi;
}

copy_reference_files() {
local log="$MAVEN_CONFIG/copy_reference_file.log"
local ref="/usr/share/maven/ref"

if (sh -c "mkdir -p \"$MAVEN_CONFIG\" && touch \"${log}\"" > /dev/null 2>&1)
then
echo "--- Copying files at $(date)" >> "$log"
find /usr/share/maven/ref/ -type f -exec bash -eu -c 'copy_reference_file /usr/share/maven/ref/ "$1" "$2"' _ {} "$log" \;
if mkdir -p "${MAVEN_CONFIG}/repository" && touch "${log}" > /dev/null 2>&1 ; then
cd "${ref}"
local reflink=""
if cp --help 2>&1 | grep -q reflink ; then
reflink="--reflink=auto"
fi
if [ -n "$(find "${MAVEN_CONFIG}/repository" -maxdepth 0 -type d -empty 2>/dev/null)" ] ; then
# destination is empty...
echo "--- Copying all files to ${MAVEN_CONFIG} at $(date)" >> "${log}"
cp -rv ${reflink} . "${MAVEN_CONFIG}" >> "${log}"
else
# destination is non-empty, copy file-by-file
echo "--- Copying individual files to ${MAVEN_CONFIG} at $(date)" >> "${log}"
find . -type f -exec sh -eu -c '
log="${1}"
shift
reflink="${1}"
shift
for f in "$@" ; do
if [ ! -e "${MAVEN_CONFIG}/${f}" ] || [ -e "${f}.override" ] ; then
mkdir -p "${MAVEN_CONFIG}/$(dirname "${f}")"
cp -rv ${reflink} "${f}" "${MAVEN_CONFIG}/${f}" >> "${log}"
fi
done
' _ "${log}" "${reflink}" {} +
fi
echo >> "${log}"
else
echo "Can not write to ${log}. Wrong volume permissions? Carrying on ..."
fi
}

export -f copy_reference_file
owd="$(pwd)"
copy_reference_files
unset MAVEN_CONFIG

cd "${owd}"
unset owd

exec "$@"
Loading

0 comments on commit 7b4d1f0

Please sign in to comment.