2020-08-24 12:06:23 +00:00
#!/usr/bin/env bash
if [ [ ! -f "/.dockerenv" ] ] ; then
repo_root = " $( git rev-parse --show-toplevel) " ;
else
repo_root = "/srv" ;
fi
lantern_path = " ${ repo_root } /lantern-build-engine " ;
IMAGEBUILDER_REGISTRY = " ${ IMAGEBUILDER_REGISTRY :- registry .service.mooncarrot.space : 5000 } " ;
2021-01-14 01:23:45 +00:00
export IMAGEBUILDER_REGISTRY;
2020-08-24 12:06:23 +00:00
###############################################################################
#shellcheck disable=SC1090
source " ${ lantern_path } /lantern.sh " ;
if [ [ -z " ${ BASE_PATH } " ] ] ; then
2020-08-24 18:28:31 +00:00
subtask_begin " BASE_PATH environment variable not found - setting base path to ${ HC } ${ repo_root } /images ${ RS } " ;
BASE_PATH = " ${ repo_root } /images " ;
2020-08-24 12:06:23 +00:00
subtask_end " $? " ;
fi
if [ [ ! -d " ${ BASE_PATH } " ] ] ; then
echo " Error: The specified base path ' ${ BASE_PATH } ' doesn't exist. " ;
exit 1;
fi
# Make sure the current directory is the location of this script to simplify matters
cd " $( dirname " $( readlink -f " $0 " ) " ) " || { echo "Error: Failed to cd" ; exit 1; } ;
# Check out the lantern git submodule if needed
if [ ! -f " ${ lantern_path } /lantern.sh " ] ; then git submodule update --init " ${ lantern_path } " ; fi
# Create temporary directory
temp_dir = " $( mktemp --tmpdir -d "imagebuilder-XXXXXXX" ) " ;
on_exit( ) {
task_begin "Cleaning up temporary directory" ;
rm -rf " ${ temp_dir } " ;
task_end " $? " ;
}
trap on_exit EXIT;
###############################################################################
subcommand = " ${ 1 } " ;
shift;
if [ [ -z " ${ subcommand } " ] ] ; then
CHEADING = " ${ HC } ${ FCYN } " ;
CACTION = " ${ FYEL } " ; #
CARG = " ${ FMAG } "
echo -e " ${ HC } imagebuilder: Docker image (re)builder ${ RS } " >& 2;
echo -e " By Starbeamrainbowlabs" >& 2;
echo -e "" >& 2;
echo -e " ${ CHEADING } Usage: ${ RS } " >& 2;
echo -e " ${ HC } ${ FGRN } ./imagebuilder.sh ${ RS } ${ CACTION } {action} ${ RS } ${ LC } [ ${ RS } ${ CARG } {arguments} ${ RS } ${ LC } ] ${ RS } " >& 2;
echo -e "" >& 2;
echo -e " ${ CHEADING } Actions: ${ RS } " >& 2;
2021-09-11 01:19:38 +00:00
echo -e " ${ CACTION } build ${ RS } ${ CARG } {imagename} ${ RS } [ ${ CARG } {imagetag} ${ RS } ] " >& 2;
echo -e " Build the given image and upload it to the docker registry, optionally assigning a custom tag name" >& 2;
2020-08-24 12:06:23 +00:00
echo -e " ${ CACTION } list ${ RS } " >& 2;
echo -e " List available images" >& 2;
echo -e "" >& 2;
echo -e " ${ CHEADING } Environment Variables: ${ RS } " >& 2;
echo -e " ${ CACTION } IMAGEBUILDER_REGISTRY ${ RS } " >& 2;
echo -e " Set the url of the Docker registry (default: ${ HC } registry.service.mooncarrot.space:5000 ${ RS } ) " >& 2;
echo -e " ${ CACTION } BASE_PATH ${ RS } " >& 2;
echo -e " Base path in which to look for image directories (defaults to the current working directory)" >& 2;
echo -e "" >& 2;
exit 0;
fi
###############################################################################
case " ${ subcommand } " in
2020-09-05 20:10:37 +00:00
# ██ ██ ███████ ████████
# ██ ██ ██ ██
# ██ ██ ███████ ██
# ██ ██ ██ ██
# ███████ ██ ███████ ██
2020-08-24 12:06:23 +00:00
list)
while read -r filepath; do
filepath_stripped = " ${ filepath # " ${ BASE_PATH } " } " ;
if [ [ -z " ${ filepath_stripped } " ] ] || [ [ ! -f " ${ filepath } /type.txt " ] ] ; then
continue ;
fi
echo " ${ filepath_stripped } " ;
done < <( find " ${ BASE_PATH } " -maxdepth 1 -type d) ;
; ;
2020-09-05 20:10:37 +00:00
# ██████ ██ ██ ██ ██ ██████
# ██ ██ ██ ██ ██ ██ ██ ██
# ██████ ██ ██ ██ ██ ██ ██
# ██ ██ ██ ██ ██ ██ ██ ██
# ██████ ██████ ██ ███████ ██████
2020-08-24 12:06:23 +00:00
build)
imagename = " ${ 1 } " ;
2021-09-11 01:19:38 +00:00
imagetag = " ${ 2 } " ;
2020-08-24 12:06:23 +00:00
if [ [ -z " ${ imagename } " ] ] ; then
echo "Error: No image name specified." :
exit 1;
fi
imagedir = " ${ BASE_PATH } / ${ imagename } " ;
if [ [ ! -d " ${ imagedir } " ] ] ; then
echo -e " Error: An image with the name ${ HC } ${ imagename } ${ RS } doesn't exist. " ;
exit 2;
fi
if [ [ ! -f " ${ imagedir } /type.txt " ] ] ; then
echo -e " Error: No type.txt file was found for the image with the name ${ HC } ${ imagename } ${ RS } . " ;
exit 3;
fi
2021-09-11 01:19:38 +00:00
# Determine the fully qualified tag that we're going to push to
docker_tag = " ${ IMAGEBUILDER_REGISTRY } / ${ imagename } " ;
if [ [ ! -z " ${ imagetag } " ] ] ; then
docker_tag = " ${ docker_tag } : ${ imagetag } " ;
fi
2021-09-19 13:49:01 +00:00
echo -e " [ ${ HOSTNAME } :imagebuilder] Fully qualified tag name: ${ HC } ${ FGRN } ${ docker_tag } ${ RS } " ;
2020-08-24 12:06:23 +00:00
imagetype = " $( tr -d "[:blank:]" <" ${ imagedir } /type.txt " ) " ;
case " ${ imagetype } " in
2020-09-05 20:10:37 +00:00
# ██████ ██████ ██████ ██ ██ ███████ ██████
# ██ ██ ██ ██ ██ ██ ██ ██ ██ ██
# ██ ██ ██ ██ ██ █████ █████ ██████
# ██ ██ ██ ██ ██ ██ ██ ██ ██ ██
# ██████ ██████ ██████ ██ ██ ███████ ██ ██
2020-08-24 12:06:23 +00:00
docker)
if [ [ ! -f " ${ imagedir } /Dockerfile " ] ] ; then
echo -e " Error: Failed to find a Dockerfile at ${ HC } ${ imagedir } /Dockerfile ${ RS } . " ;
exit 7;
fi
cd " ${ imagedir } " || { echo -e " Error: Failed to cd into ${ HC } ${ imagedir } ${ RS } " ; exit 1; } ;
if [ [ -x "./pre.sh" ] ] ; then
task_begin "Executing pre-build hook" ;
execute ./pre.sh;
task_end " $? " ;
fi
task_begin "Building docker image" ;
echo " Tag: ${ docker_tag } " ;
execute docker build --no-cache --pull --tag " ${ docker_tag } " --build-arg " REPO_LOCATION= ${ IMAGEBUILDER_REGISTRY } / " .;
task_end " $? " ;
task_begin "Pushing resulting docker image" ;
execute docker push " ${ docker_tag } " ;
task_end " $? " ;
if [ [ -x "./post.sh" ] ] ; then
task_begin "Executing post-build hook" ;
execute ./post.sh;
task_end " $? " ;
fi
; ;
2020-09-05 20:10:37 +00:00
# ██████ █████ ███████ ███████
# ██ ██ ██ ██ ██ ██
# ██████ ███████ ███████ █████
# ██ ██ ██ ██ ██ ██
# ██████ ██ ██ ███████ ███████
2020-08-24 12:06:23 +00:00
base| base-nopush)
builderscript = " ${ imagedir } / ${ imagename } .sh " ;
if [ [ ! -x " ${ builderscript } " ] ] ; then
echo -e " Error: Failed to find the base image builder script at ${ HC } ${ builderscript } ${ RS } (is it executable?). " ;
exit 5;
fi
output_dir = " ${ temp_dir } / ${ imagename } " ;
2021-01-14 20:59:11 +00:00
mkdir -p " ${ output_dir } " ;
2020-08-24 12:06:23 +00:00
task_begin "Building base image" ;
if [ [ " ${ UID } " -ne 0 ] ] && which fakeroot && which fakechroot; then
echo "Non-root user detected - using fakeroot & fakechroot" ;
execute fakechroot fakeroot " ${ builderscript } " " ${ output_dir } " ;
else
echo "root user or fakeroot & fakechroot not detected" ;
execute " ${ builderscript } " " ${ output_dir } " ;
fi
task_end " $? " ;
2020-09-05 20:01:07 +00:00
if [ [ " ${ imagetype } " = = "base-nopush" ] ] ; then
2021-01-14 21:15:19 +00:00
echo -e " ${ HC } Nopush mode invoked, not checking output directory or pushing to docker registry ${ RS } " ;
2020-08-24 12:06:23 +00:00
exit 0;
fi
if [ [ ! -d " ${ output_dir } " ] ] ; then
2021-12-28 13:20:59 +00:00
echo -e " ${ FRED } ${ HC } Error: The builder script failed to create the output directory (expecting directory at ${ FBLE } ${ output_dir } ${ FRED } , but found nothing). ${ RS } " ;
2020-08-24 12:06:23 +00:00
exit 6;
fi
task_begin "Importing resulting image into Docker" ;
image_filepath = " $( find " ${ output_dir } " -iname "*.tar.gz" -printf '%p' -quit) " ;
2021-09-11 01:19:38 +00:00
docker_tag_local = " $( docker import - <" ${ image_filepath } " ) " ;
2020-08-24 12:06:23 +00:00
task_end " $? " ;
task_begin "Tagging and pushing to registry" ;
2021-09-11 01:19:38 +00:00
execute docker tag " ${ docker_tag_local } " " ${ docker_tag } " ;
2021-09-19 13:49:01 +00:00
execute docker push " ${ docker_tag } " ;
2020-08-24 12:06:23 +00:00
task_end " $? " ;
; ;
2021-09-27 01:27:57 +00:00
import)
task_begin "Finding remote image name" ;
if [ [ ! -r " ${ imagedir } /imagename.txt " ] ] ; then
echo "Error: 'import' image type specified, but no imagename.txt file was found containing the (fully qualified) image name to pull from." ;
exit 8;
fi
imagename_remote = " $( tr -d "[:blank:]" <" ${ imagedir } /imagename.txt " ) "
if [ [ -z " ${ imagename_remote } " ] ] ; then
echo "Error: An empty image name to pull isn't valid." ;
exit 7;
fi
echo -e " [ ${ HOSTNAME } :imagebuilder] Remote image name is ${ FGRN } ${ HC } ${ imagename_remote } ${ RS } " ;
task_end " $? " ;
task_begin "Downloading image" ;
execute docker pull " ${ imagename_remote } " ;
task_end " $? " "Error: Failed to download image" ;
task_begin "Retagging image" ;
execute docker tag " ${ imagename_remote } " " ${ docker_tag } " ;
task_end " $? " ;
task_begin "Pushing image" ;
execute docker push " ${ docker_tag } " ;
task_end " $? " ;
; ;
2020-08-24 12:06:23 +00:00
2020-09-05 20:10:37 +00:00
# ██ ██ ███ ██ ██ ██ ███ ██ ██████ ██ ██ ███ ██
# ██ ██ ████ ██ ██ ██ ████ ██ ██ ██ ██ ██ ████ ██
# ██ ██ ██ ██ ██ █████ ██ ██ ██ ██ ██ ██ █ ██ ██ ██ ██
# ██ ██ ██ ██ ██ ██ ██ ██ ██ ██ ██ ██ ██ ███ ██ ██ ██ ██
# ██████ ██ ████ ██ ██ ██ ████ ██████ ███ ███ ██ ████
2020-08-24 12:06:23 +00:00
*)
echo -e " Error: The image type ${ HC } ${ imagetype } ${ RS } was not recognised. Currently recognised types: base, base-nopush, docker " ;
exit 4;
; ;
esac
; ;
*)
echo -e " Unknown subcommand ' ${ HC } ${ subcommand } ${ RS } ' (try calling imagebuilder.sh without any arguments) " ;
; ;
esac