#!/usr/bin/env bash load 'libs/bats-support/load' # Podman and Toolbox commands to run readonly PODMAN=${PODMAN:-podman} readonly TOOLBOX=${TOOLBOX:-toolbox} readonly SKOPEO=$(command -v skopeo) # Helpful globals readonly IMAGE_CACHE_DIR="${BATS_RUN_TMPDIR}/image-cache" # Images declare -Ag IMAGES=([busybox]="quay.io/toolbox_tests/busybox" \ [fedora]="registry.fedoraproject.org/fedora-toolbox" \ [rhel]="registry.access.redhat.com/ubi8") function cleanup_all() { $PODMAN system reset --force >/dev/null } function cleanup_containers() { $PODMAN rm --all --force >/dev/null } # Pulls an image using Podman and saves it to a image dir using Skopeo # # Parameters # ========== # - distro - os-release field ID (e.g., fedora, rhel) # - version - os-release field VERSION_ID (e.g., 33, 34, 8.4) # # Only use during test suite setup for caching all images to be used throught # tests. function _pull_and_cache_distro_image() { local num_of_retries=5 local timeout=10 local pulled=false local distro local version local image local image_archive distro="$1" version="$2" if [ ! -v IMAGES[$distro] ]; then fail "Requested distro (${distro}) does not have a matching image" fi image="${IMAGES[$distro]}" image_archive="${distro}-toolbox" if [[ $# -eq 2 ]]; then image="${image}:${version}" image_archive="${image_archive}-${version}" fi for ((i = ${num_of_retries}; i > 0; i--)); do run $PODMAN pull ${image} if [ "$status" -eq 0 ]; then pulled=true break fi sleep $timeout done if ! $pulled; then echo "Failed to pull image ${image}" assert_success fi if [ ! -d ${IMAGE_CACHE_DIR} ]; then mkdir -p ${IMAGE_CACHE_DIR} fi run $SKOPEO copy --dest-compress containers-storage:${image} dir:${IMAGE_CACHE_DIR}/${image_archive} if [ "$status" -ne 0 ]; then echo "Failed to cache image ${image} to ${IMAGE_CACHE_DIR}/${image_archive}" assert_success fi cleanup_all } # Removes the folder with cached images function _clean_cached_images() { rm -rf ${IMAGE_CACHE_DIR} } # Copies an image from local storage to Podman's image store # # Call before creating any container. Network failures are not nice. # # An image has to be cached first. See _pull_and_cache_distro_image() # # Parameters: # =========== # - distro - os-release field ID (e.g., fedora, rhel) # - version - os-release field VERSION_ID (e.g., 33, 34, 8.4) function pull_distro_image() { local distro local version local image local image_archive distro="$1" version="$2" if [ ! -v IMAGES[$distro] ]; then fail "Requested distro (${distro}) does not have a matching image" fi image="${IMAGES[$distro]}" image_archive="${distro}-toolbox" if [[ -n $version ]]; then image="${image}:${version}" image_archive="${image_archive}-${version}" fi # No need to copy if the image is already available in Podman run $PODMAN image exists ${image} if [[ "$status" -eq 0 ]]; then return fi run $SKOPEO copy "dir:${IMAGE_CACHE_DIR}/${image_archive}" "containers-storage:${image}" if [ "$status" -ne 0 ]; then echo "Failed to load image ${image} from cache ${IMAGE_CACHE_DIR}/${image_archive}" assert_success fi $PODMAN images } # Copies the system's default image to Podman's image store # # See pull_default_image() for more info. function pull_default_image() { pull_distro_image $(get_system_id) $(get_system_version) } # Creates a container with specific name, distro and version # # Pulling of an image is taken care of by the function # # Parameters: # =========== # - distro - os-release field ID (e.g., fedora, rhel) # - version - os-release field VERSION_ID (e.g., 33, 34, 8.4) # - container_name - name of the container function create_distro_container() { local distro local version local container_name distro="$1" version="$2" container_name="$3" pull_distro_image ${distro} ${version} $TOOLBOX --assumeyes create --container "${container_name}" --distro "${distro}" --release "${version}" >/dev/null \ || fail "Toolbox couldn't create container '$container_name'" } # Creates a container with specific name matching the system # # Parameters: # =========== # - container_name - name of the container function create_container() { local container_name container_name="$1" create_distro_container $(get_system_id) $(get_system_version) $container_name } # Creates a default container function create_default_container() { pull_default_image $TOOLBOX --assumeyes create >/dev/null \ || fail "Toolbox couldn't create default container" } function start_container() { local container_name container_name="$1" $PODMAN start "$container_name" >/dev/null \ || fail "Podman couldn't start the container '$container_name'" } function stop_container() { local container_name container_name="$1" # Make sure the container is running before trying to stop it $PODMAN start "$container_name" >/dev/null \ || fail "Podman couldn't start the container '$container_name'" $PODMAN stop "$container_name" >/dev/null \ || fail "Podman couldn't stop the container '$container_name'" } function list_images() { $PODMAN images --all --quiet | wc -l } function list_containers() { $PODMAN ps --all --quiet | wc -l } # Returns the path to os-release function find_os_release() { if [[ -f "/etc/os-release" ]]; then echo "/etc/os-release" elif [[ -f "/usr/lib/os-release" ]]; then echo "/usr/lib/os-release" else echo "" fi } # Returns the content of field ID in os-release function get_system_id() { local os_release os_release="$(find_os_release)" if [[ -z "$os_release" ]]; then echo "" return fi echo $(awk -F= '/ID/ {print $2}' $os_release | head -n 1) } # Returns the content of field VERSION_ID in os-release function get_system_version() { local os_release os_release="$(find_os_release)" if [[ -z "$os_release" ]]; then echo "" return fi echo $(awk -F= '/VERSION_ID/ {print $2}' $os_release | head -n 1) }