diff --git a/Dockerfile b/Dockerfile index ca7bec9..69998e5 100644 --- a/Dockerfile +++ b/Dockerfile @@ -4,8 +4,8 @@ ARG BASE_IMAGE ARG KEEP ARG SYSADMIN_PW ARG LINUX_DISTRO=alpine -ARG SCRIPTS=/build -WORKDIR $SCRIPTS +ARG BUILD_DIR=/build +WORKDIR $BUILD_DIR COPY .src ./ RUN echo -e "\n ************************************************* \n"\ @@ -25,4 +25,4 @@ RUN echo -e "\n ************************************************* \n" \ VOLUME [ "/data", "/opt", "/shell" ] WORKDIR /opt # ENTRYPOINT ["entrypoint.sh"] -CMD ["/bin/bash"] +CMD ["/bin/bash", "-l"] diff --git a/build b/build index 0c65ede..7d13007 100755 --- a/build +++ b/build @@ -8,14 +8,16 @@ declare OPTION; declare OPTARG; declare OPTIND SDIR=$(pwd) BDIR=$(dirname "$(realpath "$BASH_SOURCE")") +export SDIR +export BDIR pushd $BDIR > /dev/null source $BDIR/lib/load.sh case "$1" in - try) + image_name) shift 1 - try_container "$@" + image_name "$@" return $? ;; tag) @@ -23,6 +25,11 @@ case "$1" in image_tag "$@" return $? ;; + push) + shift 1 + image_push "$@" + return $? + ;; info) shift 1 [[ $1 == "arch" ]] && { shift 1; image_arch "$@"; return $?; } @@ -39,12 +46,27 @@ exit_abnormal() { # Function: Exit with error. scripts_dir=$SDIR/src [[ -z "$PS1" ]] || no_prompt=true +overwrite=true +target=dev -while getopts ':b:d:t:ncr:u:pxhs:w:akvoi' OPTION; do +while getopts 'g:e:b:d:t:ncr:u:pxhs:w:akvoi' OPTION; do # echo processing: option:$OPTION argument:$OPTARG index:$OPTIND remaining:${@:$OPTIND} case "$OPTION" in + e) + if [[ -f $SDIR/$OPTARG ]]; then + source $OPTARG + [[ ! $? -eq 0 ]] && echo source of $OPTARG filed, exiting && return 2 + else + echo no environment file at $OPTARG, exiting + return 2 + fi + echo "----------" + echo loaded environment filen $SDIR/$OPTARG + cat $SDIR/$OPTARG + echo "----------" + ;; o) - overwrite=true + unset overwrite ;; i) BUST_INIT_CACHE=$(date) @@ -63,7 +85,7 @@ while getopts ':b:d:t:ncr:u:pxhs:w:akvoi' OPTION; do ;; w) # the work directory to put the build scripts in container (default is /opt/build) - SCRIPTS=$OPTARG + BUILD_DIR=$OPTARG ;; b) # CUSTOM BASE IMAGE @@ -88,6 +110,9 @@ while getopts ':b:d:t:ncr:u:pxhs:w:akvoi' OPTION; do exclude_distro=true ;; t) + target=$OPTARG + ;; + g) TAG=$OPTARG ;; u) @@ -130,12 +155,13 @@ if [[ ! -d $scripts_dir ]]; then scripts_dir=$BDIR/src fi -target=${1:-dev} -LINUX_DISTRO=${LINUX_DISTRO:-alpine} -name=$2 -RUSER=${3:-$RUSER} +[[ ! "${targets[@]}" =~ $target ]] && echo $target is not a valid target && echo valid targets are: ${targets[@]} && exit 4 -IMAGE_NAME=$([[ $RUSER ]] && echo ${RUSER}/)${name}$([[ (! $exclude_distro) && $name ]] && echo "-")$([[ ! $exclude_distro ]] && echo ${LINUX_DISTRO}) +LINUX_DISTRO=${LINUX_DISTRO:-alpine} +name=$1 +RUSER=${2:-$RUSER} + +IMAGE_NAME=$([[ $RUSER ]] && echo ${RUSER}/)$([[ ! $exclude_distro ]] && echo ${LINUX_DISTRO}-)${name} # TODO writing to existing tag untags existing image so write a new tag to that image then continue # retag existing image and remove former tag @@ -144,7 +170,7 @@ if [[ $(image_exists $IMAGE_NAME) ]]; then image_delete $IMAGE_NAME else newtag=$(date +'%d%H%M%S') - echo image exists retaging $(make_tag $IMAGE_NAME) with tag :$newtag + echo image exists retaging $(image_name $IMAGE_NAME) with tag :$newtag image_tag $IMAGE_NAME $IMAGE_NAME:$newtag image_tag -r $IMAGE_NAME fi @@ -166,21 +192,21 @@ export BASE_IMAGE export TAG export IMAGE_NAME export LINUX_DISTRO -export SCRIPTS +export BUILD_DIR export KEEP export SYSADMIN_PW export BUST_INIT_CACHE echo "******************************************" echo "Building with base image: $BASE_IMAGE" -echo "Outputing to image name => $IMAGE_NAME" +echo "Outputing to image name => $IMAGE_NAME<-arch>:${TAG:-latest}" echo "Linux Distro: $LINUX_DISTRO" echo "Using build target: $target" if [[ $verbose ]]; then echo -e "\n---------------------------------" docker buildx bake --print $target echo -e "\n---------------------------------" - echo "build scripts at $scripts_dir to be copied to ${SCRIPTS:-/opt/build} in container ***** " + echo "build scripts at $scripts_dir to be copied to ${BUILD_DIR:-/build} in container ***** " ls -la $scripts_dir echo -e "\n----- base init script init.sh ------" cat $scripts_dir/init.sh @@ -193,8 +219,6 @@ if [[ ! $no_prompt ]]; then [[ $REPLY != "y" ]] && echo -e "\n" && exit 0 fi -[[ ! "${targets[@]}" =~ $target ]] && echo $target is not a valid target && echo valid targets are: ${targets[@]} && exit 4 - builder=default if [ $target == "deploy" ]; then builder=deploy diff --git a/build.env b/build.env new file mode 100644 index 0000000..24b1e97 --- /dev/null +++ b/build.env @@ -0,0 +1,7 @@ +SYSADMIN_PW=pasword +LINUX_DISTRO=ubuntu +TAG=1.0.0 +RUSER=ucommandit +REPO=git.kebler.net +# BASE_IMAGE="ucommandit/ubuntu-base" +# BUILD_DIR="/opt/build" diff --git a/docker-bake.hcl b/docker-bake.hcl index d31949d..ba692d8 100644 --- a/docker-bake.hcl +++ b/docker-bake.hcl @@ -5,7 +5,7 @@ variable "TAG" { variable "LINUX_DISTRO" { default = "alpine" } -variable "SCRIPTS" { +variable "BUILD_DIR" { default = "" } variable "IMAGE_NAME" { @@ -54,7 +54,7 @@ target "amd" { LINUX_DISTRO = "${LINUX_DISTRO}" BASE_IMAGE = "${BASE_IMAGE}" TAG = "${TAG}" - SCRIPTS = "/build/${SCRIPTS}" + SCRIPTS = "${BUILD_DIR}" KEEP = "${KEEP}" SYSADMIN_PW = "${SYSADMIN_PW}" BUST_INIT_CACHE = "${BUST_INIT_CACHE}" diff --git a/lib/src/02-make-tag b/lib/src/02-image-name similarity index 53% rename from lib/src/02-make-tag rename to lib/src/02-image-name index 3e8a813..8352383 100755 --- a/lib/src/02-make-tag +++ b/lib/src/02-image-name @@ -1,25 +1,28 @@ #!/bin/bash -make_tag () { +image_name () { -local tag +local tag; local efile # generate a full image name with tag # $1 name, $2 user(or repo), $3 repo -[[ $# -lt 1 ]] && echo "image base name required" && exit +# [[ $# -lt 1 ]] && echo "image base name required" && exit declare OPTION; declare OPTARG; declare OPTIND -while getopts 'at:r:u:' OPTION; do +while getopts 'e:ag:r:u:' OPTION; do # echo processing: option:$OPTION argument:$OPTARG index:$OPTIND remaining:${@:$OPTIND} case "$OPTION" in +e) + efile=$OPTARG + ;; r) REPO=$OPTARG ;; u) RUSER=$OPTARG ;; -t) +g) TAG=$OPTARG ;; a) # add -arm64 to image @@ -33,6 +36,21 @@ esac done shift $((OPTIND - 1)) +echo $efile +if [[ $efile ]]; then + [[ ! -f $efile ]] && efile=$SDIR/$efile + if [[ -f $efile ]]; then + source $efile + [[ ! $? -eq 0 ]] && echo source of $efile failed, exiting && return 2 + else + echo no environment file at $efile, exiting + return 2 + fi + echo "----------" + echo loaded environment filen $efile + cat $efile + echo "----------" +fi tag=$( echo $1 | cut -s -d ":" -f2) tag=${tag:-$TAG} @@ -40,11 +58,11 @@ name=${1%:*} user=${2:-$RUSER} repo=${3:-$REPO} -tag=$([[ $repo ]] && echo ${repo}/)$([[ $user ]] && echo ${user}/)$name$([[ $arm ]] && echo -arm64):${tag:-latest} +tag=$([[ $repo ]] && echo ${repo}/)$([[ $user ]] && echo ${user}/)$name$([[ $arm ]] && echo -arm64):${TAG:-latest} echo $tag } # if script was executed then call the function -(return 0 2>/dev/null) || make_tag $@ \ No newline at end of file +(return 0 2>/dev/null) || image_name $@ \ No newline at end of file diff --git a/lib/src/image-info b/lib/src/image-info index 3d3adc0..9f8792c 100755 --- a/lib/src/image-info +++ b/lib/src/image-info @@ -1,7 +1,7 @@ #!/bin/bash image_info () { [[ $1 == "-k" ]] && key=$2 && shift 2 -tag=$(make_tag "$@") +tag=$(image_name "$@") # TODO try using --format to extract keys # https://docs.docker.com/engine/reference/commandline/inspect/ info=$(docker image inspect $tag 2> /dev/null) || info=$(docker image inspect $1 2> /dev/null) || return 1 diff --git a/lib/src/image-push b/lib/src/image-push index 322c125..5d13026 100755 --- a/lib/src/image-push +++ b/lib/src/image-push @@ -2,34 +2,23 @@ image_push () { -local DIR -DIR=$(cd "$(dirname "$BASH_SOURCE")" >/dev/null 2>&1 ; pwd -P ) - #tags an image and pushes it to a repository # if not reposity is given will use docker.io and push to hub.docker.com # $1 name, $2 user(or repo), $3 repo -[[ $# -lt 1 ]] && echo "image base name required" && exit +source=$$image_name + declare OPTION; declare OPTARG; declare OPTIND -while getopts 'aht:r:u:' OPTION; do +while getopts 'e:aht:r:u:' OPTION; do # echo processing: option:$OPTION argument:$OPTARG index:$OPTIND remaining:${@:$OPTIND} case "$OPTION" in -r) - REPO=$OPTARG - ;; -u) - RUSER=$OPTARG -;; -t) - TAG=$OPTARG - ;; +e) + efile=$OPTARG + ;; h) # pull image from dockerhub if not available hub=true ;; -a) # arm image - arm=arm64 - ;; *) echo unknown run option -$OPTARG echo "USAGE: start " echo "available options: -h pull from hub.docker.com if not available, -a push arm64 image, -t custom tag " @@ -39,11 +28,26 @@ done shift $((OPTIND - 1)) +SDIR=$1 +shift +[[ $efile ]] && efile = $SDIR/$efile +if [[ -f $efile ]]; then + source $efile + [[ ! $? -eq 0 ]] && echo source of $efile failed, exiting && return 2 + else + echo no environment file at $efile, exiting + return 2 + fi + echo "----------" + echo loaded environment filen $efile + cat $efile + echo "----------" # image tag name=$1 user=${2:-$RUSER} repo=${3:-$REPO} + source=$([[ $user ]] && echo ${user}/)$name:${TAG:-latest} source2=$([[ $arm ]] && echo ${source//:/-arm64:} || echo $source) diff --git a/lib/src/image-tag b/lib/src/image-tag index 4b866a7..01f06e0 100755 --- a/lib/src/image-tag +++ b/lib/src/image-tag @@ -10,12 +10,12 @@ local name; local remove; local id [[ $# -lt 1 ]] && echo "image base name required" && exit [[ $1 == "-r" ]] && remove=true && shift 1 [[ $1 == "-i" ]] && { shift 1; id=$1; } || id=$(image_id $1) -name=$(make_tag "$1") +name=$(image_name "$1") [[ ! $id ]] && { echo "no image with id:$id name:$name"; return 1; } if [[ $2 ]];then -# echo making tag for $2 $(make_tag $2) -docker tag $id $(make_tag $2) +# echo making tag for $2 $(image_name $2) +docker tag $id $(image_name $2) else [[ $remove ]] && docker rmi $name || echo to remove an image tag use -r fi diff --git a/lib/src/usage b/lib/src/usage index f4971c2..b976cfe 100644 --- a/lib/src/usage +++ b/lib/src/usage @@ -1,18 +1,34 @@ #!/bin/bash usage() { # Function: Print a help message. echo "Image Build Script: Creates one or more images using a target in the docker-bake.hcl file" - echo "USAGE: $0 buildtarget " - echo "valid targets: ${targets[*]}; default: dev" - echo no argument options: - echo "-c try out the image by starting a container terminal therein, for dev target this is the default;" + echo "USAGE: $0 " + echo "valid build_target: ${targets[*]}; default: dev" + echo "### subcommands:" + echo "try (runs try a container script, see try usage) $0 try -i" + echo "tag (runs image_tag script)" + echo "info get image info, info nothing is all info in json" + echo "--- option switches (no argument):" + echo "-o do not overwrite an existing image (default), instead move it to a temporary timestamp tag" + echo "-i rebuild only the initialization RUN by busting the cache at that point" + echo "-v show verbose information about the build" + echo "-a (auto) do not prompt to continue build, by default will not prompt if non-interactive shell" + echo "-c after build try out the image by starting a container terminal therein, for dev target this is the default;" echo "-x exclude distro from image name;" echo "-n for --no_cache" - echo "-p push to repository; after build push to repository default is hub.docker.common (not need for deploy target)" - echo required argument options: + echo "-k keep the build scripts (see -w) after the build so they are incorporated into the image" + echo "-p push to repository; after build push to repository default is hub.docker.com (not need for deploy target)" + echo "--- options with argument :" + echo "-e load any or all of options below via a file" echo "-d supported: alpine, debian, ubuntu, default: alpine; if base image set distro will be determined" echo "-t tag following : in output image name (i.e. REPO/USER/NAME:TAG), default: latest" echo "-u ; repository user prefix in output image name (i.e. REPO/USER/NAME:TAG)" echo "-r ; private repo name, do not use for hub.docker.com (docker.io)" echo "-b ; used in FROM in Dockerfile, default is official distro image (e.g. alpine:latest)" - echo "-w ; set a custom WORKDIR in Dockerfile, default is /opt/build" + echo "-w ; set a custom WORKDIR in Dockerfile (in image), default is /build, see -k" + echo "--- options set ONLY by environment variable (see -e as well)" + echo " set alternate password for container sysadmin account, default is 'sysadmin'" + echo "NOTE any option with above can be set in environment instead" + echo "#### examples:" + echo "$0 -a -d ubuntu -u ucommandit" + echo "build (without prompt) a local ubuntu image from scratch and label it ucommandit/ubuntu:latest" } \ No newline at end of file diff --git a/src/init.sh b/src/init.sh index 5ecf39e..3896c39 100644 --- a/src/init.sh +++ b/src/init.sh @@ -1,5 +1,5 @@ #!/bin/sh - echo "entry init.sh script in $SCRIPTS" + echo "entry init.sh script in $BUILD_DIR" # remove other distro files # find $PWD -maxdepth 1 -type d ! -path $PWD ! -name ${LINUX_DISTRO} ! -name common -exec rm -rf {} + cd ${LINUX_DISTRO} || exit 1 @@ -21,6 +21,6 @@ cd .. if [ -z $KEEP ]; then - echo removing $SCRIPTS directory used for build - cd /opt && rm -rf $SCRIPTS + echo removing $BUILD_DIR directory used for build + cd /opt && rm -rf $BUILD_DIR fi \ No newline at end of file