Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

test/system: Decouple image caching from Zuul #774

Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
27 changes: 0 additions & 27 deletions playbooks/setup-env.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -46,30 +46,3 @@

- name: Show podman debug information
command: podman info --debug

- name: Pull the default image from registry.fedoraproject.org
command: "podman pull registry.fedoraproject.org/fedora-toolbox:{{ ansible_distribution_version }}"
register: _podman
until: _podman.rc == 0
retries: 5
delay: 10

- name: Copy the default image to a directory
command:
cmd: "skopeo copy containers-storage:registry.fedoraproject.org/fedora-toolbox:{{ ansible_distribution_version }} dir:{{ zuul.project.src_dir }}/fedora-toolbox-{{ ansible_distribution_version }}"
creates: "{{ zuul.project.src_dir }}/fedora-toolbox-{{ ansible_distribution_version }}/manifest.json"

- name: Pull registry.fedoraproject.org/fedora-toolbox:32
command: podman pull registry.fedoraproject.org/fedora-toolbox:32
register: _podman
until: _podman.rc == 0
retries: 5
delay: 10

- name: Copy registry.fedoraproject.org/fedora-toolbox:32 to a directory
command:
cmd: "skopeo copy containers-storage:registry.fedoraproject.org/fedora-toolbox:32 dir:{{ zuul.project.src_dir }}/fedora-toolbox-32"
creates: "{{ zuul.project.src_dir }}/fedora-toolbox-32/manifest.json"

- name: Clean up the local containers storage
command: podman system reset --force
11 changes: 11 additions & 0 deletions test/system/000-setup.bats
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
#!/usr/bin/env bats

load 'libs/helpers'

@test "test suite: Setup" {
# Cache the default image for the system
_pull_and_cache_distro_image $(get_system_id) $(get_system_version) || die
# Cache all images that will be needed during the tests
_pull_and_cache_distro_image fedora 32 || die
_pull_and_cache_distro_image busybox || die
}
6 changes: 4 additions & 2 deletions test/system/101-create.bats
Original file line number Diff line number Diff line change
Expand Up @@ -22,13 +22,15 @@ teardown() {
}

@test "create: Create a container with a valid custom name ('custom-containerName')" {
pull_default_image

run $TOOLBOX -y create -c "custom-containerName"

assert_success
}

@test "create: Create a container with a custom image and name ('fedora32'; f32)" {
pull_image 32
pull_distro_image fedora 32

run $TOOLBOX -y create -c "fedora32" -i fedora-toolbox:32

Expand All @@ -54,7 +56,7 @@ teardown() {
}

@test "create: Create a container with a distro and release options ('fedora'; f32)" {
pull_image 32
pull_distro_image fedora 32

run $TOOLBOX -y create -d "fedora" -r f32

Expand Down
15 changes: 8 additions & 7 deletions test/system/102-list.bats
Original file line number Diff line number Diff line change
Expand Up @@ -35,7 +35,7 @@ teardown() {
}

@test "list: Run 'list' with zero toolbox's containers and images, but other image (the list should be empty)" {
get_busybox_image
pull_distro_image busybox

run podman images

Expand All @@ -50,8 +50,9 @@ teardown() {
@test "list: Try to list images and containers (no flag) with 3 containers and 2 images (the list should have 3 images and 2 containers)" {
# Pull the two images
pull_default_image
pull_image 32
# Create tree containers
pull_distro_image fedora 32

# Create three containers
create_default_container
create_container non-default-one
create_container non-default-two
Expand All @@ -60,24 +61,24 @@ teardown() {
run $TOOLBOX list --images

assert_success
assert_output --partial "fedora-toolbox:${DEFAULT_FEDORA_VERSION}"
assert_output --partial "$(get_system_id)-toolbox:$(get_system_version)"
assert_output --partial "fedora-toolbox:32"

# Check containers
run $TOOLBOX list --containers

assert_success
assert_output --partial "fedora-toolbox-${DEFAULT_FEDORA_VERSION}"
assert_output --partial "$(get_system_id)-toolbox-$(get_system_version)"
assert_output --partial "non-default-one"
assert_output --partial "non-default-two"

# Check all together
run $TOOLBOX list

assert_success
assert_output --partial "fedora-toolbox:${DEFAULT_FEDORA_VERSION}"
assert_output --partial "$(get_system_id)-toolbox:$(get_system_version)"
assert_output --partial "fedora-toolbox:32"
assert_output --partial "fedora-toolbox-${DEFAULT_FEDORA_VERSION}"
assert_output --partial "$(get_system_id)-toolbox-$(get_system_version)"
assert_output --partial "non-default-one"
assert_output --partial "non-default-two"
}
7 changes: 7 additions & 0 deletions test/system/999-teardown.bats
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
#!/usr/bin/env bats

load 'libs/helpers'

@test "test suite: Teardown" {
_clean_cached_images
}
222 changes: 199 additions & 23 deletions test/system/libs/helpers.bash
Original file line number Diff line number Diff line change
@@ -1,16 +1,20 @@
#!/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)
readonly PROJECT_DIR=${PWD}

# Helpful globals
current_os_version=$(awk -F= '/VERSION_ID/ {print $2}' /etc/os-release)
readonly DEFAULT_FEDORA_VERSION=${DEFAULT_FEDORA_VERSION:-${current_os_version}}
readonly REGISTRY_URL=${REGISTRY_URL:-"registry.fedoraproject.org"}
readonly BUSYBOX_IMAGE="docker.io/library/busybox"
readonly PROJECT_DIR=${PWD}
readonly IMAGE_CACHE_DIR="${PROJECT_DIR}/image-cache"

# Images
declare -Ag IMAGES=([busybox]="docker.io/library/busybox" \
[fedora]="registry.fedoraproject.org/fedora-toolbox" \
[rhel]="registry.access.redhat.com/ubi8")


function cleanup_all() {
Expand All @@ -23,46 +27,176 @@ function cleanup_containers() {
}


function get_busybox_image() {
$PODMAN pull "$BUSYBOX_IMAGE" >/dev/null \
|| fail "Podman couldn't pull the image."
# 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
}


function pull_image() {
# 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
version="$1"
image="${REGISTRY_URL}/fedora-toolbox:${version}"
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

$SKOPEO copy "dir:${PROJECT_DIR}/fedora-toolbox-${version}" "containers-storage:${image}"
$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_image "${DEFAULT_FEDORA_VERSION}"
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
local version
local image
container_name="$1"
version="$DEFAULT_FEDORA_VERSION"
image="${REGISTRY_URL}/fedora-toolbox:${version}"

pull_image "$version"
container_name="$1"

$TOOLBOX --assumeyes create --container "$container_name" \
--image "$image" >/dev/null \
|| fail "Toolbox couldn't create the container '$container_name'"
create_distro_container $(get_system_id) $(get_system_version) $container_name
}


# Creates a default container
function create_default_container() {
create_container "fedora-toolbox-${DEFAULT_FEDORA_VERSION}"
pull_default_image

$TOOLBOX --assumeyes create >/dev/null \
|| fail "Toolbox couldn't create default container"
}


Expand Down Expand Up @@ -95,3 +229,45 @@ function list_images() {
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)
}