From 691e5915b9ecb350918acaecc2d052f8f88d7ecd Mon Sep 17 00:00:00 2001 From: Thomas Woerner <twoerner@redhat.com> Date: Mon, 16 Sep 2024 14:30:24 +0200 Subject: [PATCH] New infra/image/start.sh script to start the generated containers The script will try to get the latest image from quay to start it. With the -l option it will try to use a local image first. This is for example useful to test changes in the images build script locally. This also adds infra/image/shcontainer. Some of the content is copied from utils/shcontainer. --- infra/image/shcontainer | 166 ++++++++++++++++++++++++++++++++++++++++ infra/image/start.sh | 87 +++++++++++++++++++++ 2 files changed, 253 insertions(+) create mode 100644 infra/image/shcontainer create mode 100755 infra/image/start.sh diff --git a/infra/image/shcontainer b/infra/image/shcontainer new file mode 100644 index 0000000..6f4e8a8 --- /dev/null +++ b/infra/image/shcontainer @@ -0,0 +1,166 @@ +#!/bin/bash -eu +# This file is meant to be source'd by other scripts + +SCRIPTDIR="$(dirname -- "$(readlink -f "${BASH_SOURCE[0]}")")" +TOPDIR="$(readlink -f "${SCRIPTDIR}/../..")" + +. "${TOPDIR}/utils/shfun" + +container_create() { + local name=${1} + local image=${2} + local hostname=${3} + local memory=${4:-"3g"} + local cpus=${5:-"2"} + + [ -n "${hostname}" ] || die "No hostname given" + + log info "= Creating ${name} =" + podman create \ + --security-opt label=disable \ + --name "${name}" \ + --hostname "${hostname}" \ + --network bridge:interface_name=eth0 \ + --systemd true \ + --cpus "${cpus}" \ + --memory "${memory}" \ + --memory-swap -1 \ + --no-hosts \ + --replace \ + "${image}" + echo +} + +container_start() { + local name="${1}" + + log info "= Starting ${name} =" + podman start "${name}" + echo +} + +container_stop() { + local name="${1}" + + log info "= Stopping ${name} =" + podman stop "${name}" + echo +} + +container_wait_for_journald() { + local name=${1} + + log info "= Waiting till systemd-journald is running =" + max=20 + wait=2 + count=0 + while ! podman exec "${name}" ps -x | grep -q "systemd-journald" + do + if [ $count -ge $max ]; then + die "Timeout: systemd-journald is not starting up" + fi + count=$((count+1)) + log info "Waiting ${wait} seconds .." + sleep ${wait} + done + log info "done" + echo +} + +container_wait_up() { + local name="${1}" + + log info "= Waiting till all services are started =" + max=20 + wait=15 + count=0 + while podman exec "${name}" systemctl list-jobs | \ + grep -qvi "no jobs running" + do + if [ $count -ge $max ]; then + die "Timeout: Services are not starting up" + fi + count=$((count+1)) + log info "Waiting ${wait} seconds .." + sleep ${wait} + done + log info "done" + echo +} + +container_build() { + local tag="${1}" + local file="${2}" + local dir="${3}" + + log info "= Building ${tag} =" + podman build -t "${tag}" -f "${file}" "${dir}" + echo +} + +container_commit() { + local name="${1}" + local image="${2}" + + log info "= Committing \"${image}\" =" + podman commit "${name}" "${image}" + echo +} + +container_exec() { + local name="${1}" + shift 1 + + # "@Q" is only needed for the log output, the exec command is properly + # working without also for args containing spaces. + log info "= Executing \"${*@Q}\" =" + podman exec -t "${name}" "${@}" + echo +} + +container_remove_image_if_exists() +{ + # In older (as in Ubuntu 22.04) podman versions, + # 'podman image rm --force' fails if the image + # does not exist. + local tag_to_remove="${1}" + + if podman image exists "${tag_to_remove}" + then + log info "= Cleanup ${tag_to_remove} =" + podman image rm "${tag_to_remove}" --force + echo + fi +} + +container_get_state() +{ + local name="${1}" + + state=$(podman ps -q --all --format "{{.State}}" --filter "name=${name}") + echo "${state}" +} + +container_pull() { + local source="${1}" + + image=$(podman pull "${source}") + echo "${image}" +} + +container_image_list() { + local source="${1}" + + # Append "$" for an exact match if the source does not end with ":" to + # search for the repo only. + if [[ ${source} != *: ]]; then + source="${source}$" + fi + image=$(podman image list --format "{{ .Repository }}:{{ .Tag }}" | \ + grep "^${source}") + echo "${image}" +} + +container_check() { + [ -n "$(command -v "podman")" ] || die "podman is required." +} diff --git a/infra/image/start.sh b/infra/image/start.sh new file mode 100755 index 0000000..c5a7a34 --- /dev/null +++ b/infra/image/start.sh @@ -0,0 +1,87 @@ +#!/bin/bash -eu + +BASEDIR="$(readlink -f "$(dirname "$0")")" +TOPDIR="$(readlink -f "${BASEDIR}/../..")" + +# shellcheck disable=SC1091 +. "${BASEDIR}/shcontainer" +# shellcheck disable=SC1091 +. "${TOPDIR}/utils/shfun" + +usage() { + local prog="${0##*/}" + cat << EOF +usage: ${prog} [-h] [-l] image + ${prog} start a prebuilt ansible-freeipa test container image. +EOF +} + +help() { + cat << EOF +positional arguments: + + image The image to start, leave empty to get list of images + +optional arguments: + + -l Try to use local image first, if not found download. + +EOF +} + +list_images() { + local quay_api="https://quay.io/api/v1/repository/ansible-freeipa/upstream-tests/tag" + log info "Available images on quay:" + curl --silent -L "${quay_api}" | jq '.tags[]|.name' | tr -d '"'| sort | uniq | sed "s/.*/ &/" + echo + log info "Local images (use -l):" + local_image=$(container_image_list "${repo}:") + echo "${local_image}" | sed -e "s/.*://" | sed "s/.*/ &/" + echo +} + +repo="quay.io/ansible-freeipa/upstream-tests" +name="ansible-freeipa-tests" +hostname="ipaserver.test.local" +try_local_first="N" + +while getopts ":hl" option +do + case "${option}" in + h) help && exit 0 ;; + l) try_local_first="Y" ;; + *) die -u "Invalid option: ${option}" ;; + esac +done + +shift $((OPTIND - 1)) +image=${1:-} + +container_check + +if [ -z "${image}" ]; then + list_images + exit 0 +fi + +local_image= +if [ "${try_local_first}" == "Y" ]; then + log info "= Trying to use local image first =" + local_image=$(container_image_list "${repo}:${image}") + [ -n "${local_image}" ] && log info "Found ${local_image}" + echo +fi +if [ -z "${local_image}" ]; then + log info "= Downloading from quay =" + local_image=$(container_pull "${repo}:${image}") + echo +fi + +[ -z "${local_image}" ] && die "Image '${image}' is not valid" + +container_create "${name}" "${local_image}" "${hostname}" +container_start "${name}" +container_wait_for_journald "${name}" +container_wait_up "${name}" + +log info "Container ${name} is ready to be used." -- GitLab