minor refactoring of bind script
* fix image name generation * add logging directory and direct output to files there removed linked mount in try script as btrfs does not create volume directories (bind mount only now) move packages and init into separate directories to keep cache separate fix some minor bugsmaster
parent
066aa72b83
commit
b88ea929b0
|
@ -2,3 +2,6 @@
|
||||||
/build.log
|
/build.log
|
||||||
_opt/
|
_opt/
|
||||||
.src
|
.src
|
||||||
|
TODO.md
|
||||||
|
mnt/
|
||||||
|
logs/
|
27
Dockerfile
27
Dockerfile
|
@ -6,23 +6,32 @@ ARG SYSADMIN_PW
|
||||||
ARG LINUX_DISTRO=alpine
|
ARG LINUX_DISTRO=alpine
|
||||||
ARG BUILD_DIR=/build
|
ARG BUILD_DIR=/build
|
||||||
WORKDIR $BUILD_DIR
|
WORKDIR $BUILD_DIR
|
||||||
COPY .src ./
|
|
||||||
|
|
||||||
RUN echo -e "\n ************************************************* \n"\
|
COPY .src/packages ./packages
|
||||||
|
# PACKAGES
|
||||||
|
RUN \
|
||||||
|
# --mount=type=cache,target=/var/cache/apt \
|
||||||
|
echo -e "\n ************************************************* \n"\
|
||||||
echo "****** Building Image from Base: $BASE_IMAGE; : Distro: $LINUX_DISTRO; *****"; \
|
echo "****** Building Image from Base: $BASE_IMAGE; : Distro: $LINUX_DISTRO; *****"; \
|
||||||
echo " ---- running packages install script ---"; /bin/sh ./packages.sh; \
|
echo " ---- running packages install script ---"; \
|
||||||
|
cd packages; /bin/sh ./packages.sh; cd ..; \
|
||||||
echo -e "\n********************************************************"
|
echo -e "\n********************************************************"
|
||||||
|
# END PACKAGES
|
||||||
|
|
||||||
ARG BUST_INIT_CACHE
|
COPY .src/init ./init
|
||||||
|
|
||||||
|
# INITIALIZATION
|
||||||
RUN echo -e "\n ************************************************* \n" \
|
RUN echo -e "\n ************************************************* \n" \
|
||||||
echo "****** BUST_INIT_CACHE ${BUST_INIT_CACHE} "; \
|
echo "****** Initializing Image "; \
|
||||||
echo "****** Running Initialization Script "; \
|
cd init; \
|
||||||
chmod -R +x .; \
|
chmod -R +x .; \
|
||||||
pwd; ls -la; \
|
pwd; ls -la; \
|
||||||
echo " ---- running init script ---"; /bin/bash ./init.sh; \
|
echo " ---- running init script ---"; \
|
||||||
echo -e "\n********************************************************"
|
/bin/bash ./init.sh; \
|
||||||
|
echo -e "\n ************* End Initialzation ************************"
|
||||||
|
# END INITIALIZATION
|
||||||
|
|
||||||
VOLUME [ "/data", "/opt", "/shell" ]
|
VOLUME [ "/data", "/opt", "/shell, /home/sysadmin" ]
|
||||||
WORKDIR /opt
|
WORKDIR /opt
|
||||||
# ENTRYPOINT ["entrypoint.sh"]
|
# ENTRYPOINT ["entrypoint.sh"]
|
||||||
CMD ["/bin/bash", "-l"]
|
CMD ["/bin/bash", "-l"]
|
||||||
|
|
13
aliases
13
aliases
|
@ -1,13 +0,0 @@
|
||||||
#!/bin/bash
|
|
||||||
# three ways to invoke with --no-cache
|
|
||||||
|
|
||||||
# inline
|
|
||||||
# NO_CACHE=true ./build "$@"
|
|
||||||
|
|
||||||
# with -n option (prefered)
|
|
||||||
./build -n "$@"
|
|
||||||
alias rebuild="build -nfunction_list"
|
|
||||||
|
|
||||||
# as export
|
|
||||||
#export NO_CACHE=true
|
|
||||||
#./build "$@"
|
|
89
build
89
build
|
@ -3,7 +3,7 @@
|
||||||
docker_image_build () {
|
docker_image_build () {
|
||||||
|
|
||||||
local targets=(dev arm amd deploy private multi)
|
local targets=(dev arm amd deploy private multi)
|
||||||
local verbose
|
local verbose; local scripts_dir; local log_dir;
|
||||||
declare OPTION; declare OPTARG; declare OPTIND
|
declare OPTION; declare OPTARG; declare OPTIND
|
||||||
|
|
||||||
SDIR=$(pwd)
|
SDIR=$(pwd)
|
||||||
|
@ -15,6 +15,12 @@ pushd $BDIR > /dev/null
|
||||||
source $BDIR/lib/load.sh
|
source $BDIR/lib/load.sh
|
||||||
|
|
||||||
case "$1" in
|
case "$1" in
|
||||||
|
try)
|
||||||
|
shift 1
|
||||||
|
popd > /dev/null || return 2
|
||||||
|
try_container "$@"
|
||||||
|
return $?
|
||||||
|
;;
|
||||||
image_name)
|
image_name)
|
||||||
shift 1
|
shift 1
|
||||||
image_name "$@"
|
image_name "$@"
|
||||||
|
@ -45,6 +51,9 @@ exit_abnormal() { # Function: Exit with error.
|
||||||
}
|
}
|
||||||
|
|
||||||
scripts_dir=$SDIR/src
|
scripts_dir=$SDIR/src
|
||||||
|
# TODO allow log directory option
|
||||||
|
log_dir=$SDIR/logs
|
||||||
|
mkdir -p $log_dir
|
||||||
[[ -z "$PS1" ]] || no_prompt=true
|
[[ -z "$PS1" ]] || no_prompt=true
|
||||||
overwrite=true
|
overwrite=true
|
||||||
target=dev
|
target=dev
|
||||||
|
@ -53,25 +62,22 @@ while getopts 'g:e:b:d:t:ncr:u:pxhs:w:akvoi' OPTION; do
|
||||||
# echo processing: option:$OPTION argument:$OPTARG index:$OPTIND remaining:${@:$OPTIND}
|
# echo processing: option:$OPTION argument:$OPTARG index:$OPTIND remaining:${@:$OPTIND}
|
||||||
case "$OPTION" in
|
case "$OPTION" in
|
||||||
e)
|
e)
|
||||||
if [[ -f $SDIR/$OPTARG ]]; then
|
local efile=$SDIR/$OPTARG
|
||||||
source $OPTARG
|
if [[ -f $efile ]]; then
|
||||||
[[ ! $? -eq 0 ]] && echo source of $OPTARG filed, exiting && return 2
|
source "$efile"
|
||||||
|
[[ ! $? -eq 0 ]] && echo source of $efile failed, exiting && return 2
|
||||||
else
|
else
|
||||||
echo no environment file at $OPTARG, exiting
|
echo no environment file at $efile, exiting
|
||||||
return 2
|
return 2
|
||||||
fi
|
fi
|
||||||
echo "----------"
|
echo "----------"
|
||||||
echo loaded environment filen $SDIR/$OPTARG
|
echo loaded environment filen $efile
|
||||||
cat $SDIR/$OPTARG
|
cat $efile
|
||||||
echo "----------"
|
echo "----------"
|
||||||
;;
|
;;
|
||||||
o)
|
o)
|
||||||
unset overwrite
|
unset overwrite
|
||||||
;;
|
;;
|
||||||
i)
|
|
||||||
BUST_INIT_CACHE=$(date)
|
|
||||||
# export BUST_INIT_CACHE=$(date)
|
|
||||||
;;
|
|
||||||
v)
|
v)
|
||||||
verbose=true
|
verbose=true
|
||||||
;;
|
;;
|
||||||
|
@ -158,10 +164,20 @@ fi
|
||||||
[[ ! "${targets[@]}" =~ $target ]] && echo $target is not a valid target && echo valid targets are: ${targets[@]} && exit 4
|
[[ ! "${targets[@]}" =~ $target ]] && echo $target is not a valid target && echo valid targets are: ${targets[@]} && exit 4
|
||||||
|
|
||||||
LINUX_DISTRO=${LINUX_DISTRO:-alpine}
|
LINUX_DISTRO=${LINUX_DISTRO:-alpine}
|
||||||
|
|
||||||
|
if [[ $BASE_IMAGE ]]; then
|
||||||
|
echo determining DISTRO of base image: $BASE_IMAGE
|
||||||
|
LINUX_DISTRO=$(get_distro -d $BASE_IMAGE)
|
||||||
|
[[ ! $LINUX_DISTRO ]] && echo "unable to get base image OS for: $BASE_IMAGE, aborting build" && exit 1
|
||||||
|
echo $BASE_IMAGE is built from distro $LINUX_DISTRO
|
||||||
|
else
|
||||||
|
BASE_IMAGE=$LINUX_DISTRO
|
||||||
|
fi
|
||||||
|
|
||||||
name=$1
|
name=$1
|
||||||
RUSER=${2:-$RUSER}
|
RUSER=${2:-$RUSER}
|
||||||
|
|
||||||
IMAGE_NAME=$([[ $RUSER ]] && echo ${RUSER}/)$([[ ! $exclude_distro ]] && echo ${LINUX_DISTRO}-)${name}
|
IMAGE_NAME=$([[ $RUSER ]] && echo ${RUSER}/)${name}$([[ ! $exclude_distro ]] && echo -${LINUX_DISTRO})
|
||||||
# TODO writing to existing tag untags existing image so write a new tag to that image then continue
|
# 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
|
# retag existing image and remove former tag
|
||||||
|
@ -176,15 +192,6 @@ if [[ $(image_exists $IMAGE_NAME) ]]; then
|
||||||
fi
|
fi
|
||||||
fi
|
fi
|
||||||
|
|
||||||
|
|
||||||
if [[ $BASE_IMAGE ]]; then
|
|
||||||
echo determining DISTRO of base image: $BASE_IMAGE
|
|
||||||
LINUX_DISTRO=$(get_distro -d $BASE_IMAGE)
|
|
||||||
[[ ! $LINUX_DISTRO ]] && echo "unable to get base image OS for: $BASE_IMAGE, aborting build" && exit 1
|
|
||||||
else
|
|
||||||
BASE_IMAGE=$LINUX_DISTRO
|
|
||||||
fi
|
|
||||||
|
|
||||||
# BASE_IMAGE=$([[ $BASE_IMAGE == *:* ]] && echo $BASE_IMAGE || echo $BASE_IMAGE:latest)
|
# BASE_IMAGE=$([[ $BASE_IMAGE == *:* ]] && echo $BASE_IMAGE || echo $BASE_IMAGE:latest)
|
||||||
#$([[ ! $BASE_IMAGE == *:* ]] && echo :latest)
|
#$([[ ! $BASE_IMAGE == *:* ]] && echo :latest)
|
||||||
|
|
||||||
|
@ -202,6 +209,7 @@ echo "Building with base image: $BASE_IMAGE"
|
||||||
echo "Outputing to image name => $IMAGE_NAME<-arch>:${TAG:-latest}"
|
echo "Outputing to image name => $IMAGE_NAME<-arch>:${TAG:-latest}"
|
||||||
echo "Linux Distro: $LINUX_DISTRO"
|
echo "Linux Distro: $LINUX_DISTRO"
|
||||||
echo "Using build target: $target"
|
echo "Using build target: $target"
|
||||||
|
echo "Build Command: docker buildx --builder ${builder} bake ${nocache} ${target}"
|
||||||
if [[ $verbose ]]; then
|
if [[ $verbose ]]; then
|
||||||
echo -e "\n---------------------------------"
|
echo -e "\n---------------------------------"
|
||||||
docker buildx bake --print $target
|
docker buildx bake --print $target
|
||||||
|
@ -231,35 +239,34 @@ fi
|
||||||
|
|
||||||
[[ $target == "private" && ! $REPO ]] && echo "must use '-r <private repo>' if building to private repo" && exit 3
|
[[ $target == "private" && ! $REPO ]] && echo "must use '-r <private repo>' if building to private repo" && exit 3
|
||||||
|
|
||||||
# mount source directory to temporary .src/ subdirectory
|
# copy source directory to temporary .src/ subdirectory
|
||||||
|
# MUST either be readable by all or group readable by docker group
|
||||||
fusermount -u .src > /dev/null 2>&1
|
rm -rf $BDIR/.src
|
||||||
mkdir .src
|
rsync -aAru ${scripts_dir:-src}/ $BDIR/.src
|
||||||
bindfs ${scripts_dir:-src} .src
|
ls -la $BDIR/.src
|
||||||
|
|
||||||
docker buildx --builder ${builder} bake ${nocache} ${target} 2>&1 | tee $SDIR/${exIMAGE_NAME//\//-}build.log
|
|
||||||
|
|
||||||
fusermount -u .src > /dev/null 2>&1
|
|
||||||
rm -rf .src/
|
|
||||||
|
|
||||||
|
docker buildx --builder ${builder} bake ${nocache} ${target} 2>&1 | tee "$log_dir/${IMAGE_NAME//\//-}build.log"
|
||||||
[[ $? == 0 ]] && echo succcess building image $IMAGE_NAME || exit_abnormal 1
|
[[ $? == 0 ]] && echo succcess building image $IMAGE_NAME || exit_abnormal 1
|
||||||
|
|
||||||
if [[ $target == "private" ]]; then
|
rm -rf $BDIR/.src
|
||||||
./push -a -r $REPO $IMAGE_NAME
|
|
||||||
./push -r $REPO $IMAGE_NAME
|
# if [[ $target == "private" ]]; then
|
||||||
else
|
# ./push -a -r $REPO $IMAGE_NAME
|
||||||
if [[ $push && (! $target == "dev") ]];then
|
# ./push -r $REPO $IMAGE_NAME
|
||||||
echo pushing now
|
# else
|
||||||
./push $([[ $target == "arm" ]] && echo -a) -r $REPO $IMAGE_NAME
|
# if [[ $push && (! $target == "dev") ]];then
|
||||||
fi
|
# echo pushing now
|
||||||
fi
|
# ./push $([[ $target == "arm" ]] && echo -a) -r $REPO $IMAGE_NAME
|
||||||
|
# fi
|
||||||
|
# fi
|
||||||
|
|
||||||
|
popd > /dev/null
|
||||||
|
|
||||||
if [[ ($try || $target == "dev") ]] && [[ ! $no_prompt ]]; then
|
if [[ ($try || $target == "dev") ]] && [[ ! $no_prompt ]]; then
|
||||||
echo trying newly built image in a container
|
echo trying newly built image in a container
|
||||||
try_container -m opt $([[ $target == "deploy" ]] && echo -p) $IMAGE_NAME
|
try_container -m opt $([[ $target == "deploy" ]] && echo -p) $IMAGE_NAME
|
||||||
fi
|
fi
|
||||||
|
|
||||||
popd > /dev/null
|
|
||||||
#echo reset to calling directory $PWD
|
#echo reset to calling directory $PWD
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,7 +0,0 @@
|
||||||
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"
|
|
|
@ -3,16 +3,16 @@ variable "TAG" {
|
||||||
default = "latest"
|
default = "latest"
|
||||||
}
|
}
|
||||||
variable "LINUX_DISTRO" {
|
variable "LINUX_DISTRO" {
|
||||||
default = "alpine"
|
// default = "alpine"
|
||||||
}
|
}
|
||||||
variable "BUILD_DIR" {
|
variable "BUILD_DIR" {
|
||||||
default = ""
|
default = ""
|
||||||
}
|
}
|
||||||
variable "IMAGE_NAME" {
|
variable "IMAGE_NAME" {
|
||||||
default = "alpine"
|
// default = "alpine"
|
||||||
}
|
}
|
||||||
variable "BASE_IMAGE" {
|
variable "BASE_IMAGE" {
|
||||||
default = "alpine"
|
// default = "alpine"
|
||||||
}
|
}
|
||||||
variable "KEEP" {
|
variable "KEEP" {
|
||||||
default = ""
|
default = ""
|
||||||
|
@ -20,9 +20,6 @@ variable "KEEP" {
|
||||||
variable "SYSADMIN_PW" {
|
variable "SYSADMIN_PW" {
|
||||||
default = ""
|
default = ""
|
||||||
}
|
}
|
||||||
variable "BUST_INIT_CACHE" {
|
|
||||||
default = "1"
|
|
||||||
}
|
|
||||||
|
|
||||||
function "tag" {
|
function "tag" {
|
||||||
params = [suffix]
|
params = [suffix]
|
||||||
|
@ -57,7 +54,6 @@ target "amd" {
|
||||||
SCRIPTS = "${BUILD_DIR}"
|
SCRIPTS = "${BUILD_DIR}"
|
||||||
KEEP = "${KEEP}"
|
KEEP = "${KEEP}"
|
||||||
SYSADMIN_PW = "${SYSADMIN_PW}"
|
SYSADMIN_PW = "${SYSADMIN_PW}"
|
||||||
BUST_INIT_CACHE = "${BUST_INIT_CACHE}"
|
|
||||||
}
|
}
|
||||||
tags = tag("")
|
tags = tag("")
|
||||||
platforms = ["linux/amd64"]
|
platforms = ["linux/amd64"]
|
||||||
|
|
73
lib/src/try
73
lib/src/try
|
@ -10,27 +10,33 @@ try_container () {
|
||||||
|
|
||||||
declare -A arch=( ["x86_64"]="" ["aarch64"]="-arm64")
|
declare -A arch=( ["x86_64"]="" ["aarch64"]="-arm64")
|
||||||
local mp;local cuser; local hmp; local bind; local vname; local prod; local priv
|
local mp;local cuser; local hmp; local bind; local vname; local prod; local priv
|
||||||
local dkpath; local hostmp; local evar; local hostmap
|
local dkpath; local hostmp; local evar; local hostmap; local cleanup
|
||||||
|
|
||||||
[[ $# -lt 1 ]] && echo "image name required to try" && return 1
|
[[ $# -lt 1 ]] && echo "image name required to try" && return 1
|
||||||
|
|
||||||
declare OPTION; declare OPTARG; declare OPTIND
|
declare OPTION; declare OPTARG; declare OPTIND
|
||||||
OPTIND=0
|
OPTIND=0
|
||||||
while getopts 'pr:t:u:m:h:be:s' OPTION; do
|
while getopts 'o:dpr:t:u:m:h:ke:' OPTION; do
|
||||||
# echo processing: option:$OPTION argument:$OPTARG index:$OPTIND remaining:${@:$OPTIND}
|
# echo processing: option:$OPTION argument:$OPTARG index:$OPTIND remaining:${@:$OPTIND}
|
||||||
case "$OPTION" in
|
case "$OPTION" in
|
||||||
|
d)
|
||||||
|
dryrun="echo "
|
||||||
|
;;
|
||||||
u)
|
u)
|
||||||
cuser=$OPTARG
|
cuser=$OPTARG
|
||||||
;;
|
;;
|
||||||
b)
|
k)
|
||||||
bind=true
|
keep=true
|
||||||
;;
|
|
||||||
s)
|
|
||||||
save=true
|
|
||||||
;;
|
;;
|
||||||
|
# s)
|
||||||
|
# save=true
|
||||||
|
# ;;
|
||||||
m)
|
m)
|
||||||
mp=$OPTARG
|
mp=$OPTARG
|
||||||
;;
|
;;
|
||||||
|
o)
|
||||||
|
options="$option $OPTARG"
|
||||||
|
;;
|
||||||
h)
|
h)
|
||||||
hmp=$OPTARG
|
hmp=$OPTARG
|
||||||
;;
|
;;
|
||||||
|
@ -76,42 +82,53 @@ try_container () {
|
||||||
|
|
||||||
docker rm try-$name > /dev/null 2>&1
|
docker rm try-$name > /dev/null 2>&1
|
||||||
if [[ $mp ]]; then
|
if [[ $mp ]]; then
|
||||||
if [[ $bind ]];then
|
hostmp="${hmp:-${PWD}/mnt/$mp}"
|
||||||
dir=$(realpath "${hmp:-${PWD}/mnt/$mp}")
|
if [[ ! $(isAbsPath $hostmp) ]]; then
|
||||||
vname="try-$name${dir//\//-}"
|
[[ $SDIR ]] && hostmp=$SDIR/$hostmp || hostmp=$PWD/$hostmp
|
||||||
mkdir -p $dir
|
|
||||||
# echo bind $dir to volume $vname
|
|
||||||
docker volume create --driver local \
|
|
||||||
--opt type=none \
|
|
||||||
--opt device=$dir \
|
|
||||||
--opt o=bind "$vname" > /dev/null
|
|
||||||
else
|
|
||||||
vname="try-$name-${mp//\//-}"
|
|
||||||
hostmap="-e HOST_MAP=$(id -u):$(id -g)"
|
|
||||||
dkpath=$(docker info | grep -i "Docker Root Dir" | cut -d':' -f2)/volumes/$vname/_data
|
|
||||||
hostmp=${hmp:-${PWD}/mnt/$mp}
|
|
||||||
echo via volume $vname
|
|
||||||
echo linking $dkpath to $hostmp
|
|
||||||
ln -s $dkpath -T $hostmp
|
|
||||||
fi
|
fi
|
||||||
|
vname="try-$name${dir//\//-}"
|
||||||
|
mkdir -p "$hostmp"
|
||||||
|
# echo bind $dir to volume $vname
|
||||||
|
$dryrun docker volume create --driver local \
|
||||||
|
--opt type=none \
|
||||||
|
--opt device=$hostmp \
|
||||||
|
--opt o=bind "$vname" > /dev/null
|
||||||
|
[[ ! $dryrun ]] && echo directory $mp in container will be mounted at $hostmp
|
||||||
|
# else
|
||||||
|
# vname="try-$name-${mp//\//-}"
|
||||||
|
# hostmap="-e HOST_MAP=$(id -u):$(id -g)"
|
||||||
|
# dkpath=$(docker info | grep -i "Docker Root Dir" | cut -d':' -f2)/volumes/$vname/_data
|
||||||
|
# echo via volume $vname
|
||||||
|
# echo linking $dkpath to $hostmp
|
||||||
|
# $dryrun ln -s $dkpath -T $hostmp
|
||||||
|
# fi
|
||||||
fi
|
fi
|
||||||
|
|
||||||
echo starting container with image: $image, and name $name
|
echo starting container with image: $image, and name $name
|
||||||
echo at container prompt type \'exit\' to exit from shell and remove trial container
|
echo at container prompt type \'exit\' to exit from shell and remove trial container
|
||||||
|
|
||||||
docker run -i -t --rm $priv $evar $hostmap --entrypoint /opt/scripts/entrypoint.sh \
|
# --entrypoint /opt/scripts/entrypoint.sh \
|
||||||
|
$dryrun docker run -i -t --rm $priv $evar $hostmap $options \
|
||||||
$([[ $cuser ]] && echo "--user $cuser") \
|
$([[ $cuser ]] && echo "--user $cuser") \
|
||||||
--name try-$name --hostname try-$host-$name \
|
--name try-$name --hostname try-$host-$name \
|
||||||
$([[ $mp ]] && echo "-v $vname:/$mp") \
|
$([[ $mp ]] && echo "-v $vname:/$mp") \
|
||||||
"$image" \
|
"$image" \
|
||||||
"$@"
|
"$@"
|
||||||
echo "done with session, removing containter try-$name"
|
echo "done with session, removing containter try-$name"
|
||||||
if [[ $mp ]]; then
|
if [[ $mp ]] && [[ ! $dryrun ]]; then
|
||||||
if [[ ! $save ]]; then
|
# if [[ ! $save ]]; then
|
||||||
echo removing volume $vname used for mapping
|
echo removing volume $vname used for mapping
|
||||||
docker volume rm $vname > /dev/null
|
docker volume rm $vname > /dev/null
|
||||||
[[ ! $bind ]] && [[ -h $hostmp ]] && echo "removing link at $hostmp" && rm $hostmp
|
if [[ $keep ]]; then
|
||||||
|
echo mounted container directory $mp on host at $hostmp will not be removed
|
||||||
|
else
|
||||||
|
echo deleting directory at mountpoint $hostmp mapped to $mp in container
|
||||||
|
echo "use option -k to keep this directory after exiting container"
|
||||||
|
echo "useful for testing scripts inside the container"
|
||||||
|
rm -rf $hostmp
|
||||||
fi
|
fi
|
||||||
|
# [[ ! $bind ]] && [[ -h $hostmp ]] && echo "removing link at $hostmp" && rm $hostmp
|
||||||
|
# fi
|
||||||
fi
|
fi
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
64
readme.md
64
readme.md
|
@ -1,8 +1,23 @@
|
||||||
# UCI Docker Image Builder
|
# UCI Docker Image Builder
|
||||||
|
|
||||||
A build script plus associated library to facilitate building docker linux images using any of three distros (alpine,debian,ubuntu) and either architecture (amd64/arm64)
|
Prerequistes:
|
||||||
|
|
||||||
The Dockerfile is minimal, calling a set of distro specific scripts and common scripts in order to build the image
|
see https://hacking.kebler.net/Linux/Arch/docker/
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
<!-- assuming your current (dev) user is in the docker group
|
||||||
|
for linking into volumes for the try command
|
||||||
|
```
|
||||||
|
sudo chown -R :docker /var/lib/docker
|
||||||
|
sudo chmod -R g+r docker /var/lib/docker
|
||||||
|
``` -->
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
A build script plus associated library to facilitate building docker linux images using any of four distros (arch,alpine,debian,ubuntu) and either architecture (amd64/arm64)
|
||||||
|
|
||||||
|
The Dockerfile is minimal copying a directory and then calling a packages script and and init script in two RUN statements calling a set of distro specific scripts and common scripts in order to build the image
|
||||||
|
|
||||||
The build environment makes user of docker's "buildx bake" commands and a docker-bake.hcl file
|
The build environment makes user of docker's "buildx bake" commands and a docker-bake.hcl file
|
||||||
|
|
||||||
|
@ -10,17 +25,54 @@ The master branch is configured to build base images from the docker hub distro
|
||||||
|
|
||||||
The main script is "build" At the very minimum run as just `./build` it will build an alpine image from the docker hub official alpine latest image with a minimal set of packages installed (e.g. git) and a custom uci shell environment.
|
The main script is "build" At the very minimum run as just `./build` it will build an alpine image from the docker hub official alpine latest image with a minimal set of packages installed (e.g. git) and a custom uci shell environment.
|
||||||
|
|
||||||
|
To run the ./build script from other repos install it using the ./install install which just creates a link in /opt/bin
|
||||||
|
|
||||||
|
`ln -nsf $(dirname "$(realpath "$BASH_SOURCE")")/build /opt/bin/dbuild`
|
||||||
|
|
||||||
The repo also supports (with scripts) pushing to alternate private repositories packages (like a self hosted gitea or github)
|
The repo also supports (with scripts) pushing to alternate private repositories packages (like a self hosted gitea or github)
|
||||||
|
|
||||||
One can make decendent images in one of two way.
|
One can make decendent images in one of two ways.
|
||||||
|
|
||||||
1. Make your base images on the master branch then create a new branch and edit the script files in the src folder
|
1. Make your base images on the master branch (or a branch if you need to customize)
|
||||||
3. User the installer script (./install) to install to link the build script into your system path. Then clone the template branch
|
2. User the installer script (./install) to link the build script into your system path. Then clone the template branch
|
||||||
|
3.
|
||||||
|
|
||||||
|
|
||||||
the build script requires an init.sh file in a source directory for the scripts it will run while building a new image
|
the build script requires an init.sh file in a source directory for the scripts it will run while building a new image
|
||||||
by default that is `<source directory>/init.sh`. by default that source directory is `src/` relative to the current directory
|
by default that is `<source directory>/init.sh`. by default that source directory is `src/` relative to the current directory
|
||||||
|
|
||||||
|
|
||||||
|
```
|
||||||
|
Image Build Script: Creates one or more images using a target in the docker-bake.hcl file
|
||||||
|
USAGE: /opt/bin/dbuild <subcommand> <options> <build_target> <imagename, imageuser>
|
||||||
|
valid build_target: dev arm amd deploy private multi; default: dev
|
||||||
|
### subcommands:
|
||||||
|
try (runs try a container script, see try usage) /opt/bin/dbuild try -i
|
||||||
|
tag (runs image_tag script)
|
||||||
|
info get image info, info <arch, exists, id> nothing is all info in json
|
||||||
|
--- option switches (no argument):
|
||||||
|
-o do not overwrite an existing image (default), instead move it to a temporary timestamp tag
|
||||||
|
-i rebuild only the initialization RUN by busting the cache at that point
|
||||||
|
-v show verbose information about the build
|
||||||
|
-a (auto) do not prompt to continue build, by default will not prompt if non-interactive shell
|
||||||
|
-c after build try out the image by starting a container terminal therein, for dev target this is the default;
|
||||||
|
-x exclude distro from image name;
|
||||||
|
-n for --no_cache
|
||||||
|
-k keep the build scripts (see -w) after the build so they are incorporated into the image
|
||||||
|
-p push to repository; after build push to repository default is hub.docker.com (not need for deploy target)
|
||||||
|
--- options with argument <ARGUMENT>:
|
||||||
|
-e <path to environment file> load any or all of options below via a file
|
||||||
|
-d <LINUX_DISTRO> supported: alpine, debian, ubuntu, default: alpine; if base image set distro will be determined
|
||||||
|
-t <TAG> tag following : in output image name (i.e. REPO/USER/NAME:TAG), default: latest
|
||||||
|
-u <USER>; repository user prefix in output image name (i.e. REPO/USER/NAME:TAG)
|
||||||
|
-r <REPO>; private repo name, do not use for hub.docker.com (docker.io)
|
||||||
|
-b <BASE_IMAGE>; used in FROM in Dockerfile, default is official distro image (e.g. alpine:latest)
|
||||||
|
-w <BUILD_DIR>; set a custom WORKDIR in Dockerfile (in image), default is /build, see -k
|
||||||
|
--- options set ONLY by environment variable (see -e as well)
|
||||||
|
<SYSADMIN_PW> set alternate password for container sysadmin account, default is 'sysadmin'
|
||||||
|
NOTE any option with <CAPTIALIZED> above can be set in environment instead
|
||||||
|
#### examples:
|
||||||
|
/opt/bin/dbuild -a -d ubuntu -u ucommandit
|
||||||
|
build (without prompt) a local ubuntu image from scratch and label it ucommandit/ubuntu:latest
|
||||||
|
```
|
||||||
|
|
||||||
|
|
|
@ -1,2 +0,0 @@
|
||||||
bash
|
|
||||||
bash-completion
|
|
|
@ -1,27 +0,0 @@
|
||||||
#!/bin/bash
|
|
||||||
|
|
||||||
echo -e "\n##################################"
|
|
||||||
# add admin user
|
|
||||||
groupadd -g 1000 host
|
|
||||||
useradd -r -g host -u 1000 host
|
|
||||||
groupadd -g 1001 sysadmin
|
|
||||||
useradd -rm -s /bin/bash -G sudo,host -g sysadmin -u 1001 sysadmin
|
|
||||||
groups sysadmin
|
|
||||||
chpasswd <<<"sysadmin:${SYSADMIN_PW:-sysadmin}"
|
|
||||||
cp permitmod /etc/sudoers.d
|
|
||||||
chmod 440 /etc/sudoers.d/permitmod
|
|
||||||
|
|
||||||
git clone https://git.kebler.net/bash/shell-base.git /shell/base
|
|
||||||
/bin/bash /shell/base/install/install.sh sysadmin
|
|
||||||
# copy permenent scripts to /opt/scripts
|
|
||||||
/bin/bash -l -c "module_load dir; dir_copy scripts /opt"
|
|
||||||
source /opt/scripts/container.env
|
|
||||||
# make essential directories
|
|
||||||
mkdir -p $SHARED_DIRS /opt/scripts /opt/bin
|
|
||||||
# let the sysadmin user (1000) own these and group write
|
|
||||||
# install distro info screen
|
|
||||||
/bin/bash install-info.sh
|
|
||||||
chown -R sysadmin:sysadmin $SHARED_DIRS
|
|
||||||
chmod -R g+rw $SHARED_DIRS
|
|
||||||
# call distro info
|
|
||||||
/bin/bash -l -c "info"
|
|
|
@ -0,0 +1 @@
|
||||||
|
echo initialization script for archlinux distro
|
|
@ -0,0 +1,33 @@
|
||||||
|
#!/bin/bash
|
||||||
|
|
||||||
|
echo -e "\n##################################"
|
||||||
|
# which groupadd
|
||||||
|
# which useradd
|
||||||
|
# which /bin/bash
|
||||||
|
# echo SHELL $SHELL
|
||||||
|
|
||||||
|
groupadd -g 1000 host
|
||||||
|
useradd -r -g host -u 1000 host
|
||||||
|
groupadd -g 1001 sysadmin
|
||||||
|
useradd -rm -s /bin/bash -G host,$([[ $(getent group sudo) ]] && echo sudo || echo wheel) -g sysadmin -u 1001 sysadmin
|
||||||
|
echo sysadmin groups: $(groups sysadmin)
|
||||||
|
chpasswd <<<"sysadmin:${SYSADMIN_PW:-sysadmin}"
|
||||||
|
cp permitmod /etc/sudoers.d
|
||||||
|
chmod 440 /etc/sudoers.d/permitmod
|
||||||
|
|
||||||
|
git clone https://git.kebler.net/bash/shell-base.git /shell/base
|
||||||
|
export SHELL=/bin/bash
|
||||||
|
mkdir -p /home/sysadmin/shell
|
||||||
|
/bin/bash /shell/base/install/install.sh sysadmin
|
||||||
|
echo "******** uci shell install complete **********"
|
||||||
|
/bin/bash -l -c "module_load dir; dir_copy scripts /opt"
|
||||||
|
echo installed scripts in /opt/scripts
|
||||||
|
ls -la /opt/scripts
|
||||||
|
source /opt/scripts/container.env
|
||||||
|
# make essential directories
|
||||||
|
mkdir -p $SHARED_DIRS /opt/scripts /opt/bin
|
||||||
|
chown -R host:host /home/sysadmin/shell $SHARED_DIRS /opt/scripts /opt/bin
|
||||||
|
chmod -R g+rw /home/sysadmin/shell $SHARED_DIRS /opt/scripts /opt/bin
|
||||||
|
echo installing and running image distro info
|
||||||
|
/bin/bash install-info.sh
|
||||||
|
/opt/scripts/info
|
|
@ -4,6 +4,6 @@ apk update; apk upgrade;
|
||||||
pwd; ls -la
|
pwd; ls -la
|
||||||
echo ">>>> installing packages => alpine: $(cat ./packages); common: $(cat ../common/packages)"
|
echo ">>>> installing packages => alpine: $(cat ./packages); common: $(cat ../common/packages)"
|
||||||
apk add --no-cache bash bash-completion $(cat ./packages) $(cat ../common/packages)
|
apk add --no-cache bash bash-completion $(cat ./packages) $(cat ../common/packages)
|
||||||
# apk add bindfs --repository=http://dl-cdn.alpinelinux.org/alpine/edge/testing
|
|
||||||
# needed for useradd and groupadd
|
# needed for useradd and groupadd
|
||||||
apk add shadow --repository=http://dl-2.alpinelinux.org/alpine/edge/community
|
apk add shadow --no-cache --repository=http://dl-2.alpinelinux.org/alpine/edge/community
|
||||||
|
# apk add bindfs --repository=http://dl-cdn.alpinelinux.org/alpine/edge/testing
|
|
@ -0,0 +1,8 @@
|
||||||
|
#!/bin/sh
|
||||||
|
echo install packages for archlinux distro
|
||||||
|
pacman -Syu
|
||||||
|
pwd; ls -la
|
||||||
|
echo ">>>> installing packages => arch: $(cat ./packages); common: $(cat ../common/packages)"
|
||||||
|
pacman -S --needed --noconfirm $(cat ./packages) $(cat ../common/packages)
|
||||||
|
pacman -Scc --noconfirm
|
||||||
|
|
|
@ -1,6 +1,5 @@
|
||||||
#!/bin/bash
|
#!/bin/bash
|
||||||
echo install packages for ubuntu distro
|
echo install packages for ubuntu distro
|
||||||
apt-get update
|
apt-get update
|
||||||
echo ">>>> installing packages => $(cat packages) $(cat common-packages)"
|
echo ">>>> installing packages => $(cat packages) $(cat ../common/packages)"
|
||||||
apt-get install $(cat packages) $(cat ../common/packages) -y
|
apt-get install $(cat packages) $(cat ../common/packages) -y
|
||||||
# ./add-ppa.sh -i -p git git-core/ppa
|
|
|
@ -1,5 +1,5 @@
|
||||||
#!/bin/sh
|
#!/bin/sh
|
||||||
echo "installing packages...."
|
echo "installing packages.... for $LINUX_DISTRO"
|
||||||
cd ${LINUX_DISTRO} || exit 1
|
cd ${LINUX_DISTRO} || exit 1
|
||||||
/bin/sh packages.sh
|
/bin/sh packages.sh
|
||||||
cd ..
|
cd ..
|
|
@ -0,0 +1,117 @@
|
||||||
|
#!/bin/bash
|
||||||
|
add-ppa () {
|
||||||
|
|
||||||
|
if [ $EUID != 0 ]; then
|
||||||
|
sudo bash -c "$(declare -f add-ppa); add-ppa $*"
|
||||||
|
else
|
||||||
|
VERSION=jammy
|
||||||
|
KEYSDIR=/etc/apt/trusted.gpg.d
|
||||||
|
KEYSERVER=keyserver.ubuntu.com
|
||||||
|
|
||||||
|
declare OPTION; declare OPTARG; declare OPTIND
|
||||||
|
while getopts 'v:p:s:k:c:d:oi' OPTION; do
|
||||||
|
echo processing: option:$OPTION argument:$OPTARG index:$OPTIND remaining:${@:$OPTIND}
|
||||||
|
case "$OPTION" in
|
||||||
|
i)
|
||||||
|
INSTALL=true
|
||||||
|
;;
|
||||||
|
v)
|
||||||
|
VERSION=$OPTARG
|
||||||
|
;;
|
||||||
|
p)
|
||||||
|
PACKAGE=$OPTARG
|
||||||
|
;;
|
||||||
|
c)
|
||||||
|
CMD=$OPTARG
|
||||||
|
;;
|
||||||
|
d)
|
||||||
|
KEYSDIR=$OPTARG
|
||||||
|
;;
|
||||||
|
s)
|
||||||
|
KEYSERVER=$OPTARG
|
||||||
|
;;
|
||||||
|
o)
|
||||||
|
# overwrite any exising public key
|
||||||
|
KEYOVERWRITE=true
|
||||||
|
;;
|
||||||
|
*) echo unknown run option -$OPTARG
|
||||||
|
echo "USAGE: add-ppa <options> package/branch (e.g. git-core/ppa)"
|
||||||
|
echo "available options -v <ubnutu version name - default Jammy>; -p <apt install package name if not the same>"
|
||||||
|
;;
|
||||||
|
esac
|
||||||
|
done
|
||||||
|
|
||||||
|
shift $((OPTIND - 1))
|
||||||
|
|
||||||
|
#check input
|
||||||
|
if [ -z ${1+x} ]; then
|
||||||
|
echo "No ppa provided!"
|
||||||
|
return 1
|
||||||
|
fi
|
||||||
|
|
||||||
|
LAUNCHPAD="https://ppa.launchpadcontent.net"
|
||||||
|
DEV=$(echo $1 | cut -d ':' -f 2 | cut -d '/' -f1 )
|
||||||
|
PACKAGE=${PACKAGE:-$DEV}
|
||||||
|
CMD=${CMD:-$PACKAGE}
|
||||||
|
BRANCH=${2:-$(echo $1| cut -d '/' -f 2)}
|
||||||
|
URL="$LAUNCHPAD/$DEV/$BRANCH/ubuntu $VERSION main"
|
||||||
|
|
||||||
|
echo "*********** Adding PPA Repository ************"
|
||||||
|
echo DEVELOPER: $DEV
|
||||||
|
echo BRANCH: $BRANCH
|
||||||
|
echo PACKAGE: $PACKAGE
|
||||||
|
echo COMMAND: $CMD
|
||||||
|
echo URL: $URL
|
||||||
|
|
||||||
|
if [[ -t 0 ]]; then
|
||||||
|
read -n 1 -p "do you want to continue [y]=>" REPLY
|
||||||
|
[[ $REPLY != "y" ]] && return 0
|
||||||
|
fi
|
||||||
|
|
||||||
|
echo -e "\n*********************************************"
|
||||||
|
#create source list file
|
||||||
|
echo "deb $URL" > /etc/apt/sources.list.d/$DEV.list
|
||||||
|
echo "***** added /etc/apt/sources.list.d/$DEV.list with****"
|
||||||
|
cat /etc/apt/sources.list.d/$DEV.list
|
||||||
|
echo "*********************************************"
|
||||||
|
|
||||||
|
KEYFILE=$KEYSDIR/$DEV.gpg
|
||||||
|
|
||||||
|
[[ $KEYOVERWRITE ]] && rm $KEYFILE
|
||||||
|
if [ ! -f $KEYFILE ]; then
|
||||||
|
# using an update error to grab key id
|
||||||
|
KEY_ERROR=/tmp/${DEV}_key_error
|
||||||
|
touch $KEY_ERROR
|
||||||
|
apt-get update > /dev/null 2> $KEY_ERROR
|
||||||
|
cat $KEY_ERROR
|
||||||
|
KEY=$(sed -n 's/^.*NO_PUBKEY //p' "$KEY_ERROR" | head -1)
|
||||||
|
# echo Reposity Public Key Settings
|
||||||
|
# echo KEYS DIRECTORY: $KEYSDIR
|
||||||
|
# echo KEY SERVER: $KEYSERVER
|
||||||
|
# echo KEY: $KEY
|
||||||
|
if [ ! $KEY ]; then
|
||||||
|
echo can not determine $DEV/$BRANCH key sign
|
||||||
|
echo "removing file: /etc/apt/sources.list.d/$DEV.list and aborting"
|
||||||
|
rm /etc/apt/sources.list.d/$DEV.list
|
||||||
|
return 1
|
||||||
|
fi
|
||||||
|
echo downloading and saving public key $KEY for $DEV/$BRANCH to $KEYFILE
|
||||||
|
gpg --keyserver $KEYSERVER --recv $KEY
|
||||||
|
gpg --export $KEY > $KEYFILE
|
||||||
|
else
|
||||||
|
echo " >>>>>> $KEYFILE already exists, using that key $KEY <<<<<"
|
||||||
|
fi
|
||||||
|
echo ppa repo $DEV/$BRANCH for package $PACKAGE now registered, updating...
|
||||||
|
apt-get update 1> /dev/null
|
||||||
|
if [[ $INSTALL ]]; then
|
||||||
|
echo installing $PACKAGE
|
||||||
|
[[ -t 0 ]] && apt policy $PACKAGE
|
||||||
|
apt-get install $PACKAGE -y
|
||||||
|
$CMD --version
|
||||||
|
fi
|
||||||
|
fi
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
# # if script was executed then call the function
|
||||||
|
(return 0 2>/dev/null) || add-ppa $@
|
|
@ -1,6 +1,6 @@
|
||||||
#!/bin/bash
|
#!/bin/bash
|
||||||
echo install packages for ubuntu distro
|
echo install packages for ubuntu distro
|
||||||
apt-get update
|
apt-get update
|
||||||
echo ">>>> installing packages => $(cat packages) $(cat common-packages)"
|
echo ">>>> installing packages => $(cat packages) $(cat ../common/packages)"
|
||||||
apt-get install $(cat packages) $(cat ../common/packages) -y
|
apt-get install $(cat packages) $(cat ../common/packages) -y
|
||||||
/bin/bash add-ppa.sh -i -p git git-core/ppa
|
./add-ppa.sh -i -p git git-core/ppa
|
Loading…
Reference in New Issue