4 changed files with 185 additions and 1328 deletions
@ -1,98 +1,121 @@ |
|||||
#!/bin/bash |
#!/bin/bash |
||||
################################################################################ |
################################################################################ |
||||
# Functions/variables |
set -eEuo pipefail |
||||
quit() { |
err=0 |
||||
if [[ $1 == 0 || $FLAGS_debug == $FLAGS_FALSE ]]; then |
trap 'err=$?' ERR |
||||
podman rm -i -f tmp-$epoch 2>&1 > /dev/null |
trap 'cleanup' EXIT |
||||
fi |
|
||||
exit $1 |
|
||||
} |
|
||||
|
|
||||
epoch=$(date +%s.%3N) |
epoch=$(date +%s.%3N) |
||||
today=$(date +%Y-%m-%d-T%H%M) |
today=$(date +%Y-%m-%d-T%H%M) |
||||
|
|
||||
# Handle flags |
badarg() { |
||||
source shflags |
echo -n "$(basename $0): " |
||||
DEFINE_boolean 'squash' false 'squash newly built layers into a single new layer' 's' |
echo "$1" |
||||
DEFINE_boolean 'debug' false "Don't delete temporary container on build fail" 'd' |
echo "Try '$(basename $0) -h' for more information." |
||||
DEFINE_string 'tag' 'latest' 'Tag (other than date) to assign to the image' 't' |
exit 2 |
||||
|
} |
||||
|
|
||||
|
cleanup() { |
||||
|
if [[ $err -eq 0 || $opt_debug -eq 0 ]]; then |
||||
|
podman rm -i -f tmp-$epoch 2>&1 > /dev/null |
||||
|
fi |
||||
|
} |
||||
|
|
||||
|
help="Usage: $(basename $0) [-sdh] [-t tag] [directory] [name] |
||||
|
Builds an image from files in a directory, and assigns it a name. |
||||
|
|
||||
|
Files used are 'Containerfile' and optionally 'Systemdfile'. If first argument |
||||
|
is omitted, script assumes files can be found in the current working directory. |
||||
|
If second argument is omitted, the directory where the files were found is used |
||||
|
as the image name. |
||||
|
|
||||
FLAGS_HELP="Usage: $(basename $0) [-sd] [-t tag] [directory] [name] |
Options: |
||||
|
-s Squash all newly built layers in the image into a single layer |
||||
|
-d Debug mode: don't delete the temporary container created by the script |
||||
|
when encountering an error |
||||
|
-t [tag] Tag the image with the given string. Can be used multiple times to assign |
||||
|
the image multiple tags |
||||
|
-h Display this help and exit" |
||||
|
|
||||
Builds an image from the Containerfile and (optionally) Systemdfile in the |
# Handle options |
||||
specified directory, and tags the image with the given name. If no directory |
opt_squash=0 |
||||
argument is given, the current working directory is used. If no name argument |
opt_debug=0 |
||||
is given, the image is named after the directory. |
opt_tags=() |
||||
" |
while getopts ':sdt:h' arg; do |
||||
FLAGS "$@" || exit $? |
case $arg in |
||||
eval set -- "${FLAGS_ARGV}" |
s) opt_squash=1;; |
||||
|
d) opt_debug=1;; |
||||
|
t) opt_tags+=("${OPTARG}");; |
||||
|
h) echo "$help"; exit 0;; |
||||
|
:) badarg "Argument missing for option '-$OPTARG'";; |
||||
|
?) badarg "Invalid option '-$OPTARG'";; |
||||
|
esac |
||||
|
done |
||||
|
|
||||
# Handle errors/arguments/cases |
echo "${opt_tags[*]}" |
||||
|
exit 0 |
||||
|
|
||||
|
# Handle non-option arguments |
||||
if [[ $# -gt 2 ]]; then |
if [[ $# -gt 2 ]]; then |
||||
echo "Error: too many arguments" |
badarg "Too many arguments" |
||||
echo "" |
|
||||
flags_help |
|
||||
exit 1 |
|
||||
fi |
fi |
||||
|
|
||||
if [[ -n $1 ]]; then |
if [[ -n $1 ]]; then |
||||
directory=$1 |
directory="$1" |
||||
else |
else |
||||
directory=$(pwd) |
directory=$(pwd) |
||||
fi |
fi |
||||
|
|
||||
if [[ ! -d $directory ]]; then |
|
||||
echo "Error: directory \"$directory\" not found" |
if [[ -n $2 ]]; then |
||||
echo "" |
name="$2" |
||||
flags_help |
|
||||
exit 1 |
|
||||
else |
else |
||||
cd $directory |
name=$(basename "$directory") |
||||
fi |
fi |
||||
|
|
||||
if [[ -n $2 ]]; then |
# Main |
||||
name=$2 |
if [[ ! -d "$directory" ]]; then |
||||
|
echo "Error: directory '$directory' not found" |
||||
|
exit 1 |
||||
else |
else |
||||
name=$(basename $(pwd)) |
cd "$directory" |
||||
fi |
fi |
||||
|
|
||||
# build options |
|
||||
buildopts="" |
buildopts="" |
||||
if [[ $FLAGS_squash == $FLAGS_TRUE ]]; then |
if [[ $opt_squash -eq 1 ]]; then |
||||
buildopts="$buildopts --squash" |
buildopts="$buildopts --squash" |
||||
fi |
fi |
||||
|
|
||||
# Main |
|
||||
|
|
||||
# tell buildah to build images in docker format instead of the default OCI format |
# tell buildah to build images in docker format instead of the default OCI format |
||||
# because only docker-format images can use the SHELL directive in Containerfiles |
# because only docker-format images can use the SHELL directive in Containerfiles |
||||
export BUILDAH_FORMAT=docker |
export BUILDAH_FORMAT=docker |
||||
|
|
||||
# build image |
# build image |
||||
echo "Building image ..." |
echo "Building image ..." |
||||
podman build -f Containerfile -t tmp-$epoch $buildopts || quit $? |
podman build -f Containerfile -t tmp-$epoch $buildopts |
||||
|
|
||||
# Systemdfile is for commands that need systemd to execute |
# Systemdfile is for commands that need systemd to execute |
||||
if [[ -f Systemdfile ]]; then |
if [[ -f Systemdfile ]]; then |
||||
echo "Running build steps that require systemd ..." |
echo "Running build steps that require systemd ..." |
||||
echo "Creating container ..." |
echo "Creating temporary container ..." |
||||
podman create --name tmp-$epoch tmp-$epoch || quit $? |
podman create --name tmp-$epoch tmp-$epoch |
||||
podman start tmp-$epoch || quit $? |
podman start tmp-$epoch |
||||
echo "Copying script to container ..." |
echo "Copying script to container ..." |
||||
podman cp Systemdfile tmp-$epoch:/root/ |
podman cp Systemdfile tmp-$epoch:/root/ |
||||
echo "Running script ..." |
echo "Running script ..." |
||||
podman exec tmp-$epoch bash -c "chmod +x /root/Systemdfile && /root/Systemdfile" || quit $? |
podman exec tmp-$epoch bash -c "chmod +x /root/Systemdfile && /root/Systemdfile" |
||||
echo "Committing container to image ..." |
echo "Committing container to image ..." |
||||
podman commit tmp-$epoch $name:$today || quit $? |
podman commit tmp-$epoch "$name:$today" |
||||
else |
else |
||||
echo "Systemdfile not found, skipping container creation ..." |
echo "Systemdfile not found, skipping temporary container step ..." |
||||
# tag image we already built with appropriate tag, and untag with tmp |
# tag image we already built with appropriate tag, and untag with tmp |
||||
podman tag tmp-$epoch $name:$today |
podman tag tmp-$epoch "$name:$today" |
||||
podman rmi tmp-$epoch |
podman rmi tmp-$epoch |
||||
fi |
fi |
||||
|
|
||||
# tag with latest tag |
# assign any extra tags |
||||
podman tag $name:$today $name:$FLAGS_tag |
for tag in "${opt_tags[@]}"; do |
||||
echo "Done!" |
podman tag "$name:$today" "$name:$tag" |
||||
|
done |
||||
|
|
||||
quit 0 |
echo "Done!" |
||||
|
@ -1,59 +1,79 @@ |
|||||
#!/bin/bash |
#!/bin/bash |
||||
################################################################################ |
################################################################################ |
||||
# Handle flags |
set -eEuo pipefail |
||||
source shflags |
|
||||
DEFINE_boolean 'overwrite' false 'Overwrite container if one with same name already exists.' 'o' |
badarg() { |
||||
DEFINE_boolean 'config' false 'Automatically configure container with deploy options stored in image metadata.' 'c' |
echo -n "$(basename $0): " |
||||
DEFINE_string 'label' 'deployopts' 'Image metadata label from which to get the deploy options.' 'l' |
echo "$1" |
||||
|
echo "Try '$(basename $0) -h' for more information." |
||||
FLAGS_HELP="Usage: $(basename $0) [-oc] [-d label] [image] [name] |
exit 2 |
||||
|
} |
||||
Creates and starts a container from the specified image, and assigns it the |
|
||||
specified name. If no image argument is given, uses the current working |
help="Usage: $(basename $0) [-fch] [-l label] [-e options] image [container] |
||||
directory as the name of the image. If no name argument is given, the container |
Create and start a container from a local image, and assign it the given name. |
||||
is given the same name as the image. |
|
||||
" |
If second argument is omitted, defaults to assigning the container the same name |
||||
FLAGS "$@" || exit $? |
as the image. |
||||
eval set -- "${FLAGS_ARGV}" |
|
||||
|
|
||||
# Handle errors/arguments/cases |
|
||||
if [[ $# -gt 2 ]]; then |
|
||||
echo "Error: too many arguments" |
|
||||
echo "" |
|
||||
flags_help |
|
||||
exit 1 |
|
||||
fi |
|
||||
|
|
||||
if [[ -n $1 ]]; then |
Options: |
||||
image=$1 |
-f Force overwrite if a container with the given name already exists |
||||
|
-c Configure the container with deploy options stored in the image |
||||
|
metadata. By default, uses the metadata tag labeled 'config_default' |
||||
|
-l [label] Label from which to get the deploy options. Automatically sets -c |
||||
|
-e [options] Extra deploy options to assign to the container. If -e and -c are |
||||
|
both used, options from image metadata and command line are combined |
||||
|
-h Display this help and exit" |
||||
|
|
||||
|
# Handle options |
||||
|
opt_force=0 |
||||
|
opt_config=0 |
||||
|
opt_label='config_default' |
||||
|
opt_extras='' |
||||
|
while getopts ':fcl:e:h' arg; do |
||||
|
case $arg in |
||||
|
f) opt_force=1;; |
||||
|
c) opt_config=1;; |
||||
|
l) opt_config=1; opt_label="${OPTARG}";; |
||||
|
e) opt_extras="${OPTARG}";; |
||||
|
h) echo "$help"; exit 0;; |
||||
|
:) badarg "Argument missing for option '-$OPTARG'";; |
||||
|
?) badarg "Invalid option '-$OPTARG'";; |
||||
|
esac |
||||
|
done |
||||
|
|
||||
|
# Handle non-option arguments |
||||
|
if [[ $# -lt 1 ]]; then |
||||
|
badarg "Missing image name" |
||||
else |
else |
||||
echo "Warning: No image name given. Assuming image name from current working directory." |
image="$1" |
||||
image=$(basename $(pwd)) |
fi |
||||
|
|
||||
|
if [[ $# -gt 2 ]]; then |
||||
|
badarg "Too many arguments" |
||||
fi |
fi |
||||
|
|
||||
if [[ -n $2 ]]; then |
if [[ -n $2 ]]; then |
||||
name=$2 |
container="$2" |
||||
else |
else |
||||
name=$image |
container="$image" |
||||
fi |
fi |
||||
|
|
||||
# Main |
# Main |
||||
set -e |
if [[ $opt_config -eq 1 ]]; then |
||||
|
echo "Getting deploy options from image metadata label '$opt_label' ..." |
||||
if [[ $FLAGS_config -eq $FLAGS_TRUE ]]; then |
deployconf=$(podman image inspect -f "{{ .Config.Labels.${opt_label} }}" "$image") |
||||
echo "Getting deploy options from image metadata label \"$FLAGS_label\" ..." |
if [[ $config == "<no value>" ]]; then |
||||
deployopts=$(podman image inspect -f "{{ .Config.Labels.${FLAGS_label} }}" $image) |
echo "Error: could not find image metadata label '$opt_label'" |
||||
if [[ $deployopts == "<no value>" ]]; then |
exit 1 |
||||
echo "Error: image metadata label \"$FLAGS_label\" is empty or nonexistent." |
fi |
||||
exit 2 |
|
||||
fi |
|
||||
else |
else |
||||
deployopts="" |
deployconf="" |
||||
fi |
fi |
||||
|
deployconf="$deployconf $opts_extras" |
||||
|
|
||||
if [[ $FLAGS_overwrite -eq $FLAGS_TRUE ]]; then |
if [[ $opt_force -eq 1 ]]; then |
||||
podman rm -i -f $name |
podman rm -i -f "$container" |
||||
fi |
fi |
||||
|
|
||||
podman run -itd --name $name --hostname $name $deployopts $image |
podman run -itd --name "$container" --hostname "$container" $deployconf "$image" |
||||
echo "Done!" |
echo "Done!" |
||||
|
@ -1,18 +1,48 @@ |
|||||
#!/bin/bash |
#!/bin/bash |
||||
|
################################################################################ |
||||
|
set -eEuo pipefail |
||||
|
|
||||
if [[ -z $1 || $1 == "-h" || $1 == "--help" ]]; then |
badarg() { |
||||
echo "Usage: $(basename $0) container [command] |
echo -n "$(basename $0): " |
||||
|
echo "$1" |
||||
|
echo "Try '$(basename $0) -h' for more information." |
||||
|
exit 2 |
||||
|
} |
||||
|
|
||||
Runs a bash shell on the given container. If second argument is |
help="Usage: $(basename $0) [-h] container [command] |
||||
omitted, an interactive login shell is launched. If second argument |
Runs a bash shell on the given container. |
||||
is given, the string is interpreted as a command and executed directly. |
|
||||
To ensure that any shell syntax is evaluated in the container shell |
If the second argument is omitted, an interactive login shell is launched. If the |
||||
instead of the local shell, wrap your command in single quotes." |
second argument is present, the string is interpreted as a command and executed |
||||
exit 1 |
directly. To ensure that any shell syntax is evaluated in the container shell |
||||
|
instead of the host shell, make sure to wrap your string in single quotes. |
||||
|
|
||||
|
Options: |
||||
|
-h Display this help and exit" |
||||
|
|
||||
|
# Handle options |
||||
|
while getopts ':h' arg; do |
||||
|
case $arg in |
||||
|
h) echo "$help"; exit 0;; |
||||
|
:) badarg "Argument missing for option '-$OPTARG'";; |
||||
|
?) badarg "Invalid option '-$OPTARG'";; |
||||
|
esac |
||||
|
done |
||||
|
|
||||
|
# Handle non-option arguments |
||||
|
if [[ $# -lt 1 ]]; then |
||||
|
badarg "Missing container name" |
||||
|
else |
||||
|
container="$1" |
||||
|
fi |
||||
|
|
||||
|
if [[ $# -gt 2 ]]; then |
||||
|
badarg "Too many arguments" |
||||
fi |
fi |
||||
|
|
||||
|
# Main |
||||
if [[ -z $2 ]]; then |
if [[ -z $2 ]]; then |
||||
podman exec -it $1 bash -l |
podman exec -it "$container" bash -l |
||||
else |
else |
||||
podman exec -it $1 bash -c "${*:2}" |
podman exec -it "$container" bash -c "${@:2}" |
||||
fi |
fi |
||||
|
File diff suppressed because it is too large
Loading…
Reference in new issue