From ab35aaf23c539b5110f28660eaa72d15e5400150 Mon Sep 17 00:00:00 2001 From: Victor M Date: Mon, 11 Sep 2023 18:24:49 +0200 Subject: [PATCH 01/39] wip --- src/bootstrap.sh | 4 +++- src/shared/common.sh | 2 +- 2 files changed, 4 insertions(+), 2 deletions(-) diff --git a/src/bootstrap.sh b/src/bootstrap.sh index 54c35622..4f4dafe2 100644 --- a/src/bootstrap.sh +++ b/src/bootstrap.sh @@ -18,7 +18,9 @@ clone_cicd_tools_repo() { } _delete_cicd_tools_rootdir() { - echo "Removing existing CICD tools directory: '${CICD_TOOLS_ROOTDIR}'" + if _debug_mode; then + echo "Removing existing CICD tools directory: '${CICD_TOOLS_ROOTDIR}'" + fi rm -rf "${CICD_TOOLS_ROOTDIR}" } diff --git a/src/shared/common.sh b/src/shared/common.sh index c94f0803..ec06e474 100644 --- a/src/shared/common.sh +++ b/src/shared/common.sh @@ -24,7 +24,7 @@ get_7_chars_commit_hash() { } local_build() { - [[ "$LOCAL_BUILD" = true ]] + [[ "$LOCAL_BUILD" = true || "$CI" != "true" ]] } CICD_TOOLS_COMMON_LOADED=0 From 8e90226308e945e60ad2ae26e99bd72f5c094ca0 Mon Sep 17 00:00:00 2001 From: Victor M Date: Wed, 13 Sep 2023 19:21:03 +0200 Subject: [PATCH 02/39] first iteration --- src/main.sh | 15 +++++++-- src/shared/common.sh | 2 ++ ...-engine-lib.sh => container_engine_lib.sh} | 1 + src/shared/container_image_builder_lib.sh | 32 +++++++++++++++++++ test/shared_common.bats | 7 ++-- ....bats => shared_container_engine_lib.bats} | 2 +- 6 files changed, 53 insertions(+), 6 deletions(-) rename src/shared/{container-engine-lib.sh => container_engine_lib.sh} (99%) create mode 100644 src/shared/container_image_builder_lib.sh rename test/{shared_container-engine-lib.bats => shared_container_engine_lib.bats} (98%) diff --git a/src/main.sh b/src/main.sh index f49f915d..8d2fe4f9 100644 --- a/src/main.sh +++ b/src/main.sh @@ -18,6 +18,9 @@ load_library() { container_engine) _load_container_engine ;; + image_builder) + _load_image_builder + ;; *) echo "Unsupported library: '$LIB_TO_LOAD'" return 1 @@ -31,8 +34,16 @@ _load_all() { _load_container_engine() { # shellcheck source=src/shared/common.sh source "${CICD_TOOLS_SCRIPTS_DIR}/shared/common.sh" - # shellcheck source=src/shared/container-engine-lib.sh - source "${CICD_TOOLS_SCRIPTS_DIR}/shared/container-engine-lib.sh" + # shellcheck source=src/shared/container_engine_lib.sh + source "${CICD_TOOLS_SCRIPTS_DIR}/shared/container_engine_lib.sh" +} + +_load_image_builder() { + # shellcheck source=src/shared/container_engine_lib.sh + source "${CICD_TOOLS_SCRIPTS_DIR}/shared/container_engine_lib.sh" + # shellcheck source=src/shared/container_image_builder_lib.sh + source "${CICD_TOOLS_SCRIPTS_DIR}/shared/container_image_builder_lib.sh" + } load_library "$LIB_TO_LOAD" diff --git a/src/shared/common.sh b/src/shared/common.sh index ec06e474..d2356c79 100644 --- a/src/shared/common.sh +++ b/src/shared/common.sh @@ -1,5 +1,7 @@ #!/usr/bin/env bash +# Common functions that are shared across the different libraries + CICD_TOOLS_COMMON_LOADED=${CICD_TOOLS_COMMON_LOADED:-1} LOCAL_BUILD=${LOCAL_BUILD:-false} diff --git a/src/shared/container-engine-lib.sh b/src/shared/container_engine_lib.sh similarity index 99% rename from src/shared/container-engine-lib.sh rename to src/shared/container_engine_lib.sh index 92f67c0c..7d944b4a 100644 --- a/src/shared/container-engine-lib.sh +++ b/src/shared/container_engine_lib.sh @@ -9,6 +9,7 @@ if [[ "$CICD_TOOLS_CONTAINER_ENGINE_LOADED" -eq 0 ]]; then return 0 fi +# TODO: consider remove if [ -z "$CICD_TOOLS_SCRIPTS_DIR" ]; then echo "scripts directory not defined, please load through main.sh script" return 1 diff --git a/src/shared/container_image_builder_lib.sh b/src/shared/container_image_builder_lib.sh new file mode 100644 index 00000000..558a6571 --- /dev/null +++ b/src/shared/container_image_builder_lib.sh @@ -0,0 +1,32 @@ +#!/usr/bin/env bash + +CICD_TOOLS_CONTAINER_IMAGE_BUILDER_LOADED=${CICD_TOOLS_CONTAINER_IMAGE_BUILDER_LOADED:-1} + +if [[ "$CICD_TOOLS_CONTAINER_IMAGE_BUILDER_LOADED" -eq 0 ]]; then + return 0 +fi + +# TODO: consider remove +if [ -z "$CICD_TOOLS_SCRIPTS_DIR" ]; then + echo "scripts directory not defined, please load through main.sh script" + return 1 +fi + +# shellcheck source=src/shared/container-engine-lib.sh +source "${CICD_TOOLS_SCRIPTS_DIR}/shared/container_engine_lib.sh" + +if _debug_mode; then + echo "loading build container images" +fi + +CICD_TOOLS_CONTAINER_IMAGE_BUILDER_IMAGE_TAG='' + +cicd_tools::build_container_images::get_image_tag() { + echo -n "$CICD_TOOLS_CONTAINER_IMAGE_BUILDER_IMAGE_TAG" +} + +cicd_tools::build_container_images::build_image() { + echo "WIP" +} + +CICD_TOOLS_CONTAINER_IMAGE_BUILDER_LOADED=0 diff --git a/test/shared_common.bats b/test/shared_common.bats index 5b0fb753..fa7616a5 100644 --- a/test/shared_common.bats +++ b/test/shared_common.bats @@ -55,12 +55,13 @@ setup() { @test "local build check" { assert [ -z "$LOCAL_BUILD" ] + assert [ -z "$CI" ] source "src/shared/common.sh" - refute local_build - LOCAL_BUILD='1' + assert local_build + CI='true' refute local_build LOCAL_BUILD='true' assert local_build - LOCAL_BUILD='false' + unset LOCAL_BUILD refute local_build } diff --git a/test/shared_container-engine-lib.bats b/test/shared_container_engine_lib.bats similarity index 98% rename from test/shared_container-engine-lib.bats rename to test/shared_container_engine_lib.bats index 7b41d240..cea2251c 100644 --- a/test/shared_container-engine-lib.bats +++ b/test/shared_container_engine_lib.bats @@ -6,7 +6,7 @@ setup() { @test "Load directly results in error" { - run ! source "src/shared/container-engine-lib.sh" + run ! source "src/shared/container_engine_lib.sh" assert_failure assert_output --partial "load through main.sh" } From 116db05444b77176e4abe9ac0adc40525a9e4606 Mon Sep 17 00:00:00 2001 From: Victor M Date: Wed, 13 Sep 2023 20:00:18 +0200 Subject: [PATCH 03/39] first phase --- src/shared/common.sh | 12 ++++- src/shared/container_image_builder_lib.sh | 48 ++++++++++++++++- test/shared_container_image_builder_lib.bats | 57 ++++++++++++++++++++ 3 files changed, 113 insertions(+), 4 deletions(-) create mode 100644 test/shared_container_image_builder_lib.bats diff --git a/src/shared/common.sh b/src/shared/common.sh index d2356c79..e9b75965 100644 --- a/src/shared/common.sh +++ b/src/shared/common.sh @@ -21,12 +21,20 @@ command_is_present() { command -v "$1" > /dev/null 2>&1 } -get_7_chars_commit_hash() { - git rev-parse --short=7 HEAD +_get_n_chars_commit_hash() { + git rev-parse --short="$1" HEAD +} + +cicd_tools::common::get_7_chars_commit_hash() { + _get_n_chars_commit_hash 7 } local_build() { [[ "$LOCAL_BUILD" = true || "$CI" != "true" ]] } +cicd_tools::common::err() { + echo "[$(date +'%Y-%m-%dT%H:%M:%S%z')]: $*" >&2 +} + CICD_TOOLS_COMMON_LOADED=0 diff --git a/src/shared/container_image_builder_lib.sh b/src/shared/container_image_builder_lib.sh index 558a6571..2a5fc7dd 100644 --- a/src/shared/container_image_builder_lib.sh +++ b/src/shared/container_image_builder_lib.sh @@ -21,12 +21,56 @@ fi CICD_TOOLS_CONTAINER_IMAGE_BUILDER_IMAGE_TAG='' -cicd_tools::build_container_images::get_image_tag() { +cicd_tools::image_builder::get_image_tag() { echo -n "$CICD_TOOLS_CONTAINER_IMAGE_BUILDER_IMAGE_TAG" } -cicd_tools::build_container_images::build_image() { +cicd_tools::image_builder::build_image() { echo "WIP" } +_set_image_tag() { + + local image_tag + local commit_hash + local build_id + + commit_hash=$(cicd_tools::common::get_7_chars_commit_hash) + + if _is_change_request_context; then + build_id=$(_get_build_id) + if [ -z "$build_id" ]; then + cicd_tools::common::err "cannot get build ID from environment" + return 1 + fi + image_tag="pr-${build_id}-${commit_hash}" + else + image_tag="$commit_hash" + fi + + CICD_TOOLS_CONTAINER_IMAGE_BUILDER_IMAGE_TAG="$image_tag" + readonly CICD_TOOLS_CONTAINER_IMAGE_BUILDER_IMAGE_TAG +} + +_is_change_request_context() { + [ -n "$ghprbPullId" ] || [ -n "$gitlabMergeRequestId" ] +} + +_get_build_id() { + + local build_id + + if [ -n "$ghprbPullId" ]; then + build_id="$ghprbPullId" + elif [ -n "$gitlabMergeRequestId" ]; then + build_id="$gitlabMergeRequestId" + else + build_id='' + fi + + echo -n "$build_id" +} + + +_set_image_tag CICD_TOOLS_CONTAINER_IMAGE_BUILDER_LOADED=0 diff --git a/test/shared_container_image_builder_lib.bats b/test/shared_container_image_builder_lib.bats new file mode 100644 index 00000000..7c1b12ab --- /dev/null +++ b/test/shared_container_image_builder_lib.bats @@ -0,0 +1,57 @@ + +setup() { + load "test_helper/common-setup" + _common_setup +} + +@test "Load directly results in error" { + + run ! source "src/shared/container_image_builder_lib.sh" + assert_failure + assert_output --partial "load through main.sh" +} + +@test "Sets expected loaded flags" { + + assert [ -z "$CICD_TOOLS_COMMON_LOADED" ] + assert [ -z "$CICD_TOOLS_CONTAINER_ENGINE_LOADED" ] + assert [ -z "$CICD_TOOLS_CONTAINER_IMAGE_BUILDER_LOADED" ] + + source main.sh image_builder + + assert [ -n "$CICD_TOOLS_COMMON_LOADED" ] + assert [ -n "$CICD_TOOLS_CONTAINER_ENGINE_LOADED" ] + assert [ -n "$CICD_TOOLS_CONTAINER_IMAGE_BUILDER_LOADED" ] +} + +@test "Image tag is set appropriately outside of a change request context" { + + source main.sh image_builder + run cicd_tools::image_builder::get_image_tag + assert_success + assert_output --regexp '^\b[0-9a-f]{7}\b$' + + assert [ -n "$CICD_TOOLS_CONTAINER_IMAGE_BUILDER_IMAGE_TAG" ] +} + +@test "Image tag is set appropriately in a Pull Request context" { + + ghprbPullId=123 + source main.sh image_builder + run cicd_tools::image_builder::get_image_tag + assert_success + assert_output --regexp '^pr-\d+-\b[0-9a-f]{7}\b$' + + assert [ -n "$CICD_TOOLS_CONTAINER_IMAGE_BUILDER_IMAGE_TAG" ] +} + +@test "Image tag is set appropriately in a Merge Request context" { + + $gitlabMergeRequestId=4321 + source main.sh image_builder + run cicd_tools::image_builder::get_image_tag + assert_success + assert_output --regexp '^mr-\d+-\b[0-9a-f]{7}\b$' + + assert [ -n "$CICD_TOOLS_CONTAINER_IMAGE_BUILDER_IMAGE_TAG" ] +} \ No newline at end of file From dcc61e3ce94dd29562e8594ab8df2be8580d2d94 Mon Sep 17 00:00:00 2001 From: Victor M Date: Thu, 14 Sep 2023 10:11:10 +0200 Subject: [PATCH 04/39] Fix tests --- test/shared_common.bats | 4 ++-- test/shared_container_image_builder_lib.bats | 10 +++++----- 2 files changed, 7 insertions(+), 7 deletions(-) diff --git a/test/shared_common.bats b/test/shared_common.bats index fa7616a5..491799df 100644 --- a/test/shared_common.bats +++ b/test/shared_common.bats @@ -47,9 +47,9 @@ setup() { @test "get_7_chars_commit_hash works" { source "src/shared/common.sh" - run get_7_chars_commit_hash + run cicd_tools::common::get_7_chars_commit_hash assert_success - assert_output --regexp '^\b[0-9a-f]{7}\b$' + assert_output --regexp '^[0-9a-f]{7}$' } @test "local build check" { diff --git a/test/shared_container_image_builder_lib.bats b/test/shared_container_image_builder_lib.bats index 7c1b12ab..8662ddeb 100644 --- a/test/shared_container_image_builder_lib.bats +++ b/test/shared_container_image_builder_lib.bats @@ -29,7 +29,7 @@ setup() { source main.sh image_builder run cicd_tools::image_builder::get_image_tag assert_success - assert_output --regexp '^\b[0-9a-f]{7}\b$' + assert_output --regexp '^[0-9a-f]{7}$' assert [ -n "$CICD_TOOLS_CONTAINER_IMAGE_BUILDER_IMAGE_TAG" ] } @@ -40,18 +40,18 @@ setup() { source main.sh image_builder run cicd_tools::image_builder::get_image_tag assert_success - assert_output --regexp '^pr-\d+-\b[0-9a-f]{7}\b$' + assert_output --regexp '^pr-[0-9]+-[0-9a-f]{7}$' assert [ -n "$CICD_TOOLS_CONTAINER_IMAGE_BUILDER_IMAGE_TAG" ] } @test "Image tag is set appropriately in a Merge Request context" { - $gitlabMergeRequestId=4321 + gitlabMergeRequestId=4321 source main.sh image_builder run cicd_tools::image_builder::get_image_tag assert_success - assert_output --regexp '^mr-\d+-\b[0-9a-f]{7}\b$' + assert_output --regexp '^pr-[0-9]+-[0-9a-f]{7}$' assert [ -n "$CICD_TOOLS_CONTAINER_IMAGE_BUILDER_IMAGE_TAG" ] -} \ No newline at end of file +} From 4e0d4c1c6864c3017f94e9ed3b1ce0483b4e08c7 Mon Sep 17 00:00:00 2001 From: Victor M Date: Thu, 14 Sep 2023 17:25:47 +0200 Subject: [PATCH 05/39] rename of libraries --- src/main.sh | 73 ++++--- src/shared/{common.sh => common_lib.sh} | 24 +-- src/shared/container_engine_lib.sh | 121 ----------- src/shared/container_image_builder_lib.sh | 76 ------- src/shared/container_lib.sh | 111 ++++++++++ src/shared/image_builder_lib.sh | 200 ++++++++++++++++++ test/main.bats | 25 +-- ...red_common.bats => shared_common_lib.bats} | 39 ++-- ...ine_lib.bats => shared_container_lib.bats} | 70 +++--- ...lib.bats => shared_image_builder_lib.bats} | 2 +- 10 files changed, 438 insertions(+), 303 deletions(-) rename src/shared/{common.sh => common_lib.sh} (50%) delete mode 100644 src/shared/container_engine_lib.sh delete mode 100644 src/shared/container_image_builder_lib.sh create mode 100644 src/shared/container_lib.sh create mode 100644 src/shared/image_builder_lib.sh rename test/{shared_common.bats => shared_common_lib.bats} (51%) rename test/{shared_container_engine_lib.bats => shared_container_lib.bats} (71%) rename test/{shared_container_image_builder_lib.bats => shared_image_builder_lib.bats} (96%) diff --git a/src/main.sh b/src/main.sh index 8d2fe4f9..53381f0f 100644 --- a/src/main.sh +++ b/src/main.sh @@ -1,49 +1,64 @@ #!/usr/bin/env bash -CICD_TOOLS_COMMON_LOADED=${CICD_TOOLS_COMMON_LOADED:-1} -CICD_TOOLS_CONTAINER_ENGINE_LOADED=${CICD_TOOLS_CONTAINER_ENGINE_LOADED:-1} +CICD_TOOLS_COMMON_LIB_LOADED=${CICD_TOOLS_COMMON_LIB_LOADED:-1} +CICD_TOOLS_CONTAINER_LIB_LOADED=${CICD_TOOLS_CONTAINER_LIB_LOADED:-1} CICD_TOOLS_DEBUG="${CICD_TOOLS_DEBUG:-}" # https://stackoverflow.com/a/246128 SCRIPT_DIR="$( cd -- "$( dirname -- "${BASH_SOURCE[0]}" )" &> /dev/null && pwd )" CICD_TOOLS_SCRIPTS_DIR="${CICD_TOOLS_SCRIPTS_DIR:-$SCRIPT_DIR}" LIB_TO_LOAD=${1:-all} -load_library() { +cicd_tools::debug() { + if cicd_tools::_debug_mode; then + cicd_tools::log $* + fi +} - case $LIB_TO_LOAD in +cicd_tools::_debug_mode() { + [[ -n "$CICD_TOOLS_DEBUG" ]] +} - all) - _load_all - ;; - container_engine) - _load_container_engine - ;; - image_builder) - _load_image_builder - ;; - *) echo "Unsupported library: '$LIB_TO_LOAD'" - return 1 +cicd_tools::log() { + echo "[$(date +'%Y-%m-%dT%H:%M:%S%z')]: $*" +} - esac +cicd_tools::err() { + echo "[$(date +'%Y-%m-%dT%H:%M:%S%z')]: $*" >&2 } -_load_all() { - _load_container_engine +cicd_tools::load_library() { + + case $LIB_TO_LOAD in + all) cicd_tools::_load_all ;; + common) cicd_tools::_load_common_lib ;; + container) cicd_tools::_load_container_lib;; + image_builder) cicd_tools::_load_image_builder_lib ;; + *) cicd_tools::err "Unsupported library: '$LIB_TO_LOAD'" && return 1 ;; + esac } -_load_container_engine() { - # shellcheck source=src/shared/common.sh - source "${CICD_TOOLS_SCRIPTS_DIR}/shared/common.sh" - # shellcheck source=src/shared/container_engine_lib.sh - source "${CICD_TOOLS_SCRIPTS_DIR}/shared/container_engine_lib.sh" +cicd_tools::_load_all() { + cicd_tools::_load_common_lib + cicd_tools::_load_container_lib + cicd_tools::_load_image_builder_lib } -_load_image_builder() { - # shellcheck source=src/shared/container_engine_lib.sh - source "${CICD_TOOLS_SCRIPTS_DIR}/shared/container_engine_lib.sh" - # shellcheck source=src/shared/container_image_builder_lib.sh - source "${CICD_TOOLS_SCRIPTS_DIR}/shared/container_image_builder_lib.sh" +cicd_tools::_load_common_lib() { + # shellcheck source=src/shared/common_lib.sh + source "${CICD_TOOLS_SCRIPTS_DIR}/shared/common_lib.sh" +} + +cicd_tools::_load_container_lib() { + cicd_tools::_load_common_lib + # shellcheck source=src/shared/container_lib.sh + source "${CICD_TOOLS_SCRIPTS_DIR}/shared/container_lib.sh" +} +cicd_tools::_load_image_builder_lib() { + cicd_tools::_load_common_lib + cicd_tools::_load_container_lib + # shellcheck source=src/shared/image_builder.sh + source "${CICD_TOOLS_SCRIPTS_DIR}/shared/image_builder_lib.sh" } -load_library "$LIB_TO_LOAD" +cicd_tools::load_library "$LIB_TO_LOAD" diff --git a/src/shared/common.sh b/src/shared/common_lib.sh similarity index 50% rename from src/shared/common.sh rename to src/shared/common_lib.sh index e9b75965..3804e8ec 100644 --- a/src/shared/common.sh +++ b/src/shared/common_lib.sh @@ -6,35 +6,33 @@ CICD_TOOLS_COMMON_LOADED=${CICD_TOOLS_COMMON_LOADED:-1} LOCAL_BUILD=${LOCAL_BUILD:-false} if [ "$CICD_TOOLS_COMMON_LOADED" -eq 0 ]; then + cicd_tools::debug "common library already loaded, skipping" return 0 fi -_debug_mode() { - [[ -n "$CICD_TOOLS_DEBUG" ]] -} - -if _debug_mode; then - echo "loading common" +if [ -z "$CICD_TOOLS_SCRIPTS_DIR" ]; then + echo "scripts directory not defined, please load through main.sh script" >&2 + return 1 fi -command_is_present() { +cicd_tools::debug "loading common lib" + +cicd_tools::common::command_is_present() { command -v "$1" > /dev/null 2>&1 } -_get_n_chars_commit_hash() { +cicd_tools::common::_get_n_chars_commit_hash() { git rev-parse --short="$1" HEAD } cicd_tools::common::get_7_chars_commit_hash() { - _get_n_chars_commit_hash 7 + cicd_tools::common::_get_n_chars_commit_hash 7 } -local_build() { +cicd_tools::common::local_build() { [[ "$LOCAL_BUILD" = true || "$CI" != "true" ]] } -cicd_tools::common::err() { - echo "[$(date +'%Y-%m-%dT%H:%M:%S%z')]: $*" >&2 -} +cicd_tools::debug "common lib loaded" CICD_TOOLS_COMMON_LOADED=0 diff --git a/src/shared/container_engine_lib.sh b/src/shared/container_engine_lib.sh deleted file mode 100644 index 7d944b4a..00000000 --- a/src/shared/container_engine_lib.sh +++ /dev/null @@ -1,121 +0,0 @@ -#!/usr/bin/env bash - -# container engine helper functions to handle both podman and docker commands - -CICD_TOOLS_COMMON_LOADED=${CICD_TOOLS_COMMON_LOADED:-1} -CICD_TOOLS_CONTAINER_ENGINE_LOADED=${CICD_TOOLS_CONTAINER_ENGINE_LOADED:-1} - -if [[ "$CICD_TOOLS_CONTAINER_ENGINE_LOADED" -eq 0 ]]; then - return 0 -fi - -# TODO: consider remove -if [ -z "$CICD_TOOLS_SCRIPTS_DIR" ]; then - echo "scripts directory not defined, please load through main.sh script" - return 1 -fi - -if [[ "$CICD_TOOLS_COMMON_LOADED" -ne 0 ]]; then - # shellcheck source=src/shared/common.sh - source "${CICD_TOOLS_SCRIPTS_DIR}/shared/common.sh" -fi - -if _debug_mode; then - echo "loading container engine" -fi - -CONTAINER_ENGINE_CMD='' -PREFER_CONTAINER_ENGINE=${PREFER_CONTAINER_ENGINE:-} - -container_engine_cmd() { - - if [[ -z "$CONTAINER_ENGINE_CMD" ]]; then - if ! _set_container_engine_cmd; then - return 1 - fi - fi - - "$CONTAINER_ENGINE_CMD" "$@" -} - -_set_container_engine_cmd() { - - if _preferred_container_engine_available; then - CONTAINER_ENGINE_CMD="$PREFER_CONTAINER_ENGINE" - else - if _container_engine_available 'podman'; then - CONTAINER_ENGINE_CMD='podman' - elif _container_engine_available 'docker'; then - CONTAINER_ENGINE_CMD='docker' - else - echo "ERROR, no container engine found, please install either podman or docker first" - return 1 - fi - fi - - if _debug_mode; then - echo "Container engine selected: $CONTAINER_ENGINE_CMD" - fi -} - -_preferred_container_engine_available() { - - local CONTAINER_ENGINE_AVAILABLE=1 - - if [ -n "$PREFER_CONTAINER_ENGINE" ]; then - if _container_engine_available "$PREFER_CONTAINER_ENGINE"; then - CONTAINER_ENGINE_AVAILABLE=0 - else - echo "WARNING: preferred container engine '${PREFER_CONTAINER_ENGINE}' not present, or isn't supported, finding alternative..." - fi - fi - - return "$CONTAINER_ENGINE_AVAILABLE" -} - -_container_engine_available() { - - local CONTAINER_ENGINE_TO_CHECK="$1" - local CONTAINER_ENGINE_AVAILABLE=1 - - if _container_engine_command_exists_and_is_supported "$CONTAINER_ENGINE_TO_CHECK"; then - CONTAINER_ENGINE_AVAILABLE=0 - fi - - return "$CONTAINER_ENGINE_AVAILABLE" -} - -_container_engine_command_exists_and_is_supported() { - - local COMMAND="$1" - local RESULT=0 - - if _supported_container_engine "$COMMAND" && command_is_present "$COMMAND"; then - if [[ "$COMMAND" == 'docker' ]] && _docker_seems_emulated; then - echo "WARNING: docker seems emulated, skipping." - RESULT=1 - fi - else - RESULT=1 - fi - - return "$RESULT" -} - -_supported_container_engine() { - - local CONTAINER_ENGINE_TO_CHECK="$1" - - [ "$CONTAINER_ENGINE_TO_CHECK" = 'docker' ] || \ - [ "$CONTAINER_ENGINE_TO_CHECK" = 'podman' ] -} - -_docker_seems_emulated() { - [[ "$(docker 2>/dev/null --version)" =~ podman\ +version ]] -} - -_podman_version_under_4_5_0() { - [ "$(echo -en "4.5.0\n$(_podman_version)" | sort -V | head -1)" != "4.5.0" ] -} - -CICD_TOOLS_CONTAINER_ENGINE_LOADED=0 diff --git a/src/shared/container_image_builder_lib.sh b/src/shared/container_image_builder_lib.sh deleted file mode 100644 index 2a5fc7dd..00000000 --- a/src/shared/container_image_builder_lib.sh +++ /dev/null @@ -1,76 +0,0 @@ -#!/usr/bin/env bash - -CICD_TOOLS_CONTAINER_IMAGE_BUILDER_LOADED=${CICD_TOOLS_CONTAINER_IMAGE_BUILDER_LOADED:-1} - -if [[ "$CICD_TOOLS_CONTAINER_IMAGE_BUILDER_LOADED" -eq 0 ]]; then - return 0 -fi - -# TODO: consider remove -if [ -z "$CICD_TOOLS_SCRIPTS_DIR" ]; then - echo "scripts directory not defined, please load through main.sh script" - return 1 -fi - -# shellcheck source=src/shared/container-engine-lib.sh -source "${CICD_TOOLS_SCRIPTS_DIR}/shared/container_engine_lib.sh" - -if _debug_mode; then - echo "loading build container images" -fi - -CICD_TOOLS_CONTAINER_IMAGE_BUILDER_IMAGE_TAG='' - -cicd_tools::image_builder::get_image_tag() { - echo -n "$CICD_TOOLS_CONTAINER_IMAGE_BUILDER_IMAGE_TAG" -} - -cicd_tools::image_builder::build_image() { - echo "WIP" -} - -_set_image_tag() { - - local image_tag - local commit_hash - local build_id - - commit_hash=$(cicd_tools::common::get_7_chars_commit_hash) - - if _is_change_request_context; then - build_id=$(_get_build_id) - if [ -z "$build_id" ]; then - cicd_tools::common::err "cannot get build ID from environment" - return 1 - fi - image_tag="pr-${build_id}-${commit_hash}" - else - image_tag="$commit_hash" - fi - - CICD_TOOLS_CONTAINER_IMAGE_BUILDER_IMAGE_TAG="$image_tag" - readonly CICD_TOOLS_CONTAINER_IMAGE_BUILDER_IMAGE_TAG -} - -_is_change_request_context() { - [ -n "$ghprbPullId" ] || [ -n "$gitlabMergeRequestId" ] -} - -_get_build_id() { - - local build_id - - if [ -n "$ghprbPullId" ]; then - build_id="$ghprbPullId" - elif [ -n "$gitlabMergeRequestId" ]; then - build_id="$gitlabMergeRequestId" - else - build_id='' - fi - - echo -n "$build_id" -} - - -_set_image_tag -CICD_TOOLS_CONTAINER_IMAGE_BUILDER_LOADED=0 diff --git a/src/shared/container_lib.sh b/src/shared/container_lib.sh new file mode 100644 index 00000000..dd6bb929 --- /dev/null +++ b/src/shared/container_lib.sh @@ -0,0 +1,111 @@ +#!/usr/bin/env bash + +# container engine helper functions to handle both podman and docker commands + +CICD_TOOLS_CONTAINER_ENGINE_LOADED=${CICD_TOOLS_CONTAINER_ENGINE_LOADED:-1} + +if [[ "$CICD_TOOLS_CONTAINER_ENGINE_LOADED" -eq 0 ]]; then + cicd_tools::debug "container engine library already loaded, skipping" + return 0 +fi + +if [ -z "$CICD_TOOLS_SCRIPTS_DIR" ]; then + echo "scripts directory not defined, please load through main.sh script" >&2 + return 1 +fi + +cicd_tools::debug "loading container lib" + +CONTAINER_ENGINE_CMD='' +PREFER_CONTAINER_ENGINE=${PREFER_CONTAINER_ENGINE:-} + +cicd_tools::container::cmd() { + + if [[ -z "$CONTAINER_ENGINE_CMD" ]]; then + if ! cicd_tools::container::_set_container_engine_cmd; then + return 1 + fi + fi + + "$CONTAINER_ENGINE_CMD" "$@" +} + +cicd_tools::container::_set_container_engine_cmd() { + + if cicd_tools::container::_preferred_container_engine_available; then + CONTAINER_ENGINE_CMD="$PREFER_CONTAINER_ENGINE" + else + if cicd_tools::container::_container_engine_available 'podman'; then + CONTAINER_ENGINE_CMD='podman' + elif cicd_tools::container::_container_engine_available 'docker'; then + CONTAINER_ENGINE_CMD='docker' + else + cicd_tools::err "ERROR, no container engine found, please install either podman or docker first" + return 1 + fi + fi + + cicd_tools::debug "Container engine selected: $CONTAINER_ENGINE_CMD" +} + +cicd_tools::container::_preferred_container_engine_available() { + + local CONTAINER_ENGINE_AVAILABLE=1 + + if [ -n "$PREFER_CONTAINER_ENGINE" ]; then + if cicd_tools::container::_container_engine_available "$PREFER_CONTAINER_ENGINE"; then + CONTAINER_ENGINE_AVAILABLE=0 + else + cicd_tools::log "WARNING: preferred container engine '${PREFER_CONTAINER_ENGINE}' not present, or isn't supported, finding alternative..." + fi + fi + + return "$CONTAINER_ENGINE_AVAILABLE" +} + +cicd_tools::container::_container_engine_available() { + + local cmd="$1" + local available=1 + + if cicd_tools::container::_cmd_exists_and_is_supported "$cmd"; then + available=0 + fi + + return "$available" +} + +cicd_tools::container::_cmd_exists_and_is_supported() { + + local cmd="$1" + local result=0 + + if cicd_tools::container::_supported_container_engine "$cmd" && cicd_tools::common::command_is_present "$cmd"; then + if [[ "$cmd" == 'docker' ]] && cicd_tools::container::_docker_seems_emulated; then + cicd_tools::log "WARNING: docker seems emulated, skipping." + result=1 + fi + else + result=1 + fi + + return "$result" +} + +cicd_tools::container::_supported_container_engine() { + + local CONTAINER_ENGINE_TO_CHECK="$1" + + [ "$CONTAINER_ENGINE_TO_CHECK" = 'docker' ] || \ + [ "$CONTAINER_ENGINE_TO_CHECK" = 'podman' ] +} + +cicd_tools::container::_docker_seems_emulated() { + [[ "$(docker 2>/dev/null --version)" =~ podman\ +version ]] +} + +cicd_tools::container::_podman_version_under_4_5_0() { + [ "$(echo -en "4.5.0\n$(_podman_version)" | sort -V | head -1)" != "4.5.0" ] +} + +CICD_TOOLS_CONTAINER_ENGINE_LOADED=0 diff --git a/src/shared/image_builder_lib.sh b/src/shared/image_builder_lib.sh new file mode 100644 index 00000000..cdcbbdec --- /dev/null +++ b/src/shared/image_builder_lib.sh @@ -0,0 +1,200 @@ +#!/usr/bin/env bash + +CICD_TOOLS_CONTAINER_IMAGE_BUILDER_LOADED=${CICD_TOOLS_CONTAINER_IMAGE_BUILDER_LOADED:-1} + +if [[ "$CICD_TOOLS_CONTAINER_IMAGE_BUILDER_LOADED" -eq 0 ]]; then + return 0 +fi + +if [ -z "$CICD_TOOLS_SCRIPTS_DIR" ]; then + echo "scripts directory not defined, please load through main.sh script" >&2 + return 1 +fi + +cicd_tools::debug "loading image builder library" + +# TODO: reconsider namespaced variables +CICD_TOOLS_CONTAINER_IMAGE_BUILDER_IMAGE_TAG='' +readonly CICD_TOOLS_CONTAINER_IMAGE_BUILDER_REDHAT_REGISTRY='registry.redhat.io' +readonly CICD_TOOLS_CONTAINER_IMAGE_BUILDER_QUAY_REGISTRY='quay.io' +readonly CICD_TOOLS_CONTAINER_IMAGE_BUILDER_QUAY_EXPIRE_TIME=${CICD_TOOLS_CONTAINER_IMAGE_BUILDER_QUAY_EXPIRE_TIME:-3d} +readonly CICD_TOOLS_CONTAINER_IMAGE_BUILDER_QUAY_USER="${CICD_TOOLS_CONTAINER_IMAGE_BUILDER_QUAY_USER:-$QUAY_USER}" +readonly CICD_TOOLS_CONTAINER_IMAGE_BUILDER_QUAY_PASSWORD="${CICD_TOOLS_CONTAINER_IMAGE_BUILDER_QUAY_PASSWORD:-$QUAY_TOKEN}" +readonly CICD_TOOLS_CONTAINER_IMAGE_BUILDER_REDHAT_USER="${CICD_TOOLS_CONTAINER_IMAGE_BUILDER_REDHAT_USER:-$RH_REGISTRY_USER}" +readonly CICD_TOOLS_CONTAINER_IMAGE_BUILDER_REDHAT_PASSWORD="${CICD_TOOLS_CONTAINER_IMAGE_BUILDER_REDHAT_PASSWORD:-$RH_REGISTRY_TOKEN}" + +cicd_tools::image_builder::get_image_tag() { + echo -n "$CICD_TOOLS_CONTAINER_IMAGE_BUILDER_IMAGE_TAG" +} + +cicd_tools::image_builder::build() { + +# TODO: review params + local OPTIND OPTARG option image context containerfile additional_tags \ + labels labels_param build_args build_args_param tags tags_param + + while getopts 'b:c:f:i:l:t:' option; do + case "${option}" in + b) build_args="${OPTARG}" ;; + c) context="${OPTARG}" ;; + f) containerfile="${OPTARG}" ;; + i) image="${OPTARG}" ;; + l) labels="${OPTARG}" ;; + t) additional_tags="${OPTARG}" ;; + *) cicd_tools::err "cannot handle parameter" && return 1;; + esac + done + # shift $((OPTIND-1)) + + containerfile="${containerfile:-Dockerfile}" + context="${context:-.}" + + if [ -z "$image" ]; then + cicd_tools::err "you must specify an image name" + return 1 + fi + + if [ ! -r "$containerfile" ]; then + cicd_tools::err "${containerfile} not found or not readable" + return 1 + fi + + if _is_change_request_context; then + labels="${labels} $(_get_expiry_label)" + fi + + + for tag in ${CICD_TOOLS_CONTAINER_IMAGE_BUILDER_IMAGE_TAG} ${additional_tags}; do + tags="$tags ${image}:${tag}" + done + + labels_param="$(_get_build_param '--label' "$labels")" + build_args_param="$(_get_build_param '--build_arg' "$build_args")" + tags_param="$(_get_build_param '-t' "$tags")" + +# TODO: delete +# for label in $labels; do +# labels_param="${labels_param} --label $label" +# done +# +# for build_arg in $build_args; do +# build_args_param="${build_args_param} --build_arg $build_arg" +# done +# +# tags="${CICD_TOOLS_CONTAINER_IMAGE_BUILDER_IMAGE_TAG} ${additional_tags}" +# +# for tag in $tags; do +# tags_param="$tags_param -t ${image}:${tag}" +# done + + if ! cicd_tools::container::cmd build -f "$containerfile" $tags_param $build_args_param $labels_param \ + "$context"; then + cicd_tools::err "Error building image: ${image_name}" + return 1 + fi +} + +_get_build_param() { + + local option_key="$1" + local raw_params="$2" + local build_param + + for raw_param in $raw_params; do + build_param="$build_param "$option_key" $raw_param" + done + + echo -n "$build_param" +} + +_get_expiry_label() { + echo "--label quay.expires-after=${CICD_TOOLS_CONTAINER_IMAGE_BUILDER_QUAY_EXPIRE_TIME}" +} + +_set_image_tag() { + + local image_tag commit_hash build_id + + commit_hash=$(cicd_tools::common::get_7_chars_commit_hash) + + if _is_change_request_context; then + build_id=$(_get_build_id) + image_tag="pr-${build_id}-${commit_hash}" + else + image_tag="$commit_hash" + fi + + CICD_TOOLS_CONTAINER_IMAGE_BUILDER_IMAGE_TAG="$image_tag" + readonly CICD_TOOLS_CONTAINER_IMAGE_BUILDER_IMAGE_TAG +} + +_is_change_request_context() { + [ -n "$ghprbPullId" ] || [ -n "$gitlabMergeRequestId" ] +} + +_get_build_id() { + + local build_id + + if [ -n "$ghprbPullId" ]; then + build_id="$ghprbPullId" + elif [ -n "$gitlabMergeRequestId" ]; then + build_id="$gitlabMergeRequestId" + fi + + echo -n "$build_id" +} + +_image_builder_setup() { + _try_log_in_to_image_registries + _set_image_tag +} + +_try_log_in_to_image_registries() { + + if _quay_credentials_found; then + _log_in_to_quay + fi + + if _redhat_registry_credentials_found; then + _log_in_to_redhat_registry + fi +} + +_quay_credentials_found() { + [ -n "$CICD_TOOLS_CONTAINER_IMAGE_BUILDER_QUAY_USER" ] && \ + [ -n "$CICD_TOOLS_CONTAINER_IMAGE_BUILDER_QUAY_PASSWORD" ] +} + +_redhat_registry_credentials_found() { + [ -n "$CICD_TOOLS_CONTAINER_IMAGE_BUILDER_REDHAT_USER" ] && \ + [ -n "$CICD_TOOLS_CONTAINER_IMAGE_BUILDER_REDHAT_PASSWORD" ] +} + +_log_in_to_container_registry() { + + local username="$1" + local password="$2" + local registry="$3" + + cicd_tools::container::cmd login "-u=${username}" "--password-stdin" "$registry" <<< "$password" +} + +_log_in_to_quay_registry() { + _log_in_to_container_registry "$CICD_TOOLS_CONTAINER_IMAGE_BUILDER_QUAY_USER" \ + "$CICD_TOOLS_CONTAINER_IMAGE_BUILDER_QUAY_PASSWORD" \ + "$CICD_TOOLS_CONTAINER_IMAGE_BUILDER_QUAY_REGISTRY" +} + +_log_in_to_redhat_registry() { + _log_in_to_container_registry "$CICD_TOOLS_CONTAINER_IMAGE_BUILDER_REDHAT_USER" \ + "$CICD_TOOLS_CONTAINER_IMAGE_BUILDER_REDHAT_PASSWORD" \ + "$CICD_TOOLS_CONTAINER_IMAGE_BUILDER_REDHAT_REGISTRY" +} + +if ! _image_builder_setup; then + cicd_tools::err "Image builder setup failed!" + return 1 +fi + +CICD_TOOLS_CONTAINER_IMAGE_BUILDER_LOADED=0 diff --git a/test/main.bats b/test/main.bats index c5293d57..a288a6d8 100644 --- a/test/main.bats +++ b/test/main.bats @@ -16,7 +16,7 @@ setup() { run source src/main.sh '' assert_success assert_output --partial "loading common" - assert_output --partial "loading container engine" + assert_output --partial "loading container lib" } @test "loading all work successfully" { @@ -24,8 +24,9 @@ setup() { CICD_TOOLS_DEBUG=1 run source main.sh all assert_success - assert_output --partial "loading common" - assert_output --partial "loading container engine" + assert_output --partial "loading common lib" + assert_output --partial "loading container lib" + assert_output --partial "loading image builder lib" } @test "loading container helper functions work successfully" { @@ -33,14 +34,14 @@ setup() { podman() { echo "podman here" } - run ! container_engine_cmd + run ! cicd_tools::container::cmd assert_failure CICD_TOOLS_DEBUG=1 - run source main.sh container_engine + run source main.sh container assert_success - assert_output --partial "loading container engine" - source main.sh container_engine - run container_engine_cmd + assert_output --partial "loading container lib" + source main.sh container + run cicd_tools::container::cmd assert_success assert_output --partial "podman here" } @@ -52,9 +53,9 @@ setup() { assert [ "$CICD_TOOLS_COMMON_LOADED" -eq 0 ] CICD_TOOLS_DEBUG=1 run source main.sh "" - refute_output --partial "loading common" + refute_output --partial "loading common lib" run source main.sh all - refute_output --partial "loading common" - run source main.sh container_engine - refute_output --partial "loading container engine" + refute_output --partial "loading common lib" + run source main.sh container + refute_output --partial "loading container lib" } diff --git a/test/shared_common.bats b/test/shared_common_lib.bats similarity index 51% rename from test/shared_common.bats rename to test/shared_common_lib.bats index 491799df..eb12522d 100644 --- a/test/shared_common.bats +++ b/test/shared_common_lib.bats @@ -4,18 +4,18 @@ setup() { _common_setup } -@test "Common can be sourced directly" { +@test "Load directly results in error" { - run source "src/shared/common.sh" - assert_success + run ! source "src/shared/common_lib.sh" + assert_failure + assert_output --partial "load through main.sh" } - @test "Sets expected loaded flags" { assert [ -z "$CICD_TOOLS_COMMON_LOADED" ] - source "src/shared/common.sh" + source main.sh common assert [ "$CICD_TOOLS_COMMON_LOADED" -eq 0 ] } @@ -24,9 +24,9 @@ setup() { @test "Loading common message is displayed" { CICD_TOOLS_DEBUG=1 - run source 'src/shared/common.sh' + run source main.sh common assert_success - assert_output "loading common" + assert_output --partial "loading common" } @test "command is present works" { @@ -35,18 +35,18 @@ setup() { echo "cat exists" } - source "src/shared/common.sh" - run ! command_is_present foo + source main.sh common + run ! cicd_tools::common::command_is_present foo assert_failure - run command_is_present cat + run cicd_tools::common::command_is_present cat assert_success assert_output "" } @test "get_7_chars_commit_hash works" { - source "src/shared/common.sh" + source main.sh common run cicd_tools::common::get_7_chars_commit_hash assert_success assert_output --regexp '^[0-9a-f]{7}$' @@ -56,12 +56,19 @@ setup() { assert [ -z "$LOCAL_BUILD" ] assert [ -z "$CI" ] - source "src/shared/common.sh" - assert local_build + source src/main.sh common + run cicd_tools::common::local_build + assert_success CI='true' - refute local_build + run cicd_tools::common::local_build + assert_failure + assert_output "" LOCAL_BUILD='true' - assert local_build + run cicd_tools::common::local_build + assert_output "" + assert_success unset LOCAL_BUILD - refute local_build + run ! cicd_tools::common::local_build + assert_output "" + assert_failure } diff --git a/test/shared_container_engine_lib.bats b/test/shared_container_lib.bats similarity index 71% rename from test/shared_container_engine_lib.bats rename to test/shared_container_lib.bats index cea2251c..d3983da2 100644 --- a/test/shared_container_engine_lib.bats +++ b/test/shared_container_lib.bats @@ -6,7 +6,7 @@ setup() { @test "Load directly results in error" { - run ! source "src/shared/container_engine_lib.sh" + run ! source "src/shared/container_lib.sh" assert_failure assert_output --partial "load through main.sh" } @@ -16,7 +16,7 @@ setup() { assert [ -z "$CICD_TOOLS_COMMON_LOADED" ] assert [ -z "$CICD_TOOLS_CONTAINER_ENGINE_LOADED" ] - source main.sh container_engine + source main.sh container assert [ -n "$CICD_TOOLS_COMMON_LOADED" ] assert [ -n "$CICD_TOOLS_CONTAINER_ENGINE_LOADED" ] @@ -25,9 +25,9 @@ setup() { @test "Loading common message is displayed" { CICD_TOOLS_DEBUG=1 - run source main.sh container_engine + run source main.sh container assert_success - assert_output --partial "loading container engine" + assert_output --partial "loading container lib" } @test "container engine cmd is set once" { @@ -41,21 +41,21 @@ setup() { PREFER_CONTAINER_ENGINE="docker" - run ! container_engine_cmd + run ! cicd_tools::container::cmd assert_failure - assert_output --partial "container_engine_cmd: command not found" + assert_output --partial "cicd_tools::container::cmd: command not found" - source src/main.sh container_engine + source src/main.sh container - container_engine_cmd --version - run container_engine_cmd --version + cicd_tools::container::cmd --version + run cicd_tools::container::cmd --version assert_success assert_output "docker version 1" - unset PREFER_CONTAINER_ENGINE - source main.sh container_engine - run container_engine_cmd --version + unset PREFER_container + source main.sh container + run cicd_tools::container::cmd --version assert_success assert_output "docker version 1" } @@ -69,22 +69,22 @@ setup() { echo "podman version 1" } - run ! container_engine_cmd + run ! cicd_tools::container::cmd assert_failure - assert_output --partial "container_engine_cmd: command not found" + assert_output --partial "cicd_tools::container::cmd: command not found" - source src/main.sh container_engine + source src/main.sh container - container_engine_cmd --version + cicd_tools::container::cmd --version PREFER_CONTAINER_ENGINE="docker" - run container_engine_cmd --version + run cicd_tools::container::cmd --version assert_success assert_output "podman version 1" - source main.sh container_engine - run container_engine_cmd --version + source main.sh container + run cicd_tools::container::cmd --version assert_success assert_output "podman version 1" } @@ -95,8 +95,8 @@ setup() { echo "podman version 1" } - source main.sh container_engine - run container_engine_cmd --version + source main.sh container + run cicd_tools::container::cmd --version assert_output --partial "podman version 1" } @@ -112,18 +112,18 @@ setup() { echo 'podman version 1' } - source main.sh container_engine - run container_engine_cmd --version + source main.sh container + run cicd_tools::container::cmd --version assert_output --regexp "WARNING.*docker.*seems emulated" assert_output --partial "podman version 1" } @test "if no container engine found, fails" { - source main.sh container_engine + source main.sh container OLDPATH="$PATH" PATH=':' - run ! container_engine_cmd --version + run ! cicd_tools::container::cmd --version PATH="$OLDPATH" assert_failure assert_output --partial "ERROR, no container engine found" @@ -136,11 +136,11 @@ setup() { docker() { echo 'docker version 1' } - source main.sh container_engine + source main.sh container OLDPATH="$PATH" PATH=':' - run container_engine_cmd --version + run cicd_tools::container::cmd --version PATH="$OLDPATH" assert_output --regexp "WARNING.*podman.*not present" assert_output --partial "docker version 1" @@ -153,11 +153,11 @@ setup() { docker() { echo 'podman version 1' } - source main.sh container_engine + source main.sh container OLDPATH="$PATH" PATH=':' - run container_engine_cmd --version + run cicd_tools::container::cmd --version PATH="$OLDPATH" assert [ $status -eq 1 ] assert_output --regexp "WARNING.*docker seems emulated" @@ -173,9 +173,9 @@ setup() { docker() { echo 'docker version 1' } - source main.sh container_engine + source main.sh container - run container_engine_cmd --version + run cicd_tools::container::cmd --version assert_success assert_output --partial "podman version 1" } @@ -190,8 +190,8 @@ setup() { docker() { echo 'docker version 1' } - source main.sh container_engine - run container_engine_cmd --version + source main.sh container + run cicd_tools::container::cmd --version assert_success assert_output --partial "docker version 1" } @@ -207,8 +207,8 @@ setup() { podman() { echo 'podman version 1' } - source main.sh container_engine - run container_engine_cmd --version + source main.sh container + run cicd_tools::container::cmd --version assert_success assert_output --regexp "WARNING.*'cat'.*isn't supported" assert_output --partial "podman version 1" diff --git a/test/shared_container_image_builder_lib.bats b/test/shared_image_builder_lib.bats similarity index 96% rename from test/shared_container_image_builder_lib.bats rename to test/shared_image_builder_lib.bats index 8662ddeb..5c095e3c 100644 --- a/test/shared_container_image_builder_lib.bats +++ b/test/shared_image_builder_lib.bats @@ -6,7 +6,7 @@ setup() { @test "Load directly results in error" { - run ! source "src/shared/container_image_builder_lib.sh" + run ! source "src/shared/container_lib.sh" assert_failure assert_output --partial "load through main.sh" } From f90aaf3abca3a44fa6a955d34dd4cf206d7ebed0 Mon Sep 17 00:00:00 2001 From: Victor M Date: Thu, 14 Sep 2023 17:29:34 +0200 Subject: [PATCH 06/39] fix for CI --- test/shared_common_lib.bats | 2 ++ 1 file changed, 2 insertions(+) diff --git a/test/shared_common_lib.bats b/test/shared_common_lib.bats index eb12522d..58f84b63 100644 --- a/test/shared_common_lib.bats +++ b/test/shared_common_lib.bats @@ -54,6 +54,8 @@ setup() { @test "local build check" { + unset CI + assert [ -z "$LOCAL_BUILD" ] assert [ -z "$CI" ] source src/main.sh common From e60590aa0b54b67b31d76cce69e5195b6bc77737 Mon Sep 17 00:00:00 2001 From: Victor M Date: Thu, 14 Sep 2023 17:37:55 +0200 Subject: [PATCH 07/39] fix shellcheck tips --- src/main.sh | 6 +-- src/shared/image_builder_lib.sh | 71 ++++++++++++------------------ test/shared_image_builder_lib.bats | 10 ++--- 3 files changed, 36 insertions(+), 51 deletions(-) diff --git a/src/main.sh b/src/main.sh index 53381f0f..79fdc00c 100644 --- a/src/main.sh +++ b/src/main.sh @@ -10,7 +10,7 @@ LIB_TO_LOAD=${1:-all} cicd_tools::debug() { if cicd_tools::_debug_mode; then - cicd_tools::log $* + cicd_tools::log "$*" fi } @@ -31,7 +31,7 @@ cicd_tools::load_library() { case $LIB_TO_LOAD in all) cicd_tools::_load_all ;; common) cicd_tools::_load_common_lib ;; - container) cicd_tools::_load_container_lib;; + container) cicd_tools::_load_container_lib ;; image_builder) cicd_tools::_load_image_builder_lib ;; *) cicd_tools::err "Unsupported library: '$LIB_TO_LOAD'" && return 1 ;; esac @@ -57,7 +57,7 @@ cicd_tools::_load_container_lib() { cicd_tools::_load_image_builder_lib() { cicd_tools::_load_common_lib cicd_tools::_load_container_lib - # shellcheck source=src/shared/image_builder.sh + # shellcheck source=src/shared/image_builder_lib.sh source "${CICD_TOOLS_SCRIPTS_DIR}/shared/image_builder_lib.sh" } diff --git a/src/shared/image_builder_lib.sh b/src/shared/image_builder_lib.sh index cdcbbdec..7f8b955d 100644 --- a/src/shared/image_builder_lib.sh +++ b/src/shared/image_builder_lib.sh @@ -1,8 +1,8 @@ #!/usr/bin/env bash -CICD_TOOLS_CONTAINER_IMAGE_BUILDER_LOADED=${CICD_TOOLS_CONTAINER_IMAGE_BUILDER_LOADED:-1} +CICD_TOOLS_IMAGE_BUILDER_LOADED=${CICD_TOOLS_IMAGE_BUILDER_LOADED:-1} -if [[ "$CICD_TOOLS_CONTAINER_IMAGE_BUILDER_LOADED" -eq 0 ]]; then +if [[ "$CICD_TOOLS_IMAGE_BUILDER_LOADED" -eq 0 ]]; then return 0 fi @@ -14,17 +14,17 @@ fi cicd_tools::debug "loading image builder library" # TODO: reconsider namespaced variables -CICD_TOOLS_CONTAINER_IMAGE_BUILDER_IMAGE_TAG='' -readonly CICD_TOOLS_CONTAINER_IMAGE_BUILDER_REDHAT_REGISTRY='registry.redhat.io' -readonly CICD_TOOLS_CONTAINER_IMAGE_BUILDER_QUAY_REGISTRY='quay.io' -readonly CICD_TOOLS_CONTAINER_IMAGE_BUILDER_QUAY_EXPIRE_TIME=${CICD_TOOLS_CONTAINER_IMAGE_BUILDER_QUAY_EXPIRE_TIME:-3d} -readonly CICD_TOOLS_CONTAINER_IMAGE_BUILDER_QUAY_USER="${CICD_TOOLS_CONTAINER_IMAGE_BUILDER_QUAY_USER:-$QUAY_USER}" -readonly CICD_TOOLS_CONTAINER_IMAGE_BUILDER_QUAY_PASSWORD="${CICD_TOOLS_CONTAINER_IMAGE_BUILDER_QUAY_PASSWORD:-$QUAY_TOKEN}" -readonly CICD_TOOLS_CONTAINER_IMAGE_BUILDER_REDHAT_USER="${CICD_TOOLS_CONTAINER_IMAGE_BUILDER_REDHAT_USER:-$RH_REGISTRY_USER}" -readonly CICD_TOOLS_CONTAINER_IMAGE_BUILDER_REDHAT_PASSWORD="${CICD_TOOLS_CONTAINER_IMAGE_BUILDER_REDHAT_PASSWORD:-$RH_REGISTRY_TOKEN}" +CICD_TOOLS_IMAGE_BUILDER_IMAGE_TAG='' +readonly CICD_TOOLS_IMAGE_BUILDER_REDHAT_REGISTRY='registry.redhat.io' +readonly CICD_TOOLS_IMAGE_BUILDER_QUAY_REGISTRY='quay.io' +readonly CICD_TOOLS_IMAGE_BUILDER_QUAY_EXPIRE_TIME=${CICD_TOOLS_IMAGE_BUILDER_QUAY_EXPIRE_TIME:-3d} +readonly CICD_TOOLS_IMAGE_BUILDER_QUAY_USER="${CICD_TOOLS_IMAGE_BUILDER_QUAY_USER:-$QUAY_USER}" +readonly CICD_TOOLS_IMAGE_BUILDER_QUAY_PASSWORD="${CICD_TOOLS_IMAGE_BUILDER_QUAY_PASSWORD:-$QUAY_TOKEN}" +readonly CICD_TOOLS_IMAGE_BUILDER_REDHAT_USER="${CICD_TOOLS_IMAGE_BUILDER_REDHAT_USER:-$RH_REGISTRY_USER}" +readonly CICD_TOOLS_IMAGE_BUILDER_REDHAT_PASSWORD="${CICD_TOOLS_IMAGE_BUILDER_REDHAT_PASSWORD:-$RH_REGISTRY_TOKEN}" cicd_tools::image_builder::get_image_tag() { - echo -n "$CICD_TOOLS_CONTAINER_IMAGE_BUILDER_IMAGE_TAG" + echo -n "$CICD_TOOLS_IMAGE_BUILDER_IMAGE_TAG" } cicd_tools::image_builder::build() { @@ -64,7 +64,7 @@ cicd_tools::image_builder::build() { fi - for tag in ${CICD_TOOLS_CONTAINER_IMAGE_BUILDER_IMAGE_TAG} ${additional_tags}; do + for tag in ${CICD_TOOLS_IMAGE_BUILDER_IMAGE_TAG} ${additional_tags}; do tags="$tags ${image}:${tag}" done @@ -72,24 +72,9 @@ cicd_tools::image_builder::build() { build_args_param="$(_get_build_param '--build_arg' "$build_args")" tags_param="$(_get_build_param '-t' "$tags")" -# TODO: delete -# for label in $labels; do -# labels_param="${labels_param} --label $label" -# done -# -# for build_arg in $build_args; do -# build_args_param="${build_args_param} --build_arg $build_arg" -# done -# -# tags="${CICD_TOOLS_CONTAINER_IMAGE_BUILDER_IMAGE_TAG} ${additional_tags}" -# -# for tag in $tags; do -# tags_param="$tags_param -t ${image}:${tag}" -# done - if ! cicd_tools::container::cmd build -f "$containerfile" $tags_param $build_args_param $labels_param \ "$context"; then - cicd_tools::err "Error building image: ${image_name}" + cicd_tools::err "Error building image" return 1 fi } @@ -101,14 +86,14 @@ _get_build_param() { local build_param for raw_param in $raw_params; do - build_param="$build_param "$option_key" $raw_param" + build_param="${build_param} ${option_key} ${raw_param}" done echo -n "$build_param" } _get_expiry_label() { - echo "--label quay.expires-after=${CICD_TOOLS_CONTAINER_IMAGE_BUILDER_QUAY_EXPIRE_TIME}" + echo "--label quay.expires-after=${CICD_TOOLS_IMAGE_BUILDER_QUAY_EXPIRE_TIME}" } _set_image_tag() { @@ -124,8 +109,8 @@ _set_image_tag() { image_tag="$commit_hash" fi - CICD_TOOLS_CONTAINER_IMAGE_BUILDER_IMAGE_TAG="$image_tag" - readonly CICD_TOOLS_CONTAINER_IMAGE_BUILDER_IMAGE_TAG + CICD_TOOLS_IMAGE_BUILDER_IMAGE_TAG="$image_tag" + readonly CICD_TOOLS_IMAGE_BUILDER_IMAGE_TAG } _is_change_request_context() { @@ -162,13 +147,13 @@ _try_log_in_to_image_registries() { } _quay_credentials_found() { - [ -n "$CICD_TOOLS_CONTAINER_IMAGE_BUILDER_QUAY_USER" ] && \ - [ -n "$CICD_TOOLS_CONTAINER_IMAGE_BUILDER_QUAY_PASSWORD" ] + [ -n "$CICD_TOOLS_IMAGE_BUILDER_QUAY_USER" ] && \ + [ -n "$CICD_TOOLS_IMAGE_BUILDER_QUAY_PASSWORD" ] } _redhat_registry_credentials_found() { - [ -n "$CICD_TOOLS_CONTAINER_IMAGE_BUILDER_REDHAT_USER" ] && \ - [ -n "$CICD_TOOLS_CONTAINER_IMAGE_BUILDER_REDHAT_PASSWORD" ] + [ -n "$CICD_TOOLS_IMAGE_BUILDER_REDHAT_USER" ] && \ + [ -n "$CICD_TOOLS_IMAGE_BUILDER_REDHAT_PASSWORD" ] } _log_in_to_container_registry() { @@ -181,15 +166,15 @@ _log_in_to_container_registry() { } _log_in_to_quay_registry() { - _log_in_to_container_registry "$CICD_TOOLS_CONTAINER_IMAGE_BUILDER_QUAY_USER" \ - "$CICD_TOOLS_CONTAINER_IMAGE_BUILDER_QUAY_PASSWORD" \ - "$CICD_TOOLS_CONTAINER_IMAGE_BUILDER_QUAY_REGISTRY" + _log_in_to_container_registry "$CICD_TOOLS_IMAGE_BUILDER_QUAY_USER" \ + "$CICD_TOOLS_IMAGE_BUILDER_QUAY_PASSWORD" \ + "$CICD_TOOLS_IMAGE_BUILDER_QUAY_REGISTRY" } _log_in_to_redhat_registry() { - _log_in_to_container_registry "$CICD_TOOLS_CONTAINER_IMAGE_BUILDER_REDHAT_USER" \ - "$CICD_TOOLS_CONTAINER_IMAGE_BUILDER_REDHAT_PASSWORD" \ - "$CICD_TOOLS_CONTAINER_IMAGE_BUILDER_REDHAT_REGISTRY" + _log_in_to_container_registry "$CICD_TOOLS_IMAGE_BUILDER_REDHAT_USER" \ + "$CICD_TOOLS_IMAGE_BUILDER_REDHAT_PASSWORD" \ + "$CICD_TOOLS_IMAGE_BUILDER_REDHAT_REGISTRY" } if ! _image_builder_setup; then @@ -197,4 +182,4 @@ if ! _image_builder_setup; then return 1 fi -CICD_TOOLS_CONTAINER_IMAGE_BUILDER_LOADED=0 +CICD_TOOLS_IMAGE_BUILDER_LOADED=0 diff --git a/test/shared_image_builder_lib.bats b/test/shared_image_builder_lib.bats index 5c095e3c..e2fa1e8f 100644 --- a/test/shared_image_builder_lib.bats +++ b/test/shared_image_builder_lib.bats @@ -15,13 +15,13 @@ setup() { assert [ -z "$CICD_TOOLS_COMMON_LOADED" ] assert [ -z "$CICD_TOOLS_CONTAINER_ENGINE_LOADED" ] - assert [ -z "$CICD_TOOLS_CONTAINER_IMAGE_BUILDER_LOADED" ] + assert [ -z "$CICD_TOOLS_IMAGE_BUILDER_LOADED" ] source main.sh image_builder assert [ -n "$CICD_TOOLS_COMMON_LOADED" ] assert [ -n "$CICD_TOOLS_CONTAINER_ENGINE_LOADED" ] - assert [ -n "$CICD_TOOLS_CONTAINER_IMAGE_BUILDER_LOADED" ] + assert [ -n "$CICD_TOOLS_IMAGE_BUILDER_LOADED" ] } @test "Image tag is set appropriately outside of a change request context" { @@ -31,7 +31,7 @@ setup() { assert_success assert_output --regexp '^[0-9a-f]{7}$' - assert [ -n "$CICD_TOOLS_CONTAINER_IMAGE_BUILDER_IMAGE_TAG" ] + assert [ -n "$CICD_TOOLS_IMAGE_BUILDER_IMAGE_TAG" ] } @test "Image tag is set appropriately in a Pull Request context" { @@ -42,7 +42,7 @@ setup() { assert_success assert_output --regexp '^pr-[0-9]+-[0-9a-f]{7}$' - assert [ -n "$CICD_TOOLS_CONTAINER_IMAGE_BUILDER_IMAGE_TAG" ] + assert [ -n "$CICD_TOOLS_IMAGE_BUILDER_IMAGE_TAG" ] } @test "Image tag is set appropriately in a Merge Request context" { @@ -53,5 +53,5 @@ setup() { assert_success assert_output --regexp '^pr-[0-9]+-[0-9a-f]{7}$' - assert [ -n "$CICD_TOOLS_CONTAINER_IMAGE_BUILDER_IMAGE_TAG" ] + assert [ -n "$CICD_TOOLS_IMAGE_BUILDER_IMAGE_TAG" ] } From 55d4dcf16453b95140ddce59d96564766cfd125f Mon Sep 17 00:00:00 2001 From: Victor M Date: Thu, 14 Sep 2023 18:09:44 +0200 Subject: [PATCH 08/39] fix workflow --- src/bootstrap.sh | 5 ++--- test/shared_image_builder_lib.bats | 2 +- 2 files changed, 3 insertions(+), 4 deletions(-) diff --git a/src/bootstrap.sh b/src/bootstrap.sh index 4f4dafe2..24203b14 100644 --- a/src/bootstrap.sh +++ b/src/bootstrap.sh @@ -18,14 +18,13 @@ clone_cicd_tools_repo() { } _delete_cicd_tools_rootdir() { - if _debug_mode; then - echo "Removing existing CICD tools directory: '${CICD_TOOLS_ROOTDIR}'" - fi + cicd_tools::debug "Removing existing CICD tools directory: '${CICD_TOOLS_ROOTDIR}'" rm -rf "${CICD_TOOLS_ROOTDIR}" } cleanup() { _delete_cicd_tools_rootdir + unset clone_cicd_tools_repo _delete_cicd_tools_rootdir cleanup } if [ -z "$CICD_TOOLS_SKIP_GIT_CLONE" ]; then diff --git a/test/shared_image_builder_lib.bats b/test/shared_image_builder_lib.bats index e2fa1e8f..bdd65b56 100644 --- a/test/shared_image_builder_lib.bats +++ b/test/shared_image_builder_lib.bats @@ -6,7 +6,7 @@ setup() { @test "Load directly results in error" { - run ! source "src/shared/container_lib.sh" + run ! source "src/shared/image_builder_lib.sh" assert_failure assert_output --partial "load through main.sh" } From 14de779b5a102dd1d5ddac3a3d39fb1e20d8ed25 Mon Sep 17 00:00:00 2001 From: Victor M Date: Thu, 14 Sep 2023 18:14:50 +0200 Subject: [PATCH 09/39] fix e2e tests --- test/e2e/test_bootstrap_script_main.sh | 10 +++++----- .../e2e/test_e2e_load_library_from_bootstrap_script.sh | 10 +++++----- test/e2e/test_e2e_load_library_from_function.sh | 8 ++++---- test/e2e/test_e2e_load_library_locally.sh | 8 ++++---- 4 files changed, 18 insertions(+), 18 deletions(-) diff --git a/test/e2e/test_bootstrap_script_main.sh b/test/e2e/test_bootstrap_script_main.sh index 63a07cc8..68b890d2 100755 --- a/test/e2e/test_bootstrap_script_main.sh +++ b/test/e2e/test_bootstrap_script_main.sh @@ -17,12 +17,12 @@ load_cicd_helper_functions() { source <(curl -sSL "$CICD_TOOLS_URL") "$LIBRARY_TO_LOAD" # required to persist container preferrence - container_engine_cmd --version + cicd_tools::container::cmd --version } -load_cicd_helper_functions container_engine +load_cicd_helper_functions container -EXPECTED_OUTPUT=$(container_engine_cmd --version) +EXPECTED_OUTPUT=$(cicd_tools::container::cmd --version) # Assert there's an actual output if ! [ "Docker version 99" == "$EXPECTED_OUTPUT" ]; then @@ -33,12 +33,12 @@ fi load_cicd_helper_functions # Assert output doesn't change -if ! [ "$(container_engine_cmd --version)" == "$EXPECTED_OUTPUT" ]; then +if ! [ "$(cicd_tools::container::cmd --version)" == "$EXPECTED_OUTPUT" ]; then echo "Container command not preserved between runs!" exit 1 fi -if ! [ "$(container_engine_cmd --version)" == "$EXPECTED_OUTPUT" ]; then +if ! [ "$(cicd_tools::container::cmd --version)" == "$EXPECTED_OUTPUT" ]; then echo "Container command not preserved between runs!" exit 1 fi diff --git a/test/e2e/test_e2e_load_library_from_bootstrap_script.sh b/test/e2e/test_e2e_load_library_from_bootstrap_script.sh index 607bdad1..28765db6 100755 --- a/test/e2e/test_e2e_load_library_from_bootstrap_script.sh +++ b/test/e2e/test_e2e_load_library_from_bootstrap_script.sh @@ -29,12 +29,12 @@ load_cicd_helper_functions() { fi # required to persist container preferrence - container_engine_cmd --version + cicd_tools::container::cmd --version } -load_cicd_helper_functions container_engine +load_cicd_helper_functions container -EXPECTED_OUTPUT=$(container_engine_cmd --version) +EXPECTED_OUTPUT=$(cicd_tools::container::cmd --version) # Assert there's an actual output if ! [ "Docker version 99" == "$EXPECTED_OUTPUT" ]; then @@ -45,12 +45,12 @@ fi load_cicd_helper_functions # Assert output doesn't change -if ! [ "$(container_engine_cmd --version)" == "$EXPECTED_OUTPUT" ]; then +if ! [ "$(cicd_tools::container::cmd --version)" == "$EXPECTED_OUTPUT" ]; then echo "Container command not preserved between runs!" exit 1 fi -if ! [ "$(container_engine_cmd --version)" == "$EXPECTED_OUTPUT" ]; then +if ! [ "$(cicd_tools::container::cmd --version)" == "$EXPECTED_OUTPUT" ]; then echo "Container command not preserved between runs!" exit 1 fi diff --git a/test/e2e/test_e2e_load_library_from_function.sh b/test/e2e/test_e2e_load_library_from_function.sh index 196eb241..eb043494 100755 --- a/test/e2e/test_e2e_load_library_from_function.sh +++ b/test/e2e/test_e2e_load_library_from_function.sh @@ -16,9 +16,9 @@ load_common_helper_cicd_tools() { local LIBRARY_TO_LOAD=${1:-all} local MAIN_SCRIPT='./src/main.sh' source "$MAIN_SCRIPT" "$LIBRARY_TO_LOAD" - container_engine_cmd --version + cicd_tools::container::cmd --version } -load_common_helper_cicd_tools container_engine +load_common_helper_cicd_tools container EXPECTED_OUTPUT=$(container_engine_cmd --version) @@ -31,12 +31,12 @@ fi load_cicd_helper_functions # Assert output doesn't change -if ! [ "$(container_engine_cmd --version)" == "$EXPECTED_OUTPUT" ]; then +if ! [ "$(cicd_tools::container::cmd --version)" == "$EXPECTED_OUTPUT" ]; then echo "Container command not preserved between runs!" exit 1 fi -if ! [ "$(container_engine_cmd --version)" == "$EXPECTED_OUTPUT" ]; then +if ! [ "$(cicd_tools::container::cmd --version)" == "$EXPECTED_OUTPUT" ]; then echo "Container command not preserved between runs!" exit 1 fi diff --git a/test/e2e/test_e2e_load_library_locally.sh b/test/e2e/test_e2e_load_library_locally.sh index b775cc0f..7eff61ed 100755 --- a/test/e2e/test_e2e_load_library_locally.sh +++ b/test/e2e/test_e2e_load_library_locally.sh @@ -15,9 +15,9 @@ MAIN_SCRIPT='./src/main.sh' source "$MAIN_SCRIPT" "$LIBRARY_TO_LOAD" -container_engine_cmd --version >/dev/null +cicd_tools::container::cmd --version >/dev/null -EXPECTED_OUTPUT=$(container_engine_cmd --version) +EXPECTED_OUTPUT=$(cicd_tools::container::cmd --version) # Assert there's an actual output if ! [ "Docker version 99" == "$EXPECTED_OUTPUT" ]; then @@ -28,12 +28,12 @@ fi load_cicd_helper_functions # Assert output doesn't change -if ! [ "$(container_engine_cmd --version)" == "$EXPECTED_OUTPUT" ]; then +if ! [ "$(cicd_tools::container::cmd --version)" == "$EXPECTED_OUTPUT" ]; then echo "Container command not preserved between runs!" exit 1 fi -if ! [ "$(container_engine_cmd --version)" == "$EXPECTED_OUTPUT" ]; then +if ! [ "$(cicd_tools::container::cmd --version)" == "$EXPECTED_OUTPUT" ]; then echo "Container command not preserved between runs!" exit 1 fi From 0c1b975c950d08521507e8a02a4f4a49d27cb458 Mon Sep 17 00:00:00 2001 From: Victor M Date: Thu, 14 Sep 2023 20:11:56 +0200 Subject: [PATCH 10/39] full coverage --- src/shared/image_builder_lib.sh | 73 +++++++------ test/data/Containerfile.empty | 0 test/data/Containerfile.test | 2 + test/shared_image_builder_lib.bats | 167 +++++++++++++++++++++++++++++ 4 files changed, 211 insertions(+), 31 deletions(-) create mode 100644 test/data/Containerfile.empty create mode 100644 test/data/Containerfile.test diff --git a/src/shared/image_builder_lib.sh b/src/shared/image_builder_lib.sh index 7f8b955d..23415025 100644 --- a/src/shared/image_builder_lib.sh +++ b/src/shared/image_builder_lib.sh @@ -50,7 +50,7 @@ cicd_tools::image_builder::build() { context="${context:-.}" if [ -z "$image" ]; then - cicd_tools::err "you must specify an image name" + cicd_tools::err "you must specify an image name to build with -i" return 1 fi @@ -59,8 +59,8 @@ cicd_tools::image_builder::build() { return 1 fi - if _is_change_request_context; then - labels="${labels} $(_get_expiry_label)" + if cicd_tools::image_builder::is_change_request_context; then + labels="${labels} $(cicd_tools::image_builder::_get_expiry_label)" fi @@ -68,9 +68,9 @@ cicd_tools::image_builder::build() { tags="$tags ${image}:${tag}" done - labels_param="$(_get_build_param '--label' "$labels")" - build_args_param="$(_get_build_param '--build_arg' "$build_args")" - tags_param="$(_get_build_param '-t' "$tags")" + labels_param="$(cicd_tools::image_builder::_get_build_param '--label' "$labels")" + build_args_param="$(cicd_tools::image_builder::_get_build_param '--build_arg' "$build_args")" + tags_param="$(cicd_tools::image_builder::_get_build_param '-t' "$tags")" if ! cicd_tools::container::cmd build -f "$containerfile" $tags_param $build_args_param $labels_param \ "$context"; then @@ -79,31 +79,31 @@ cicd_tools::image_builder::build() { fi } -_get_build_param() { +cicd_tools::image_builder::_get_build_param() { local option_key="$1" local raw_params="$2" local build_param for raw_param in $raw_params; do - build_param="${build_param} ${option_key} ${raw_param}" + build_param=$(echo -n "${build_param} ${option_key} ${raw_param}") done echo -n "$build_param" } -_get_expiry_label() { - echo "--label quay.expires-after=${CICD_TOOLS_IMAGE_BUILDER_QUAY_EXPIRE_TIME}" +cicd_tools::image_builder::_get_expiry_label() { + echo "quay.expires-after=${CICD_TOOLS_IMAGE_BUILDER_QUAY_EXPIRE_TIME}" } -_set_image_tag() { +cicd_tools::image_builder::_set_image_tag() { local image_tag commit_hash build_id commit_hash=$(cicd_tools::common::get_7_chars_commit_hash) - if _is_change_request_context; then - build_id=$(_get_build_id) + if cicd_tools::image_builder::is_change_request_context; then + build_id=$(cicd_tools::image_builder::get_build_id) image_tag="pr-${build_id}-${commit_hash}" else image_tag="$commit_hash" @@ -113,11 +113,11 @@ _set_image_tag() { readonly CICD_TOOLS_IMAGE_BUILDER_IMAGE_TAG } -_is_change_request_context() { +cicd_tools::image_builder::is_change_request_context() { [ -n "$ghprbPullId" ] || [ -n "$gitlabMergeRequestId" ] } -_get_build_id() { +cicd_tools::image_builder::get_build_id() { local build_id @@ -130,33 +130,42 @@ _get_build_id() { echo -n "$build_id" } -_image_builder_setup() { - _try_log_in_to_image_registries - _set_image_tag +cicd_tools::image_builder::_image_builder_setup() { + if ! cicd_tools::image_builder::_try_log_in_to_image_registries; then + cicd_tools::err "Error trying to log into the image registries!" + return 1 + fi + cicd_tools::image_builder::_set_image_tag } -_try_log_in_to_image_registries() { +cicd_tools::image_builder::_try_log_in_to_image_registries() { - if _quay_credentials_found; then - _log_in_to_quay + if cicd_tools::image_builder::_quay_credentials_found; then + if ! cicd_tools::image_builder::_log_in_to_quay_registry; then + cicd_tools::err "Error logging in to Quay.io!" + return 1 + fi fi - if _redhat_registry_credentials_found; then - _log_in_to_redhat_registry + if cicd_tools::image_builder::_redhat_registry_credentials_found; then + if ! cicd_tools::image_builder::_log_in_to_redhat_registry; then + cicd_tools::err "Error logging in to Red Hat Registry!" + return 1 + fi fi } -_quay_credentials_found() { +cicd_tools::image_builder::_quay_credentials_found() { [ -n "$CICD_TOOLS_IMAGE_BUILDER_QUAY_USER" ] && \ [ -n "$CICD_TOOLS_IMAGE_BUILDER_QUAY_PASSWORD" ] } -_redhat_registry_credentials_found() { +cicd_tools::image_builder::_redhat_registry_credentials_found() { [ -n "$CICD_TOOLS_IMAGE_BUILDER_REDHAT_USER" ] && \ [ -n "$CICD_TOOLS_IMAGE_BUILDER_REDHAT_PASSWORD" ] } -_log_in_to_container_registry() { +cicd_tools::image_builder::_log_in_to_container_registry() { local username="$1" local password="$2" @@ -165,21 +174,23 @@ _log_in_to_container_registry() { cicd_tools::container::cmd login "-u=${username}" "--password-stdin" "$registry" <<< "$password" } -_log_in_to_quay_registry() { - _log_in_to_container_registry "$CICD_TOOLS_IMAGE_BUILDER_QUAY_USER" \ +cicd_tools::image_builder::_log_in_to_quay_registry() { + cicd_tools::image_builder::_log_in_to_container_registry "$CICD_TOOLS_IMAGE_BUILDER_QUAY_USER" \ "$CICD_TOOLS_IMAGE_BUILDER_QUAY_PASSWORD" \ "$CICD_TOOLS_IMAGE_BUILDER_QUAY_REGISTRY" } -_log_in_to_redhat_registry() { - _log_in_to_container_registry "$CICD_TOOLS_IMAGE_BUILDER_REDHAT_USER" \ +cicd_tools::image_builder::_log_in_to_redhat_registry() { + cicd_tools::image_builder::_log_in_to_container_registry "$CICD_TOOLS_IMAGE_BUILDER_REDHAT_USER" \ "$CICD_TOOLS_IMAGE_BUILDER_REDHAT_PASSWORD" \ "$CICD_TOOLS_IMAGE_BUILDER_REDHAT_REGISTRY" } -if ! _image_builder_setup; then +if ! cicd_tools::image_builder::_image_builder_setup; then cicd_tools::err "Image builder setup failed!" return 1 fi +cicd_tools::debug "Image builder lib loaded" + CICD_TOOLS_IMAGE_BUILDER_LOADED=0 diff --git a/test/data/Containerfile.empty b/test/data/Containerfile.empty new file mode 100644 index 00000000..e69de29b diff --git a/test/data/Containerfile.test b/test/data/Containerfile.test new file mode 100644 index 00000000..52cd0947 --- /dev/null +++ b/test/data/Containerfile.test @@ -0,0 +1,2 @@ +FROM registry.access.redhat.com/ubi8/ubi-minimal:8.8-1037 +RUN echo "testing is fun!" diff --git a/test/shared_image_builder_lib.bats b/test/shared_image_builder_lib.bats index bdd65b56..65907364 100644 --- a/test/shared_image_builder_lib.bats +++ b/test/shared_image_builder_lib.bats @@ -36,6 +36,11 @@ setup() { @test "Image tag is set appropriately in a Pull Request context" { + # git mock + git() { + echo "1abcdef" + } + ghprbPullId=123 source main.sh image_builder run cicd_tools::image_builder::get_image_tag @@ -47,6 +52,11 @@ setup() { @test "Image tag is set appropriately in a Merge Request context" { + # git mock + git() { + echo "1abcdef" + } + gitlabMergeRequestId=4321 source main.sh image_builder run cicd_tools::image_builder::get_image_tag @@ -55,3 +65,160 @@ setup() { assert [ -n "$CICD_TOOLS_IMAGE_BUILDER_IMAGE_TAG" ] } + +@test "Image build works as expected" { + + # podman mock + podman() { + echo "$@" + } + + # git mock + git() { + echo "1abcdef" + } + + source main.sh image_builder + run ! cicd_tools::image_builder::build + assert_failure + assert_output --partial "you must specify an image name to build" + + run ! cicd_tools::image_builder::build -i "foobar" -f "non-existent-Containerfile" + assert_failure + assert_output --partial "non-existent-Containerfile not found " + + run ! cicd_tools::image_builder::build -i "defaults" + assert_output --partial "Dockerfile not found" + + run ! cicd_tools::image_builder::build -i foo -f "test/data/Containerfile.test" -X + assert_output --partial "X" + assert_output --partial "cannot handle parameter" + + run cicd_tools::image_builder::build -i "someimage" -f "test/data/Containerfile.test" + assert_success + assert_output --partial "" + assert_output --regexp "\.$" + + run cicd_tools::image_builder::build \ + -l "LABEL1=FOO LABEL2=bar" \ + -i "quay.io/my-awesome-org/my-awesome-app" \ + -t "test1 additional-label-2 security" \ + -b "BUILD_ARG1=foobar BUILD_ARG2=bananas" \ + -c "another/context" \ + -f "test/data/Containerfile.test" + assert_success + assert_output --regexp "^build.*" + assert_output --regexp "another/context$" + assert_output --partial "-f test/data/Containerfile.test" + assert_output --regexp "-t quay.io/my-awesome-org/my-awesome-app:[0-9a-f]{7}" + assert_output --regexp "--label LABEL1=FOO --label LABEL2=bar" + assert_output --regexp "-t quay.io/my-awesome-org/my-awesome-app:additional-label-2" + assert_output --regexp "-t quay.io/my-awesome-org/my-awesome-app:security" + assert_output --regexp "-t quay.io/my-awesome-org/my-awesome-app:test1" + assert_output --regexp "--build_arg BUILD_ARG1=foobar" + assert_output --regexp "--build_arg BUILD_ARG2=bananas" + + + run cicd_tools::image_builder::build -i "someimage" -f "test/data/Containerfile.test" + assert_success +} + +@test "Image builds gets expiry label in change request context" { + + # podman mock + podman() { + echo "$@" + } + + # git mock + git() { + echo "1abcdef" + } + + ghprbPullId="123" + + source main.sh image_builder + run cicd_tools::image_builder::build -i "someimage" -f "test/data/Containerfile.test" + assert_success + assert_output --partial "-t someimage:pr-123-1abcdef" + assert_output --partial "--label quay.expires-after=3d" +} + +@test "Image build failures are caught" { + + # podman mock + podman() { + echo "something went really wrong" >&2 + return 1 + } + + # git mock + git() { + echo "1abcdef" + } + + source main.sh image_builder + run cicd_tools::image_builder::build -i "someimage" -f "test/data/Containerfile.test" + assert_failure + assert_output --partial "went really wrong" + assert_output --partial "Error building image" + +} + +@test "Image builder tries to login to registries" { + + # podman mock + podman() { + echo "$@" + } + + CICD_TOOLS_IMAGE_BUILDER_QUAY_USER="username1" + CICD_TOOLS_IMAGE_BUILDER_QUAY_PASSWORD="secr3t" + + run source main.sh image_builder + assert_success + assert_output --regexp "^login.*quay.io" + assert_output --partial "-u=username1" + + CICD_TOOLS_IMAGE_BUILDER_REDHAT_USER="username2" + CICD_TOOLS_IMAGE_BUILDER_REDHAT_PASSWORD="secr3t" + + run source main.sh image_builder + assert_success + assert_output --regexp "^login.*registry.redhat.io" + assert_output --partial "-u=username2" +} + +@test "Image builder logs failure on logging in to Quay.io" { + + # podman mock + podman() { + return 1 + } + + CICD_TOOLS_IMAGE_BUILDER_QUAY_USER="wrong-user" + CICD_TOOLS_IMAGE_BUILDER_QUAY_PASSWORD="secr3t" + + run ! source main.sh image_builder + assert_failure + assert_output --partial "Image builder setup failed!" + assert_output --partial "Error logging in to Quay.io" + + +} + +@test "Image builder logs failure on logging in to Red Hat Registry" { + + # podman mock + podman() { + return 1 + } + + CICD_TOOLS_IMAGE_BUILDER_REDHAT_USER="wrong-user" + CICD_TOOLS_IMAGE_BUILDER_REDHAT_PASSWORD="wrong-password" + + run ! source main.sh image_builder + assert_failure + assert_output --partial "Image builder setup failed!" + assert_output --partial "Error logging in to Red Hat Registry" +} From 7e13c8ac36e5fcb06a05337111201fe8a02ae2d1 Mon Sep 17 00:00:00 2001 From: Victor M Date: Thu, 14 Sep 2023 20:45:12 +0200 Subject: [PATCH 11/39] fix e2e test --- test/e2e/test_e2e_load_library_from_function.sh | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/test/e2e/test_e2e_load_library_from_function.sh b/test/e2e/test_e2e_load_library_from_function.sh index eb043494..41eceac4 100755 --- a/test/e2e/test_e2e_load_library_from_function.sh +++ b/test/e2e/test_e2e_load_library_from_function.sh @@ -20,7 +20,7 @@ load_common_helper_cicd_tools() { } load_common_helper_cicd_tools container -EXPECTED_OUTPUT=$(container_engine_cmd --version) +EXPECTED_OUTPUT=$(cicd_tools::container::cmd --version) # Assert there's an actual output if ! [ "Docker version 99" == "$EXPECTED_OUTPUT" ]; then From acb10893af80aec7757144bea20eca1c4fbc0e7f Mon Sep 17 00:00:00 2001 From: Victor M Date: Thu, 14 Sep 2023 21:50:56 +0200 Subject: [PATCH 12/39] Apply ShellCheck suggestions --- src/shared/image_builder_lib.sh | 11 +++++------ 1 file changed, 5 insertions(+), 6 deletions(-) diff --git a/src/shared/image_builder_lib.sh b/src/shared/image_builder_lib.sh index 23415025..c8bce7f6 100644 --- a/src/shared/image_builder_lib.sh +++ b/src/shared/image_builder_lib.sh @@ -63,17 +63,16 @@ cicd_tools::image_builder::build() { labels="${labels} $(cicd_tools::image_builder::_get_expiry_label)" fi - for tag in ${CICD_TOOLS_IMAGE_BUILDER_IMAGE_TAG} ${additional_tags}; do tags="$tags ${image}:${tag}" done - labels_param="$(cicd_tools::image_builder::_get_build_param '--label' "$labels")" - build_args_param="$(cicd_tools::image_builder::_get_build_param '--build_arg' "$build_args")" - tags_param="$(cicd_tools::image_builder::_get_build_param '-t' "$tags")" + IFS=" " read -r -a labels_param <<< "$(cicd_tools::image_builder::_get_build_param '--label' "$labels")" + IFS=" " read -r -a build_args_param <<< "$(cicd_tools::image_builder::_get_build_param '--build_arg' "$build_args")" + IFS=" " read -r -a tags_param <<< "$(cicd_tools::image_builder::_get_build_param '-t' "$tags")" - if ! cicd_tools::container::cmd build -f "$containerfile" $tags_param $build_args_param $labels_param \ - "$context"; then + if ! cicd_tools::container::cmd build -f "$containerfile" "${tags_param[@]}" \ + "${build_args_param[@]}" "${labels_param[@]}" "$context"; then cicd_tools::err "Error building image" return 1 fi From cf46e0e8eaeb97dfa59cb0e831239cc4e811dbce Mon Sep 17 00:00:00 2001 From: Victor M Date: Fri, 15 Sep 2023 18:10:31 +0200 Subject: [PATCH 13/39] refactor to add module setup phase --- src/main.sh | 2 +- src/shared/image_builder_lib.sh | 179 ++++++++++++++++++++--------- test/main.bats | 1 + test/shared_image_builder_lib.bats | 111 ++++++++++-------- 4 files changed, 184 insertions(+), 109 deletions(-) diff --git a/src/main.sh b/src/main.sh index 79fdc00c..663d4a92 100644 --- a/src/main.sh +++ b/src/main.sh @@ -6,7 +6,7 @@ CICD_TOOLS_DEBUG="${CICD_TOOLS_DEBUG:-}" # https://stackoverflow.com/a/246128 SCRIPT_DIR="$( cd -- "$( dirname -- "${BASH_SOURCE[0]}" )" &> /dev/null && pwd )" CICD_TOOLS_SCRIPTS_DIR="${CICD_TOOLS_SCRIPTS_DIR:-$SCRIPT_DIR}" -LIB_TO_LOAD=${1:-all} +LIB_TO_LOAD=${1:-container} cicd_tools::debug() { if cicd_tools::_debug_mode; then diff --git a/src/shared/image_builder_lib.sh b/src/shared/image_builder_lib.sh index c8bce7f6..f7343aae 100644 --- a/src/shared/image_builder_lib.sh +++ b/src/shared/image_builder_lib.sh @@ -14,7 +14,10 @@ fi cicd_tools::debug "loading image builder library" # TODO: reconsider namespaced variables -CICD_TOOLS_IMAGE_BUILDER_IMAGE_TAG='' +CICD_TOOLS_IMAGE_BUILDER_IMAGE_TAGS=() +readonly CICD_TOOLS_IMAGE_BUILDER_CONTAINER_FILE="${CICD_TOOLS_IMAGE_BUILDER_CONTAINER_FILE:-Dockerfile}" +readonly CICD_TOOLS_IMAGE_BUILDER_BUILD_CONTEXT="${CICD_TOOLS_IMAGE_BUILDER_BUILD_CONTEXT:-.}" +readonly CICD_TOOLS_IMAGE_BUILDER_REPOSITORY="${CICD_TOOLS_IMAGE_BUILDER_REPOSITORY:-$IMAGE_REPOSITORY}" readonly CICD_TOOLS_IMAGE_BUILDER_REDHAT_REGISTRY='registry.redhat.io' readonly CICD_TOOLS_IMAGE_BUILDER_QUAY_REGISTRY='quay.io' readonly CICD_TOOLS_IMAGE_BUILDER_QUAY_EXPIRE_TIME=${CICD_TOOLS_IMAGE_BUILDER_QUAY_EXPIRE_TIME:-3d} @@ -22,100 +25,144 @@ readonly CICD_TOOLS_IMAGE_BUILDER_QUAY_USER="${CICD_TOOLS_IMAGE_BUILDER_QUAY_USE readonly CICD_TOOLS_IMAGE_BUILDER_QUAY_PASSWORD="${CICD_TOOLS_IMAGE_BUILDER_QUAY_PASSWORD:-$QUAY_TOKEN}" readonly CICD_TOOLS_IMAGE_BUILDER_REDHAT_USER="${CICD_TOOLS_IMAGE_BUILDER_REDHAT_USER:-$RH_REGISTRY_USER}" readonly CICD_TOOLS_IMAGE_BUILDER_REDHAT_PASSWORD="${CICD_TOOLS_IMAGE_BUILDER_REDHAT_PASSWORD:-$RH_REGISTRY_TOKEN}" +CICD_TOOLS_IMAGE_BUILDER_ADDITIONAL_TAGS=("${CICD_TOOLS_IMAGE_BUILDER_ADDITIONAL_TAGS[@]:-${ADDITIONAL_TAGS[@]}}") +#readonly CICD_TOOLS_IMAGE_BUILDER_ADDITIONAL_TAGS=("${CICD_TOOLS_IMAGE_BUILDER_ADDITIONAL_TAGS[@]:-}") +CICD_TOOLS_IMAGE_BUILDER_BUILD_ARGS=("${CICD_TOOLS_IMAGE_BUILDER_BUILD_ARGS[@]:-${BUILD_ARGS[@]}}") +#readonly CICD_TOOLS_IMAGE_BUILDER_BUILD_ARGS=("${CICD_TOOLS_IMAGE_BUILDER_BUILD_ARGS[@]:-}") +CICD_TOOLS_IMAGE_BUILDER_LABELS=("${CICD_TOOLS_IMAGE_BUILDER_LABELS[@]:-${LABELS[@]}}") +#CICD_TOOLS_IMAGE_BUILDER_LABELS=("${CICD_TOOLS_IMAGE_BUILDER_LABELS[@]:-}") + +cicd_tools::image_builder::get_default_image_tag() { + echo -n "${CICD_TOOLS_IMAGE_BUILDER_IMAGE_TAGS[0]}" +} -cicd_tools::image_builder::get_image_tag() { - echo -n "$CICD_TOOLS_IMAGE_BUILDER_IMAGE_TAG" +cicd_tools::image_builder::get_image_tags() { + echo -n "${CICD_TOOLS_IMAGE_BUILDER_IMAGE_TAGS[@]}" } -cicd_tools::image_builder::build() { +cicd_tools::image_builder::build_deploy() { + + cicd_tools::image_builder::build || return 1 + if cicd_tools::image_builder::is_change_request_context; then + cicd_tools::image_builder::push || return 1 + fi +} + +cicd_tools::image_builder::tag() { -# TODO: review params - local OPTIND OPTARG option image context containerfile additional_tags \ - labels labels_param build_args build_args_param tags tags_param - - while getopts 'b:c:f:i:l:t:' option; do - case "${option}" in - b) build_args="${OPTARG}" ;; - c) context="${OPTARG}" ;; - f) containerfile="${OPTARG}" ;; - i) image="${OPTARG}" ;; - l) labels="${OPTARG}" ;; - t) additional_tags="${OPTARG}" ;; - *) cicd_tools::err "cannot handle parameter" && return 1;; - esac + local source_image + source_image=$(cicd_tools::image_builder::get_default_image_tag) + + for target_image in "${CICD_TOOLS_IMAGE_BUILDER_IMAGE_TAGS[@]}"; do + cicd_tools::container::cmd tag "$source_image" "$target_image" done - # shift $((OPTIND-1)) +} - containerfile="${containerfile:-Dockerfile}" - context="${context:-.}" +cicd_tools::image_builder::build() { - if [ -z "$image" ]; then - cicd_tools::err "you must specify an image name to build with -i" - return 1 - fi + declare -a label_params + declare -a image_tag_params + declare -a build_arg_params - if [ ! -r "$containerfile" ]; then - cicd_tools::err "${containerfile} not found or not readable" - return 1 - fi + local containerfile build_context - if cicd_tools::image_builder::is_change_request_context; then - labels="${labels} $(cicd_tools::image_builder::_get_expiry_label)" - fi + containerfile="${CICD_TOOLS_IMAGE_BUILDER_CONTAINER_FILE}" + build_context="${CICD_TOOLS_IMAGE_BUILDER_BUILD_CONTEXT}" - for tag in ${CICD_TOOLS_IMAGE_BUILDER_IMAGE_TAG} ${additional_tags}; do - tags="$tags ${image}:${tag}" + for label in "${CICD_TOOLS_IMAGE_BUILDER_LABELS[@]}"; do + label_params+=("--label ${label}") done - IFS=" " read -r -a labels_param <<< "$(cicd_tools::image_builder::_get_build_param '--label' "$labels")" - IFS=" " read -r -a build_args_param <<< "$(cicd_tools::image_builder::_get_build_param '--build_arg' "$build_args")" - IFS=" " read -r -a tags_param <<< "$(cicd_tools::image_builder::_get_build_param '-t' "$tags")" + for image_tag in "${CICD_TOOLS_IMAGE_BUILDER_IMAGE_TAGS[@]}"; do + image_tag_params+=("-t ${image_tag}") + done + + for build_arg in "${CICD_TOOLS_IMAGE_BUILDER_BUILD_ARGS[@]}"; do + build_arg_params+=("--build-arg ${build_arg}") + done - if ! cicd_tools::container::cmd build -f "$containerfile" "${tags_param[@]}" \ - "${build_args_param[@]}" "${labels_param[@]}" "$context"; then + if ! cicd_tools::container::cmd build -f "$containerfile" "${image_tag_params[@]}" \ + "${build_arg_params[@]}" "${label_params[@]}" "$build_context"; then cicd_tools::err "Error building image" return 1 fi } -cicd_tools::image_builder::_get_build_param() { +cicd_tools::image_builder::push() { - local option_key="$1" - local raw_params="$2" - local build_param - - for raw_param in $raw_params; do - build_param=$(echo -n "${build_param} ${option_key} ${raw_param}") + for image_tag in "${CICD_TOOLS_IMAGE_BUILDER_IMAGE_TAGS[@]}"; do + if ! cicd_tools::container::cmd push "${image_tag}"; then + cicd_tools::err "Error pushing image: '$image_tag'" + return 1 + fi done - - echo -n "$build_param" } cicd_tools::image_builder::_get_expiry_label() { echo "quay.expires-after=${CICD_TOOLS_IMAGE_BUILDER_QUAY_EXPIRE_TIME}" } -cicd_tools::image_builder::_set_image_tag() { +cicd_tools::image_builder::get_main_tag() { + echo -n "${CICD_TOOLS_IMAGE_BUILDER_IMAGE_TAGS[0]}" +} + +cicd_tools::image_builder::_array_empty() { + local arr=("$1") - local image_tag commit_hash build_id + [[ "${#arr[@]}" -eq 1 && -z "${arr[0]}" ]] +} + +cicd_tools::image_builder::_sanitize_arrays() { + + if cicd_tools::image_builder::_array_empty "${CICD_TOOLS_IMAGE_BUILDER_ADDITIONAL_TAGS[@]}";then + CICD_TOOLS_IMAGE_BUILDER_ADDITIONAL_TAGS=() + fi + if cicd_tools::image_builder::_array_empty "${CICD_TOOLS_IMAGE_BUILDER_BUILD_ARGS[@]}";then + CICD_TOOLS_IMAGE_BUILDER_BUILD_ARGS=() + fi + if cicd_tools::image_builder::_array_empty "${CICD_TOOLS_IMAGE_BUILDER_LABELS[@]}";then + CICD_TOOLS_IMAGE_BUILDER_LABELS=() + fi +} +cicd_tools::image_builder::_set_image_tags() { + + local main_tag commit_hash build_id + local repository="$CICD_TOOLS_IMAGE_BUILDER_REPOSITORY" + + # TODO: handle if not in a `git` repository, git not available, etc commit_hash=$(cicd_tools::common::get_7_chars_commit_hash) if cicd_tools::image_builder::is_change_request_context; then build_id=$(cicd_tools::image_builder::get_build_id) - image_tag="pr-${build_id}-${commit_hash}" + main_tag="pr-${build_id}-${commit_hash}" else - image_tag="$commit_hash" + main_tag="$commit_hash" fi - CICD_TOOLS_IMAGE_BUILDER_IMAGE_TAG="$image_tag" - readonly CICD_TOOLS_IMAGE_BUILDER_IMAGE_TAG + CICD_TOOLS_IMAGE_BUILDER_IMAGE_TAGS=("${repository}:${main_tag}") + + for additional_tag in "${CICD_TOOLS_IMAGE_BUILDER_ADDITIONAL_TAGS[@]}"; do + CICD_TOOLS_IMAGE_BUILDER_IMAGE_TAGS+=("${repository}:${additional_tag}") + done + + cicd_tools::debug "Image tags: ${CICD_TOOLS_IMAGE_BUILDER_IMAGE_TAGS[*]}" + readonly CICD_TOOLS_IMAGE_BUILDER_IMAGE_TAGS +} + +cicd_tools::image_builder::_add_expiry_label() { + + local expiry_label + expiry_label=$(cicd_tools::image_builder::_get_expiry_label) + + CICD_TOOLS_IMAGE_BUILDER_LABELS+=("${expiry_label}") } cicd_tools::image_builder::is_change_request_context() { [ -n "$ghprbPullId" ] || [ -n "$gitlabMergeRequestId" ] } +# TODO: decide on should this be private? cicd_tools::image_builder::get_build_id() { local build_id @@ -130,11 +177,27 @@ cicd_tools::image_builder::get_build_id() { } cicd_tools::image_builder::_image_builder_setup() { + if ! cicd_tools::image_builder::_try_log_in_to_image_registries; then cicd_tools::err "Error trying to log into the image registries!" return 1 fi - cicd_tools::image_builder::_set_image_tag + + if [ -z "$CICD_TOOLS_IMAGE_BUILDER_REPOSITORY" ]; then + cicd_tools::err "Image repository not defined, please set IMAGE_REPOSITORY" + return 1 + fi + + cicd_tools::image_builder::_sanitize_arrays + cicd_tools::image_builder::_set_image_tags + + if cicd_tools::image_builder::is_change_request_context; then + cicd_tools::image_builder::_add_expiry_label + fi + + readonly CICD_TOOLS_IMAGE_BUILDER_LABELS + readonly CICD_TOOLS_IMAGE_BUILDER_ADDITIONAL_TAGS + readonly CICD_TOOLS_IMAGE_BUILDER_BUILD_ARGS } cicd_tools::image_builder::_try_log_in_to_image_registries() { @@ -174,13 +237,15 @@ cicd_tools::image_builder::_log_in_to_container_registry() { } cicd_tools::image_builder::_log_in_to_quay_registry() { - cicd_tools::image_builder::_log_in_to_container_registry "$CICD_TOOLS_IMAGE_BUILDER_QUAY_USER" \ + cicd_tools::image_builder::_log_in_to_container_registry \ + "$CICD_TOOLS_IMAGE_BUILDER_QUAY_USER" \ "$CICD_TOOLS_IMAGE_BUILDER_QUAY_PASSWORD" \ "$CICD_TOOLS_IMAGE_BUILDER_QUAY_REGISTRY" } cicd_tools::image_builder::_log_in_to_redhat_registry() { - cicd_tools::image_builder::_log_in_to_container_registry "$CICD_TOOLS_IMAGE_BUILDER_REDHAT_USER" \ + cicd_tools::image_builder::_log_in_to_container_registry \ + "$CICD_TOOLS_IMAGE_BUILDER_REDHAT_USER" \ "$CICD_TOOLS_IMAGE_BUILDER_REDHAT_PASSWORD" \ "$CICD_TOOLS_IMAGE_BUILDER_REDHAT_REGISTRY" } diff --git a/test/main.bats b/test/main.bats index a288a6d8..ba4ec598 100644 --- a/test/main.bats +++ b/test/main.bats @@ -22,6 +22,7 @@ setup() { @test "loading all work successfully" { CICD_TOOLS_DEBUG=1 + IMAGE_REPOSITORY='foobar' run source main.sh all assert_success assert_output --partial "loading common lib" diff --git a/test/shared_image_builder_lib.bats b/test/shared_image_builder_lib.bats index 65907364..ca57b54a 100644 --- a/test/shared_image_builder_lib.bats +++ b/test/shared_image_builder_lib.bats @@ -17,6 +17,7 @@ setup() { assert [ -z "$CICD_TOOLS_CONTAINER_ENGINE_LOADED" ] assert [ -z "$CICD_TOOLS_IMAGE_BUILDER_LOADED" ] + IMAGE_REPOSITORY='foo' source main.sh image_builder assert [ -n "$CICD_TOOLS_COMMON_LOADED" ] @@ -24,17 +25,16 @@ setup() { assert [ -n "$CICD_TOOLS_IMAGE_BUILDER_LOADED" ] } -@test "Image tag is set appropriately outside of a change request context" { +@test "Default image tag is set appropriately outside of a change request context" { + IMAGE_REPOSITORY='foo/bar' source main.sh image_builder - run cicd_tools::image_builder::get_image_tag + run cicd_tools::image_builder::get_default_image_tag assert_success - assert_output --regexp '^[0-9a-f]{7}$' - - assert [ -n "$CICD_TOOLS_IMAGE_BUILDER_IMAGE_TAG" ] + assert_output --regexp '^foo/bar:[0-9a-f]{7}$' } -@test "Image tag is set appropriately in a Pull Request context" { +@test "Default image tag is set appropriately in a Pull Request context" { # git mock git() { @@ -42,15 +42,14 @@ setup() { } ghprbPullId=123 + IMAGE_REPOSITORY='pull/request' source main.sh image_builder - run cicd_tools::image_builder::get_image_tag + run cicd_tools::image_builder::get_default_image_tag assert_success - assert_output --regexp '^pr-[0-9]+-[0-9a-f]{7}$' - - assert [ -n "$CICD_TOOLS_IMAGE_BUILDER_IMAGE_TAG" ] + assert_output --regexp '^pull/request:pr-[0-9]+-[0-9a-f]{7}$' } -@test "Image tag is set appropriately in a Merge Request context" { +@test "Default image tag is set appropriately in a Merge Request context" { # git mock git() { @@ -58,15 +57,21 @@ setup() { } gitlabMergeRequestId=4321 + IMAGE_REPOSITORY='merge/request' source main.sh image_builder - run cicd_tools::image_builder::get_image_tag + run cicd_tools::image_builder::get_default_image_tag assert_success - assert_output --regexp '^pr-[0-9]+-[0-9a-f]{7}$' + assert_output --regexp '^merge/request:pr-[0-9]+-[0-9a-f]{7}$' +} + +@test "fails if no image repository is defined" { - assert [ -n "$CICD_TOOLS_IMAGE_BUILDER_IMAGE_TAG" ] + run ! source main.sh image_builder + assert_failure + assert_output --partial "Image repository not defined, please set IMAGE_REPOSITORY" } -@test "Image build works as expected" { +@test "Image build works as expected with default values" { # podman mock podman() { @@ -78,49 +83,49 @@ setup() { echo "1abcdef" } + IMAGE_REPOSITORY='foo' source main.sh image_builder - run ! cicd_tools::image_builder::build - assert_failure - assert_output --partial "you must specify an image name to build" + run cicd_tools::image_builder::build + assert_success + assert_output --regexp "^build" + assert_output --partial "-f Dockerfile" + assert_output --partial "-t foo:1abcdef" + assert_output --regexp "\.$" +} - run ! cicd_tools::image_builder::build -i "foobar" -f "non-existent-Containerfile" - assert_failure - assert_output --partial "non-existent-Containerfile not found " +@test "Image build works as expected with all custom values set" { - run ! cicd_tools::image_builder::build -i "defaults" - assert_output --partial "Dockerfile not found" + # podman mock + podman() { + echo "$@" + } - run ! cicd_tools::image_builder::build -i foo -f "test/data/Containerfile.test" -X - assert_output --partial "X" - assert_output --partial "cannot handle parameter" + # git mock + git() { + echo "1abcdef" + } - run cicd_tools::image_builder::build -i "someimage" -f "test/data/Containerfile.test" - assert_success - assert_output --partial "" - assert_output --regexp "\.$" + IMAGE_REPOSITORY='quay.io/my-awesome-org/my-awesome-app' + CICD_TOOLS_IMAGE_BUILDER_LABELS=("LABEL1=FOO" "LABEL2=bar") + CICD_TOOLS_IMAGE_BUILDER_ADDITIONAL_TAGS=("test1" "additional-label-2" "security") + CICD_TOOLS_IMAGE_BUILDER_BUILD_ARGS=("BUILD_ARG1=foobar" "BUILD_ARG2=bananas") + CICD_TOOLS_IMAGE_BUILDER_BUILD_CONTEXT='another/context' + CICD_TOOLS_IMAGE_BUILDER_CONTAINER_FILE='test/data/Containerfile.test' - run cicd_tools::image_builder::build \ - -l "LABEL1=FOO LABEL2=bar" \ - -i "quay.io/my-awesome-org/my-awesome-app" \ - -t "test1 additional-label-2 security" \ - -b "BUILD_ARG1=foobar BUILD_ARG2=bananas" \ - -c "another/context" \ - -f "test/data/Containerfile.test" + source main.sh image_builder + run cicd_tools::image_builder::build assert_success assert_output --regexp "^build.*" assert_output --regexp "another/context$" assert_output --partial "-f test/data/Containerfile.test" assert_output --regexp "-t quay.io/my-awesome-org/my-awesome-app:[0-9a-f]{7}" - assert_output --regexp "--label LABEL1=FOO --label LABEL2=bar" - assert_output --regexp "-t quay.io/my-awesome-org/my-awesome-app:additional-label-2" - assert_output --regexp "-t quay.io/my-awesome-org/my-awesome-app:security" - assert_output --regexp "-t quay.io/my-awesome-org/my-awesome-app:test1" - assert_output --regexp "--build_arg BUILD_ARG1=foobar" - assert_output --regexp "--build_arg BUILD_ARG2=bananas" - - - run cicd_tools::image_builder::build -i "someimage" -f "test/data/Containerfile.test" - assert_success + assert_output --partial "--label LABEL1=FOO" + assert_output --partial "--label LABEL2=bar" + assert_output --partial "-t quay.io/my-awesome-org/my-awesome-app:additional-label-2" + assert_output --partial "-t quay.io/my-awesome-org/my-awesome-app:security" + assert_output --partial "-t quay.io/my-awesome-org/my-awesome-app:test1" + assert_output --partial "--build-arg BUILD_ARG1=foobar" + assert_output --partial "--build-arg BUILD_ARG2=bananas" } @test "Image builds gets expiry label in change request context" { @@ -136,9 +141,9 @@ setup() { } ghprbPullId="123" - + IMAGE_REPOSITORY="someimage" source main.sh image_builder - run cicd_tools::image_builder::build -i "someimage" -f "test/data/Containerfile.test" + run cicd_tools::image_builder::build assert_success assert_output --partial "-t someimage:pr-123-1abcdef" assert_output --partial "--label quay.expires-after=3d" @@ -157,8 +162,9 @@ setup() { echo "1abcdef" } + IMAGE_REPOSITORY="someimage" source main.sh image_builder - run cicd_tools::image_builder::build -i "someimage" -f "test/data/Containerfile.test" + run cicd_tools::image_builder::build assert_failure assert_output --partial "went really wrong" assert_output --partial "Error building image" @@ -174,7 +180,8 @@ setup() { CICD_TOOLS_IMAGE_BUILDER_QUAY_USER="username1" CICD_TOOLS_IMAGE_BUILDER_QUAY_PASSWORD="secr3t" - + IMAGE_REPOSITORY="someimage" + run source main.sh image_builder assert_success assert_output --regexp "^login.*quay.io" @@ -198,6 +205,7 @@ setup() { CICD_TOOLS_IMAGE_BUILDER_QUAY_USER="wrong-user" CICD_TOOLS_IMAGE_BUILDER_QUAY_PASSWORD="secr3t" + IMAGE_REPOSITORY="someimage" run ! source main.sh image_builder assert_failure @@ -216,6 +224,7 @@ setup() { CICD_TOOLS_IMAGE_BUILDER_REDHAT_USER="wrong-user" CICD_TOOLS_IMAGE_BUILDER_REDHAT_PASSWORD="wrong-password" + IMAGE_REPOSITORY="someimage" run ! source main.sh image_builder assert_failure From c2b9abed12265bca5bf0d284aa94ffbb3738f50e Mon Sep 17 00:00:00 2001 From: Victor M Date: Fri, 15 Sep 2023 18:16:30 +0200 Subject: [PATCH 14/39] fix E2E tests --- test/e2e/test_e2e_load_library_from_bootstrap_script.sh | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/test/e2e/test_e2e_load_library_from_bootstrap_script.sh b/test/e2e/test_e2e_load_library_from_bootstrap_script.sh index 28765db6..74fd4acf 100755 --- a/test/e2e/test_e2e_load_library_from_bootstrap_script.sh +++ b/test/e2e/test_e2e_load_library_from_bootstrap_script.sh @@ -42,7 +42,7 @@ if ! [ "Docker version 99" == "$EXPECTED_OUTPUT" ]; then exit 1 fi -load_cicd_helper_functions +load_cicd_helper_functions container # Assert output doesn't change if ! [ "$(cicd_tools::container::cmd --version)" == "$EXPECTED_OUTPUT" ]; then From 2727d7ff3e0fa7821ac99b0dc92155749bbd6395 Mon Sep 17 00:00:00 2001 From: Victor M Date: Fri, 15 Sep 2023 20:28:02 +0200 Subject: [PATCH 15/39] Increase coverage --- src/shared/image_builder_lib.sh | 10 +--- test/main.bats | 11 +++- test/shared_image_builder_lib.bats | 82 ++++++++++++++++++++++++++++-- 3 files changed, 89 insertions(+), 14 deletions(-) diff --git a/src/shared/image_builder_lib.sh b/src/shared/image_builder_lib.sh index f7343aae..b956c35a 100644 --- a/src/shared/image_builder_lib.sh +++ b/src/shared/image_builder_lib.sh @@ -102,10 +102,6 @@ cicd_tools::image_builder::_get_expiry_label() { echo "quay.expires-after=${CICD_TOOLS_IMAGE_BUILDER_QUAY_EXPIRE_TIME}" } -cicd_tools::image_builder::get_main_tag() { - echo -n "${CICD_TOOLS_IMAGE_BUILDER_IMAGE_TAGS[0]}" -} - cicd_tools::image_builder::_array_empty() { local arr=("$1") @@ -237,15 +233,13 @@ cicd_tools::image_builder::_log_in_to_container_registry() { } cicd_tools::image_builder::_log_in_to_quay_registry() { - cicd_tools::image_builder::_log_in_to_container_registry \ - "$CICD_TOOLS_IMAGE_BUILDER_QUAY_USER" \ + cicd_tools::image_builder::_log_in_to_container_registry "$CICD_TOOLS_IMAGE_BUILDER_QUAY_USER" \ "$CICD_TOOLS_IMAGE_BUILDER_QUAY_PASSWORD" \ "$CICD_TOOLS_IMAGE_BUILDER_QUAY_REGISTRY" } cicd_tools::image_builder::_log_in_to_redhat_registry() { - cicd_tools::image_builder::_log_in_to_container_registry \ - "$CICD_TOOLS_IMAGE_BUILDER_REDHAT_USER" \ + cicd_tools::image_builder::_log_in_to_container_registry "$CICD_TOOLS_IMAGE_BUILDER_REDHAT_USER" \ "$CICD_TOOLS_IMAGE_BUILDER_REDHAT_PASSWORD" \ "$CICD_TOOLS_IMAGE_BUILDER_REDHAT_REGISTRY" } diff --git a/test/main.bats b/test/main.bats index ba4ec598..82bb720f 100644 --- a/test/main.bats +++ b/test/main.bats @@ -49,14 +49,21 @@ setup() { @test "Loading multiple times don't reload libraries multiple times" { + IMAGE_REPOSITORY='FOO' assert [ -z "$CICD_TOOLS_COMMON_LOADED" ] - source main.sh + source main.sh all assert [ "$CICD_TOOLS_COMMON_LOADED" -eq 0 ] CICD_TOOLS_DEBUG=1 run source main.sh "" + assert_success refute_output --partial "loading common lib" run source main.sh all + assert_success refute_output --partial "loading common lib" - run source main.sh container + run source main.sh container + assert_success refute_output --partial "loading container lib" + run source main.sh image_builder + assert_success + refute_output --partial "loading image_builder lib" } diff --git a/test/shared_image_builder_lib.bats b/test/shared_image_builder_lib.bats index ca57b54a..1f1b60bd 100644 --- a/test/shared_image_builder_lib.bats +++ b/test/shared_image_builder_lib.bats @@ -161,7 +161,7 @@ setup() { git() { echo "1abcdef" } - + IMAGE_REPOSITORY="someimage" source main.sh image_builder run cicd_tools::image_builder::build @@ -184,7 +184,7 @@ setup() { run source main.sh image_builder assert_success - assert_output --regexp "^login.*quay.io" + assert_output --regexp "^login.*quay.io" assert_output --partial "-u=username1" CICD_TOOLS_IMAGE_BUILDER_REDHAT_USER="username2" @@ -192,7 +192,7 @@ setup() { run source main.sh image_builder assert_success - assert_output --regexp "^login.*registry.redhat.io" + assert_output --regexp "^login.*registry.redhat.io" assert_output --partial "-u=username2" } @@ -206,7 +206,7 @@ setup() { CICD_TOOLS_IMAGE_BUILDER_QUAY_USER="wrong-user" CICD_TOOLS_IMAGE_BUILDER_QUAY_PASSWORD="secr3t" IMAGE_REPOSITORY="someimage" - + run ! source main.sh image_builder assert_failure assert_output --partial "Image builder setup failed!" @@ -231,3 +231,77 @@ setup() { assert_output --partial "Image builder setup failed!" assert_output --partial "Error logging in to Red Hat Registry" } + + +@test "Get default image tag" { + + # git mock + git() { + echo "1abcdef" + } + IMAGE_REPOSITORY="someimage" + + source main.sh image_builder + run cicd_tools::image_builder::get_default_image_tag + assert_success + assert_output "someimage:1abcdef" +} + +@test "Get all image tags" { + + # git mock + git() { + echo "1abcdef" + } + IMAGE_REPOSITORY="someimage" + ADDITIONAL_TAGS=("foo" "bar" "baz") + + source main.sh image_builder + run cicd_tools::image_builder::get_image_tags + assert_success + assert_output --partial "someimage:1abcdef" + assert_output --partial "someimage:foo" + assert_output --partial "someimage:bar" +} + +@test "tag all images" { + + # git mock + git() { + echo "source" + } + # podman mock + podman() { + echo "$@" + } + IMAGE_REPOSITORY="someimage" + ADDITIONAL_TAGS=("target1" "target2" "target3") + + source main.sh image_builder + run cicd_tools::image_builder::tag + # TODO: fix - this tries to tag source and source + refute_output --partial "tag someimage:source someimage:source" + assert_output --partial "tag someimage:source someimage:target1" + assert_output --partial "tag someimage:source someimage:target1" + assert_output --partial "tag someimage:source someimage:target1" +} + +@test "push all images" { + + # git mock + git() { + echo "abcdef1" + } + # podman mock + podman() { + echo "$@" + } + IMAGE_REPOSITORY="someimage" + ADDITIONAL_TAGS=("tag1" "tag2") + + source main.sh image_builder + run cicd_tools::image_builder::push + assert_output --partial "push someimage:abcdef1" + assert_output --partial "push someimage:tag1" + assert_output --partial "push someimage:tag2" +} From 315299473d3e9478b37ba775dd5ae7d3e919418b Mon Sep 17 00:00:00 2001 From: Victor M Date: Mon, 18 Sep 2023 15:18:04 +0200 Subject: [PATCH 16/39] Increased coverage --- src/shared/image_builder_lib.sh | 8 +++++- test/shared_image_builder_lib.bats | 45 ++++++++++++++++++++++++++++-- 2 files changed, 50 insertions(+), 3 deletions(-) diff --git a/src/shared/image_builder_lib.sh b/src/shared/image_builder_lib.sh index b956c35a..a6a97e76 100644 --- a/src/shared/image_builder_lib.sh +++ b/src/shared/image_builder_lib.sh @@ -54,7 +54,13 @@ cicd_tools::image_builder::tag() { source_image=$(cicd_tools::image_builder::get_default_image_tag) for target_image in "${CICD_TOOLS_IMAGE_BUILDER_IMAGE_TAGS[@]}"; do - cicd_tools::container::cmd tag "$source_image" "$target_image" + if [ "$target_image" = "$source_image" ]; then + continue + fi + if ! cicd_tools::container::cmd tag "$source_image" "$target_image"; then + cicd_tools::err "Error tagging image: '$source_image' as '$target_image'" + return 1 + fi done } diff --git a/test/shared_image_builder_lib.bats b/test/shared_image_builder_lib.bats index 1f1b60bd..19c1611c 100644 --- a/test/shared_image_builder_lib.bats +++ b/test/shared_image_builder_lib.bats @@ -279,11 +279,31 @@ setup() { source main.sh image_builder run cicd_tools::image_builder::tag - # TODO: fix - this tries to tag source and source refute_output --partial "tag someimage:source someimage:source" assert_output --partial "tag someimage:source someimage:target1" + assert_output --partial "tag someimage:source someimage:target2" + assert_output --partial "tag someimage:source someimage:target3" +} + +@test "tag error is caught" { + + # git mock + git() { + echo "source" + } + # podman mock + podman() { + echo "$@" + return 1 + } + IMAGE_REPOSITORY="someimage" + ADDITIONAL_TAGS=("target1") + + source main.sh image_builder + run ! cicd_tools::image_builder::tag + assert_failure assert_output --partial "tag someimage:source someimage:target1" - assert_output --partial "tag someimage:source someimage:target1" + assert_output --partial "Error tagging image" } @test "push all images" { @@ -305,3 +325,24 @@ setup() { assert_output --partial "push someimage:tag1" assert_output --partial "push someimage:tag2" } + +@test "push error is caught" { + + # git mock + git() { + echo "source" + } + # podman mock + podman() { + echo "$@" + return 1 + } + IMAGE_REPOSITORY="someimage" + ADDITIONAL_TAGS=("target1") + + source main.sh image_builder + run ! cicd_tools::image_builder::push + assert_failure + assert_output --partial "push someimage:source" + assert_output --partial "Error pushing image" +} From 5ec3077df4c565353f563e1568a2e4a67122e1ec Mon Sep 17 00:00:00 2001 From: Victor M Date: Mon, 18 Sep 2023 15:42:47 +0200 Subject: [PATCH 17/39] increase coverage --- test/shared_image_builder_lib.bats | 44 ++++++++++++++++++++++++++++++ 1 file changed, 44 insertions(+) diff --git a/test/shared_image_builder_lib.bats b/test/shared_image_builder_lib.bats index 19c1611c..b3e1e2ec 100644 --- a/test/shared_image_builder_lib.bats +++ b/test/shared_image_builder_lib.bats @@ -346,3 +346,47 @@ setup() { assert_output --partial "push someimage:source" assert_output --partial "Error pushing image" } + +@test "build deploy does not push if not on change request context" { + + # git mock + git() { + echo "source" + } + # podman mock + podman() { + echo "$@" + } + IMAGE_REPOSITORY="someimage" + ADDITIONAL_TAGS=("target1") + + source main.sh image_builder + run cicd_tools::image_builder::build_deploy + assert_success + assert_output --regexp "^build.*?-t someimage:source -t someimage:target1" + refute_output --partial "push" +} + +@test "build deploy pushes if on change request context" { + + # git mock + git() { + echo "source" + } + # podman mock + podman() { + echo "$@" + } + IMAGE_REPOSITORY="someimage" + ADDITIONAL_TAGS=("target1") + ghprbPullId='123' + + source main.sh image_builder + + run cicd_tools::image_builder::build_deploy + assert_success + assert_output --regexp "^build.*?-t someimage:pr-123-source -t someimage:target1" + assert_output --regexp "^build.*?--label quay.expires-after" + assert_output --partial "push someimage:pr-123-source" + assert_output --partial "push someimage:target1" +} From 1c4881fc1c510be7f9f9a4c02285d14f9f6f6513 Mon Sep 17 00:00:00 2001 From: Victor M Date: Mon, 18 Sep 2023 15:57:19 +0200 Subject: [PATCH 18/39] Update README.md --- README.md | 43 ++++++++++++++++++++++++++++++------------- 1 file changed, 30 insertions(+), 13 deletions(-) diff --git a/README.md b/README.md index 4adcc1c7..caf007c0 100644 --- a/README.md +++ b/README.md @@ -21,18 +21,26 @@ Grab the Jenkinsfile template for your [backend](examples/backend-pipeline-pr-ch ## Bash script helper scripts usage -The collection of helper scripts are expected to be loaded using the provided [src/bootstrap.sh](bootstrap) script. +The collection of helper libraries are expected to be loaded using the provided [src/bootstrap.sh](bootstrap) script. -Currently there is 1 collection available: +Currently there are 2 supported libraries: -- Container helper scripts: provides wrapper functions for invoking container engine agnostic commands +|Library ID|Description| +|----------|-----------| +|container | Provides wrapper functions for invoking container engine agnostic commands| +|image_builder| Provides helper functions to simplify the image building process| + +### How to use the helper libraries + +To use any of the provided libraries, you must source the [src/bootstrap.sh](bootstrap.sh) script and pass +the unique library ID to be loaded as a paramter. -To use any of the provided libraries, you must source the [src/bootstrap.sh](bootstrap.sh) script. One can simply either source the [src/bootstrap.sh](bootstrap) script directly: ``` -$ source <(curl -sSL https://raw.githubusercontent.com/RedHatInsights/cicd-tools/main/src/bootstrap.sh) -$ container_engine_cmd --version +$ source <(curl -sSL https://raw.githubusercontent.com/RedHatInsights/cicd-tools/main/src/bootstrap.sh) container + +$ cicd_tools::container::cmd --version podman version 4.6.1 ``` @@ -42,22 +50,20 @@ In case you want to refactor some of your scripts using this library, here's a s ``` load_cicd_helper_functions() { - local LIBRARY_TO_LOAD=${1:-all} + local LIBRARY_TO_LOAD="$1" local CICD_TOOLS_REPO_BRANCH='main' local CICD_TOOLS_REPO_ORG='RedHatInsights' local CICD_TOOLS_URL="https://raw.githubusercontent.com/${CICD_TOOLS_REPO_ORG}/cicd-tools/${CICD_TOOLS_REPO_BRANCH}/src/bootstrap.sh" - set -e source <(curl -sSL "$CICD_TOOLS_URL") "$LIBRARY_TO_LOAD" - set +e } -load_cicd_helper_functions +load_cicd_helper_functions container ``` you can select which collection needs to load independently as a parameter: ``` -source bootstrap.sh container_engine +source bootstrap.sh container ``` The bootstrap script will download the selected version of the CICD scripts (or `latest` if none specified) into the directory defined by @@ -70,8 +76,19 @@ The bootstrap.sh can be invoked multiple times but it has a status control to en of the libraries is loaded only once. This is to prevent potential issues with collections that are not supposed to be loaded many times. -An example of this is the _container_engine_ library, where the selected container engine -is **set only once the first command using the library helper function `container_engine_cmd` is used**. +An example of this is the _container_ library, where the selected container engine +is **set only once the first command using the library helper function `cicd_tools::container::cmd` is used**. + +Each of the libraries will export to the shell sourcing the bootstrap script the helper functions. +These functions are all namespaced, meaning the names follow the naming format: + +``` +cicd_tools::library::function +``` + +where: +- cicd_tools represents the namespace root, which is shared by all functions +- library would match with each of the imported library IDs. ## Template Scripts From 557967d7b2f78204f12274250851acdd22c831b5 Mon Sep 17 00:00:00 2001 From: Victor M Date: Mon, 18 Sep 2023 18:18:54 +0200 Subject: [PATCH 19/39] Test for image_builder --- test/e2e/test_image_builder.sh | 28 ++++++++++++++++++++++++++++ 1 file changed, 28 insertions(+) create mode 100755 test/e2e/test_image_builder.sh diff --git a/test/e2e/test_image_builder.sh b/test/e2e/test_image_builder.sh new file mode 100755 index 00000000..ad2e348e --- /dev/null +++ b/test/e2e/test_image_builder.sh @@ -0,0 +1,28 @@ +#!/usr/bin/env bash + +# Mock functions +podman() { + echo -n "$@" +} + +git() { + echo -n "abcdef1" +} + +CICD_TOOLS_IMAGE_BUILDER_CONTAINER_FILE='test/data/Containerfile.test' +IMAGE_REPOSITORY='quay.io/awesome_repo/awesome/app' +MAIN_SCRIPT='./src/main.sh' + +source "$MAIN_SCRIPT" "image_builder" + +EXPECTED_OUTPUT=$(cicd_tools::image_builder::build_deploy) + +if ! [ "build -f ${CICD_TOOLS_IMAGE_BUILDER_CONTAINER_FILE} -t ${IMAGE_REPOSITORY}:abcdef1 ." = "$EXPECTED_OUTPUT" ]; then + echo "image build_deploy not working!" + exit 1 +fi + +unset podman + + +cicd_tools::image_builder::build_deploy From cc57df440491cbc2abf70c72da95d2e6a02834e9 Mon Sep 17 00:00:00 2001 From: Victor M Date: Mon, 18 Sep 2023 18:38:51 +0200 Subject: [PATCH 20/39] fix quotes --- src/shared/image_builder_lib.sh | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/src/shared/image_builder_lib.sh b/src/shared/image_builder_lib.sh index a6a97e76..54c11250 100644 --- a/src/shared/image_builder_lib.sh +++ b/src/shared/image_builder_lib.sh @@ -76,15 +76,15 @@ cicd_tools::image_builder::build() { build_context="${CICD_TOOLS_IMAGE_BUILDER_BUILD_CONTEXT}" for label in "${CICD_TOOLS_IMAGE_BUILDER_LABELS[@]}"; do - label_params+=("--label ${label}") + label_params+=('--label' "${label}") done for image_tag in "${CICD_TOOLS_IMAGE_BUILDER_IMAGE_TAGS[@]}"; do - image_tag_params+=("-t ${image_tag}") + image_tag_params+=('-t' "${image_tag}") done for build_arg in "${CICD_TOOLS_IMAGE_BUILDER_BUILD_ARGS[@]}"; do - build_arg_params+=("--build-arg ${build_arg}") + build_arg_params+=('--build-arg' "${build_arg}") done if ! cicd_tools::container::cmd build -f "$containerfile" "${image_tag_params[@]}" \ From b1d527055a01e3d9044d90eca05d86b441358c8b Mon Sep 17 00:00:00 2001 From: Victor M Date: Wed, 20 Sep 2023 11:26:32 +0200 Subject: [PATCH 21/39] wip --- src/shared/image_builder_lib.sh | 313 ++++++++++++++++++++--------- test/shared_image_builder_lib.bats | 184 +++++++++++------ 2 files changed, 336 insertions(+), 161 deletions(-) diff --git a/src/shared/image_builder_lib.sh b/src/shared/image_builder_lib.sh index 54c11250..78dd7272 100644 --- a/src/shared/image_builder_lib.sh +++ b/src/shared/image_builder_lib.sh @@ -13,11 +13,6 @@ fi cicd_tools::debug "loading image builder library" -# TODO: reconsider namespaced variables -CICD_TOOLS_IMAGE_BUILDER_IMAGE_TAGS=() -readonly CICD_TOOLS_IMAGE_BUILDER_CONTAINER_FILE="${CICD_TOOLS_IMAGE_BUILDER_CONTAINER_FILE:-Dockerfile}" -readonly CICD_TOOLS_IMAGE_BUILDER_BUILD_CONTEXT="${CICD_TOOLS_IMAGE_BUILDER_BUILD_CONTEXT:-.}" -readonly CICD_TOOLS_IMAGE_BUILDER_REPOSITORY="${CICD_TOOLS_IMAGE_BUILDER_REPOSITORY:-$IMAGE_REPOSITORY}" readonly CICD_TOOLS_IMAGE_BUILDER_REDHAT_REGISTRY='registry.redhat.io' readonly CICD_TOOLS_IMAGE_BUILDER_QUAY_REGISTRY='quay.io' readonly CICD_TOOLS_IMAGE_BUILDER_QUAY_EXPIRE_TIME=${CICD_TOOLS_IMAGE_BUILDER_QUAY_EXPIRE_TIME:-3d} @@ -25,20 +20,6 @@ readonly CICD_TOOLS_IMAGE_BUILDER_QUAY_USER="${CICD_TOOLS_IMAGE_BUILDER_QUAY_USE readonly CICD_TOOLS_IMAGE_BUILDER_QUAY_PASSWORD="${CICD_TOOLS_IMAGE_BUILDER_QUAY_PASSWORD:-$QUAY_TOKEN}" readonly CICD_TOOLS_IMAGE_BUILDER_REDHAT_USER="${CICD_TOOLS_IMAGE_BUILDER_REDHAT_USER:-$RH_REGISTRY_USER}" readonly CICD_TOOLS_IMAGE_BUILDER_REDHAT_PASSWORD="${CICD_TOOLS_IMAGE_BUILDER_REDHAT_PASSWORD:-$RH_REGISTRY_TOKEN}" -CICD_TOOLS_IMAGE_BUILDER_ADDITIONAL_TAGS=("${CICD_TOOLS_IMAGE_BUILDER_ADDITIONAL_TAGS[@]:-${ADDITIONAL_TAGS[@]}}") -#readonly CICD_TOOLS_IMAGE_BUILDER_ADDITIONAL_TAGS=("${CICD_TOOLS_IMAGE_BUILDER_ADDITIONAL_TAGS[@]:-}") -CICD_TOOLS_IMAGE_BUILDER_BUILD_ARGS=("${CICD_TOOLS_IMAGE_BUILDER_BUILD_ARGS[@]:-${BUILD_ARGS[@]}}") -#readonly CICD_TOOLS_IMAGE_BUILDER_BUILD_ARGS=("${CICD_TOOLS_IMAGE_BUILDER_BUILD_ARGS[@]:-}") -CICD_TOOLS_IMAGE_BUILDER_LABELS=("${CICD_TOOLS_IMAGE_BUILDER_LABELS[@]:-${LABELS[@]}}") -#CICD_TOOLS_IMAGE_BUILDER_LABELS=("${CICD_TOOLS_IMAGE_BUILDER_LABELS[@]:-}") - -cicd_tools::image_builder::get_default_image_tag() { - echo -n "${CICD_TOOLS_IMAGE_BUILDER_IMAGE_TAGS[0]}" -} - -cicd_tools::image_builder::get_image_tags() { - echo -n "${CICD_TOOLS_IMAGE_BUILDER_IMAGE_TAGS[@]}" -} cicd_tools::image_builder::build_deploy() { @@ -50,15 +31,18 @@ cicd_tools::image_builder::build_deploy() { cicd_tools::image_builder::tag() { - local source_image - source_image=$(cicd_tools::image_builder::get_default_image_tag) + local source_tag target_tag image_name - for target_image in "${CICD_TOOLS_IMAGE_BUILDER_IMAGE_TAGS[@]}"; do - if [ "$target_image" = "$source_image" ]; then - continue - fi - if ! cicd_tools::container::cmd tag "$source_image" "$target_image"; then - cicd_tools::err "Error tagging image: '$source_image' as '$target_image'" + if ! image_name="$(cicd_tools::image_builder::_get_image_name)"; then + cicd_tools::err "Error getting Image name to tag" + return 1 + fi + + source_tag="$(cicd_tools::image_builder::get_image_tag)" + + for target_tag in $(cicd_tools::image_builder::get_additional_tags); do + if ! cicd_tools::container::cmd tag "${image_name}:${source_tag}" "${image_name}:${target_tag}"; then + cicd_tools::err "Error tagging '${image_name}:${source_tag}' as '${image_name}:${target_tag}'" return 1 fi done @@ -66,25 +50,51 @@ cicd_tools::image_builder::tag() { cicd_tools::image_builder::build() { - declare -a label_params - declare -a image_tag_params - declare -a build_arg_params +# declare -a image_tag_params +# declare -a build_arg_params - local containerfile build_context + local containerfile build_context image_name image_tags + declare -a label_params image_tag_params build_arg_params - containerfile="${CICD_TOOLS_IMAGE_BUILDER_CONTAINER_FILE}" - build_context="${CICD_TOOLS_IMAGE_BUILDER_BUILD_CONTEXT}" + containerfile="$(cicd_tools::image_builder::get_containerfile)" + build_context="$(cicd_tools::image_builder::get_build_context)" - for label in "${CICD_TOOLS_IMAGE_BUILDER_LABELS[@]}"; do - label_params+=('--label' "${label}") - done + if ! image_name="$(cicd_tools::image_builder::_get_image_name)"; then + cicd_tools::err "Could not get Image name to build" + return 1 + fi - for image_tag in "${CICD_TOOLS_IMAGE_BUILDER_IMAGE_TAGS[@]}"; do - image_tag_params+=('-t' "${image_tag}") + if ! image_tag=$(cicd_tools::image_builder::get_image_tag); then + cicd_tools::err "Could not get Image tag to build!" + return 1 + fi + + if ! [ -r "$containerfile" ]; then + cicd_tools::err "Containerfile '$containerfile' does not exist or is not readable!" + return 1 + fi + + image_tag_params=('-t' "${image_name}:${image_tag}") + + if ! cicd_tools::image_builder::is_change_request_context; then + for additional_tag in $(cicd_tools::image_builder::get_additional_tags); do + image_tag_params+=('-t' "${image_name}:${additional_tag}") + done + fi + +# image_tag_params=('-t' "${image_name}:${image_tag}") + +# for additional_tag in $(cicd_tools::image_builder::get_additional_tags); do +# for tag in $(cicd_tools::image_builder::get_all_tags); do +# image_tag_params=('-t' "${image_name}:${tag}") +# done + + for label in $(cicd_tools::image_builder::get_labels); do + label_params+=('--label' "${label}") done - for build_arg in "${CICD_TOOLS_IMAGE_BUILDER_BUILD_ARGS[@]}"; do - build_arg_params+=('--build-arg' "${build_arg}") + for build_arg in $(cicd_tools::image_builder::get_build_args); do + build_arg_params+=('--build-arg' "${build_arg}") done if ! cicd_tools::container::cmd build -f "$containerfile" "${image_tag_params[@]}" \ @@ -94,70 +104,199 @@ cicd_tools::image_builder::build() { fi } -cicd_tools::image_builder::push() { +cicd_tools::image_builder::get_additional_tags() { - for image_tag in "${CICD_TOOLS_IMAGE_BUILDER_IMAGE_TAGS[@]}"; do - if ! cicd_tools::container::cmd push "${image_tag}"; then - cicd_tools::err "Error pushing image: '$image_tag'" - return 1 - fi - done + declare -a additional_tags=("${CICD_TOOLS_IMAGE_BUILDER_ADDITIONAL_TAGS[@]:-${ADDITIONAL_TAGS[@]}}") + + if cicd_tools::image_builder::_array_empty "${additional_tags[@]}"; then + additional_tags=() + fi + + echo -n "${additional_tags[@]}" } -cicd_tools::image_builder::_get_expiry_label() { - echo "quay.expires-after=${CICD_TOOLS_IMAGE_BUILDER_QUAY_EXPIRE_TIME}" +cicd_tools::image_builder::get_build_args() { + + declare -a build_args=("${CICD_TOOLS_IMAGE_BUILDER_BUILD_ARGS[@]:-${BUILD_ARGS[@]}}") + + if cicd_tools::image_builder::_array_empty "${build_args[@]}"; then + build_args=() + fi + + echo -n "${build_args[@]}" } -cicd_tools::image_builder::_array_empty() { - local arr=("$1") +cicd_tools::image_builder::get_containerfile() { - [[ "${#arr[@]}" -eq 1 && -z "${arr[0]}" ]] + local containerfile="${CICD_TOOLS_IMAGE_BUILDER_CONTAINER_FILE:-"$CONTAINER_FILE"}" + + if [ -z "$containerfile" ]; then + containerfile='Dockerfile' + fi + + echo -n "$containerfile" } -cicd_tools::image_builder::_sanitize_arrays() { +cicd_tools::image_builder::get_build_context() { - if cicd_tools::image_builder::_array_empty "${CICD_TOOLS_IMAGE_BUILDER_ADDITIONAL_TAGS[@]}";then - CICD_TOOLS_IMAGE_BUILDER_ADDITIONAL_TAGS=() - fi - if cicd_tools::image_builder::_array_empty "${CICD_TOOLS_IMAGE_BUILDER_BUILD_ARGS[@]}";then - CICD_TOOLS_IMAGE_BUILDER_BUILD_ARGS=() - fi - if cicd_tools::image_builder::_array_empty "${CICD_TOOLS_IMAGE_BUILDER_LABELS[@]}";then - CICD_TOOLS_IMAGE_BUILDER_LABELS=() - fi + local build_context="${CICD_TOOLS_IMAGE_BUILDER_BUILD_CONTEXT:-"$BUILD_CONTEXT"}" + + if [ -z "$build_context" ]; then + build_context='.' + fi + + echo -n "$build_context" } -cicd_tools::image_builder::_set_image_tags() { - local main_tag commit_hash build_id - local repository="$CICD_TOOLS_IMAGE_BUILDER_REPOSITORY" +cicd_tools::image_builder::get_labels() { - # TODO: handle if not in a `git` repository, git not available, etc - commit_hash=$(cicd_tools::common::get_7_chars_commit_hash) + declare -a labels=("${CICD_TOOLS_IMAGE_BUILDER_LABELS[@]:-${LABELS[@]}}") + + if cicd_tools::image_builder::_array_empty "${labels[@]}"; then + labels=() + fi + + if cicd_tools::image_builder::is_change_request_context; then + labels+=("$(cicd_tools::image_builder::_get_expiry_label)") + fi + + echo -n "${labels[@]}" +} + +cicd_tools::image_builder::get_image_tag() { + + local commit_hash build_id tag + + if ! commit_hash=$(cicd_tools::common::get_7_chars_commit_hash); then + echo "Cannot retrieve commit hash!" + return 1 + fi if cicd_tools::image_builder::is_change_request_context; then build_id=$(cicd_tools::image_builder::get_build_id) - main_tag="pr-${build_id}-${commit_hash}" + tag="pr-${build_id}-${commit_hash}" else - main_tag="$commit_hash" + tag="${commit_hash}" fi - CICD_TOOLS_IMAGE_BUILDER_IMAGE_TAGS=("${repository}:${main_tag}") + echo -n "${tag}" +} - for additional_tag in "${CICD_TOOLS_IMAGE_BUILDER_ADDITIONAL_TAGS[@]}"; do - CICD_TOOLS_IMAGE_BUILDER_IMAGE_TAGS+=("${repository}:${additional_tag}") - done - cicd_tools::debug "Image tags: ${CICD_TOOLS_IMAGE_BUILDER_IMAGE_TAGS[*]}" - readonly CICD_TOOLS_IMAGE_BUILDER_IMAGE_TAGS +#cicd_tools::image_builder::get_() { +# +# local image_name main_tag image_names +# image_name=$(cicd_tools::image_builder::_get_image_name) +# main_tag="$(cicd_tools::image_builder::get_image_tag_from_context)" +# +# image_names=("${image_name}:${main_tag}") +# +# if ! cicd_tools::image_builder::is_change_request_context; then +# for additional_tag in $(cicd_tools::image_builder::get_additional_tags); do +# image_names+=("${image_name}:${additional_tag}") +# done +# fi +# +# echo "${image_names[@]}" +#} + +cicd_tools::image_builder::_get_image_name() { + + local image_name="${CICD_TOOLS_IMAGE_BUILDER_IMAGE_NAME:-$IMAGE_NAME}" + + if [ -z "$image_name" ]; then + cicd_tools::err "Image name not defined, please set IMAGE_NAME environment variable" + return 1 + fi + + echo -n "$image_name" +} + +#cicd_tools::image_builder::get_image_tag() { +# +# if ! commit_hash=$(cicd_tools::common::get_7_chars_commit_hash); then +# echo "Cannot retrieve commit hash!" +# return 1 +# fi +# +# if cicd_tools::image_builder::is_change_request_context; then +# build_id=$(cicd_tools::image_builder::get_build_id) +# tag="pr-${build_id}-${commit_hash}" +# else +# tag="$commit_hash" +# fi +# +# echo -n "$tag" +#} + + +#cicd_tools::image_builder::get_main_image_name() { +# +# local repository tag +# repository=$(cicd_tools::image_builder::_get_image_repository) +# tag=$(cicd_tools::image_builder::get_image_tag_from_context) +# +# echo -n "${repository}:${tag}" +#} + +cicd_tools::image_builder::push() { + + local image_name image_tags + + if ! image_name="$(cicd_tools::image_builder::_get_image_name)"; then + cicd_tools::err "Could not get Image name to push" + return 1 + fi + + if ! image_tags=("$(cicd_tools::image_builder::get_image_tags)"); then + cicd_tools::err "Could not get Image tags to push!" + return 1 + fi + +# tags=("$image_tag") +# +# for additional_tag in $(cicd_tools::image_builder::get_additional_tags); do +# tags+=("$additional_tag") +# done + +# for tag in "${tags[@]}"; do + + for tag in "${image_tags[@]}"; do + if ! cicd_tools::container::cmd push "${image_name}:${tag}"; then + cicd_tools::err "Error pushing image: '${image_name}:${tag}'" + return 1 + fi + done } -cicd_tools::image_builder::_add_expiry_label() { +#cicd_tools::image_builder::get_all_tags() { +# +# local image_tag tags +# +# if ! image_tag="$(cicd_tools::image_builder::get_image_tag)"; then +# cicd_tools::err "Could not get Image tag to build!" +# return 1 +# fi +# +# tags=("$image_tag") +# +# for additional_tag in $(cicd_tools::image_builder::get_additional_tags); do +# tags+=("$additional_tag") +# done +# +# echo -n "${tags[@]}" +#} + + +cicd_tools::image_builder::_get_expiry_label() { + echo "quay.expires-after=${CICD_TOOLS_IMAGE_BUILDER_QUAY_EXPIRE_TIME}" +} - local expiry_label - expiry_label=$(cicd_tools::image_builder::_get_expiry_label) +cicd_tools::image_builder::_array_empty() { + local arr=("$1") - CICD_TOOLS_IMAGE_BUILDER_LABELS+=("${expiry_label}") + [[ "${#arr[@]}" -eq 1 && -z "${arr[0]}" ]] } cicd_tools::image_builder::is_change_request_context() { @@ -184,22 +323,6 @@ cicd_tools::image_builder::_image_builder_setup() { cicd_tools::err "Error trying to log into the image registries!" return 1 fi - - if [ -z "$CICD_TOOLS_IMAGE_BUILDER_REPOSITORY" ]; then - cicd_tools::err "Image repository not defined, please set IMAGE_REPOSITORY" - return 1 - fi - - cicd_tools::image_builder::_sanitize_arrays - cicd_tools::image_builder::_set_image_tags - - if cicd_tools::image_builder::is_change_request_context; then - cicd_tools::image_builder::_add_expiry_label - fi - - readonly CICD_TOOLS_IMAGE_BUILDER_LABELS - readonly CICD_TOOLS_IMAGE_BUILDER_ADDITIONAL_TAGS - readonly CICD_TOOLS_IMAGE_BUILDER_BUILD_ARGS } cicd_tools::image_builder::_try_log_in_to_image_registries() { diff --git a/test/shared_image_builder_lib.bats b/test/shared_image_builder_lib.bats index b3e1e2ec..ad8db252 100644 --- a/test/shared_image_builder_lib.bats +++ b/test/shared_image_builder_lib.bats @@ -11,13 +11,18 @@ setup() { assert_output --partial "load through main.sh" } +@test "Does not fail sourcing the library" { + + run source main.sh image_builder + assert_success +} + @test "Sets expected loaded flags" { assert [ -z "$CICD_TOOLS_COMMON_LOADED" ] assert [ -z "$CICD_TOOLS_CONTAINER_ENGINE_LOADED" ] assert [ -z "$CICD_TOOLS_IMAGE_BUILDER_LOADED" ] - IMAGE_REPOSITORY='foo' source main.sh image_builder assert [ -n "$CICD_TOOLS_COMMON_LOADED" ] @@ -25,16 +30,20 @@ setup() { assert [ -n "$CICD_TOOLS_IMAGE_BUILDER_LOADED" ] } -@test "Default image tag is set appropriately outside of a change request context" { +@test "Image tag outside of a change request context" { + + # git mock + git() { + echo "1abcdef" + } - IMAGE_REPOSITORY='foo/bar' source main.sh image_builder - run cicd_tools::image_builder::get_default_image_tag + run cicd_tools::image_builder::get_image_tag assert_success - assert_output --regexp '^foo/bar:[0-9a-f]{7}$' + assert_output '1abcdef' } -@test "Default image tag is set appropriately in a Pull Request context" { +@test "Image tags in a Pull Request context" { # git mock git() { @@ -42,14 +51,15 @@ setup() { } ghprbPullId=123 - IMAGE_REPOSITORY='pull/request' source main.sh image_builder - run cicd_tools::image_builder::get_default_image_tag + + run cicd_tools::image_builder::get_image_tag + assert_success - assert_output --regexp '^pull/request:pr-[0-9]+-[0-9a-f]{7}$' + assert_output 'pr-123-1abcdef' } -@test "Default image tag is set appropriately in a Merge Request context" { +@test "Image tags in a Merge Request context" { # git mock git() { @@ -57,20 +67,16 @@ setup() { } gitlabMergeRequestId=4321 - IMAGE_REPOSITORY='merge/request' + source main.sh image_builder - run cicd_tools::image_builder::get_default_image_tag - assert_success - assert_output --regexp '^merge/request:pr-[0-9]+-[0-9a-f]{7}$' -} -@test "fails if no image repository is defined" { + run cicd_tools::image_builder::get_image_tag - run ! source main.sh image_builder - assert_failure - assert_output --partial "Image repository not defined, please set IMAGE_REPOSITORY" + assert_success + assert_output 'pr-4321-1abcdef' } + @test "Image build works as expected with default values" { # podman mock @@ -83,13 +89,21 @@ setup() { echo "1abcdef" } - IMAGE_REPOSITORY='foo' + EXPECTED_CONTAINERFILE_NAME='Dockerfile' + source main.sh image_builder + + IMAGE_NAME='quay.io/foo/bar' + touch "${EXPECTED_CONTAINERFILE_NAME}" + run cicd_tools::image_builder::build + + rm "${EXPECTED_CONTAINERFILE_NAME}" + assert_success assert_output --regexp "^build" assert_output --partial "-f Dockerfile" - assert_output --partial "-t foo:1abcdef" + assert_output --partial "-t quay.io/foo/bar:1abcdef" assert_output --regexp "\.$" } @@ -105,15 +119,17 @@ setup() { echo "1abcdef" } - IMAGE_REPOSITORY='quay.io/my-awesome-org/my-awesome-app' + source main.sh image_builder + + IMAGE_NAME='quay.io/my-awesome-org/my-awesome-app' CICD_TOOLS_IMAGE_BUILDER_LABELS=("LABEL1=FOO" "LABEL2=bar") CICD_TOOLS_IMAGE_BUILDER_ADDITIONAL_TAGS=("test1" "additional-label-2" "security") CICD_TOOLS_IMAGE_BUILDER_BUILD_ARGS=("BUILD_ARG1=foobar" "BUILD_ARG2=bananas") CICD_TOOLS_IMAGE_BUILDER_BUILD_CONTEXT='another/context' CICD_TOOLS_IMAGE_BUILDER_CONTAINER_FILE='test/data/Containerfile.test' - source main.sh image_builder run cicd_tools::image_builder::build + assert_success assert_output --regexp "^build.*" assert_output --regexp "another/context$" @@ -140,10 +156,14 @@ setup() { echo "1abcdef" } - ghprbPullId="123" - IMAGE_REPOSITORY="someimage" source main.sh image_builder + + ghprbPullId="123" + IMAGE_NAME="someimage" + CONTAINER_FILE='test/data/Containerfile.test' + run cicd_tools::image_builder::build + assert_success assert_output --partial "-t someimage:pr-123-1abcdef" assert_output --partial "--label quay.expires-after=3d" @@ -162,9 +182,13 @@ setup() { echo "1abcdef" } - IMAGE_REPOSITORY="someimage" source main.sh image_builder + + IMAGE_NAME="someimage" + CONTAINER_FILE='test/data/Containerfile.test' + run cicd_tools::image_builder::build + assert_failure assert_output --partial "went really wrong" assert_output --partial "Error building image" @@ -180,9 +204,9 @@ setup() { CICD_TOOLS_IMAGE_BUILDER_QUAY_USER="username1" CICD_TOOLS_IMAGE_BUILDER_QUAY_PASSWORD="secr3t" - IMAGE_REPOSITORY="someimage" run source main.sh image_builder + assert_success assert_output --regexp "^login.*quay.io" assert_output --partial "-u=username1" @@ -205,14 +229,12 @@ setup() { CICD_TOOLS_IMAGE_BUILDER_QUAY_USER="wrong-user" CICD_TOOLS_IMAGE_BUILDER_QUAY_PASSWORD="secr3t" - IMAGE_REPOSITORY="someimage" run ! source main.sh image_builder + assert_failure assert_output --partial "Image builder setup failed!" assert_output --partial "Error logging in to Quay.io" - - } @test "Image builder logs failure on logging in to Red Hat Registry" { @@ -224,44 +246,35 @@ setup() { CICD_TOOLS_IMAGE_BUILDER_REDHAT_USER="wrong-user" CICD_TOOLS_IMAGE_BUILDER_REDHAT_PASSWORD="wrong-password" - IMAGE_REPOSITORY="someimage" run ! source main.sh image_builder + assert_failure assert_output --partial "Image builder setup failed!" assert_output --partial "Error logging in to Red Hat Registry" } -@test "Get default image tag" { +@test "Get all image tags" { # git mock git() { echo "1abcdef" } - IMAGE_REPOSITORY="someimage" source main.sh image_builder - run cicd_tools::image_builder::get_default_image_tag - assert_success - assert_output "someimage:1abcdef" -} - -@test "Get all image tags" { - # git mock - git() { - echo "1abcdef" - } - IMAGE_REPOSITORY="someimage" + IMAGE_NAME="someimage" ADDITIONAL_TAGS=("foo" "bar" "baz") - source main.sh image_builder - run cicd_tools::image_builder::get_image_tags + run cicd_tools::image_builder::get_image_tag + assert_success - assert_output --partial "someimage:1abcdef" - assert_output --partial "someimage:foo" - assert_output --partial "someimage:bar" + assert_output "1abcdef" + + + run cicd_tools::image_builder::get_additional_tags + assert_output "foo bar baz" } @test "tag all images" { @@ -274,11 +287,14 @@ setup() { podman() { echo "$@" } - IMAGE_REPOSITORY="someimage" - ADDITIONAL_TAGS=("target1" "target2" "target3") source main.sh image_builder + + IMAGE_NAME="someimage" + ADDITIONAL_TAGS=("target1" "target2" "target3") + run cicd_tools::image_builder::tag + refute_output --partial "tag someimage:source someimage:source" assert_output --partial "tag someimage:source someimage:target1" assert_output --partial "tag someimage:source someimage:target2" @@ -296,11 +312,14 @@ setup() { echo "$@" return 1 } - IMAGE_REPOSITORY="someimage" - ADDITIONAL_TAGS=("target1") source main.sh image_builder + + IMAGE_NAME="someimage" + ADDITIONAL_TAGS=("target1") + run ! cicd_tools::image_builder::tag + assert_failure assert_output --partial "tag someimage:source someimage:target1" assert_output --partial "Error tagging image" @@ -316,16 +335,43 @@ setup() { podman() { echo "$@" } - IMAGE_REPOSITORY="someimage" - ADDITIONAL_TAGS=("tag1" "tag2") source main.sh image_builder + + IMAGE_NAME="someimage" + ADDITIONAL_TAGS=("tag1" "tag2") + run cicd_tools::image_builder::push + assert_output --partial "push someimage:abcdef1" assert_output --partial "push someimage:tag1" assert_output --partial "push someimage:tag2" } +@test "push only one image on change-request-context" { + + # git mock + git() { + echo "abcdef1" + } + # podman mock + podman() { + echo "$@" + } + + source main.sh image_builder + + IMAGE_NAME="someimage" + ghprbPullId="123" + ADDITIONAL_TAGS=("tag1" "tag2") + + run cicd_tools::image_builder::push + + assert_output --partial "push someimage:pr-123-abcdef1" + refute_output --partial "push someimage:tag1" + refute_output --partial "push someimage:tag2" +} + @test "push error is caught" { # git mock @@ -337,11 +383,14 @@ setup() { echo "$@" return 1 } - IMAGE_REPOSITORY="someimage" - ADDITIONAL_TAGS=("target1") source main.sh image_builder + + IMAGE_NAME="someimage" + ADDITIONAL_TAGS=("target1") + run ! cicd_tools::image_builder::push + assert_failure assert_output --partial "push someimage:source" assert_output --partial "Error pushing image" @@ -357,17 +406,18 @@ setup() { podman() { echo "$@" } - IMAGE_REPOSITORY="someimage" - ADDITIONAL_TAGS=("target1") source main.sh image_builder + + IMAGE_NAME="someimage" + ADDITIONAL_TAGS=("target1") run cicd_tools::image_builder::build_deploy assert_success assert_output --regexp "^build.*?-t someimage:source -t someimage:target1" refute_output --partial "push" } -@test "build deploy pushes if on change request context" { +@test "build deploy pushes only default tag if on change request context" { # git mock git() { @@ -377,16 +427,18 @@ setup() { podman() { echo "$@" } - IMAGE_REPOSITORY="someimage" - ADDITIONAL_TAGS=("target1") - ghprbPullId='123' source main.sh image_builder + ghprbPullId='123' + IMAGE_NAME="someimage" + ADDITIONAL_TAGS=("target1") + run cicd_tools::image_builder::build_deploy - assert_success - assert_output --regexp "^build.*?-t someimage:pr-123-source -t someimage:target1" + assert_success + assert_output --regexp "^build.*?-t someimage:pr-123-source" + refute_output --regexp "^build.*?-t someimage:target1" assert_output --regexp "^build.*?--label quay.expires-after" assert_output --partial "push someimage:pr-123-source" - assert_output --partial "push someimage:target1" + refute_output --partial "push someimage:target1" } From d767571a850b68d39e8e2d463e3acbd3b0aaf167 Mon Sep 17 00:00:00 2001 From: Victor M Date: Wed, 20 Sep 2023 11:42:11 +0200 Subject: [PATCH 22/39] tests fixed --- src/shared/image_builder_lib.sh | 14 +++++++++++--- test/shared_image_builder_lib.bats | 4 +++- 2 files changed, 14 insertions(+), 4 deletions(-) diff --git a/src/shared/image_builder_lib.sh b/src/shared/image_builder_lib.sh index 78dd7272..3ae78b68 100644 --- a/src/shared/image_builder_lib.sh +++ b/src/shared/image_builder_lib.sh @@ -242,18 +242,26 @@ cicd_tools::image_builder::_get_image_name() { cicd_tools::image_builder::push() { - local image_name image_tags + local image_name image_tag if ! image_name="$(cicd_tools::image_builder::_get_image_name)"; then cicd_tools::err "Could not get Image name to push" return 1 fi - if ! image_tags=("$(cicd_tools::image_builder::get_image_tags)"); then - cicd_tools::err "Could not get Image tags to push!" + if ! image_tag=$(cicd_tools::image_builder::get_image_tag); then + cicd_tools::err "Could not get Image tag to push!" return 1 fi + image_tags=("$image_tag") + + if ! $(cicd_tools::image_builder::is_change_request_context); then + for additional_tag in $(cicd_tools::image_builder::get_additional_tags); do + image_tags+=("${additional_tag}") + done + fi + # tags=("$image_tag") # # for additional_tag in $(cicd_tools::image_builder::get_additional_tags); do diff --git a/test/shared_image_builder_lib.bats b/test/shared_image_builder_lib.bats index ad8db252..e9798644 100644 --- a/test/shared_image_builder_lib.bats +++ b/test/shared_image_builder_lib.bats @@ -322,7 +322,7 @@ setup() { assert_failure assert_output --partial "tag someimage:source someimage:target1" - assert_output --partial "Error tagging image" + assert_output --regexp "Error tagging.*someimage:source.*someimage:target1" } @test "push all images" { @@ -411,6 +411,7 @@ setup() { IMAGE_NAME="someimage" ADDITIONAL_TAGS=("target1") + CONTAINER_FILE='test/data/Containerfile.test' run cicd_tools::image_builder::build_deploy assert_success assert_output --regexp "^build.*?-t someimage:source -t someimage:target1" @@ -433,6 +434,7 @@ setup() { ghprbPullId='123' IMAGE_NAME="someimage" ADDITIONAL_TAGS=("target1") + CONTAINER_FILE='test/data/Containerfile.test' run cicd_tools::image_builder::build_deploy assert_success From 9ab473de8d0369a58b0a7f2b3f7a3c13f3090837 Mon Sep 17 00:00:00 2001 From: Victor M Date: Wed, 20 Sep 2023 12:31:52 +0200 Subject: [PATCH 23/39] fix --- src/shared/image_builder_lib.sh | 2 +- test/shared_image_builder_lib.bats | 2 ++ 2 files changed, 3 insertions(+), 1 deletion(-) diff --git a/src/shared/image_builder_lib.sh b/src/shared/image_builder_lib.sh index 3ae78b68..c981132a 100644 --- a/src/shared/image_builder_lib.sh +++ b/src/shared/image_builder_lib.sh @@ -256,7 +256,7 @@ cicd_tools::image_builder::push() { image_tags=("$image_tag") - if ! $(cicd_tools::image_builder::is_change_request_context); then + if ! cicd_tools::image_builder::is_change_request_context; then for additional_tag in $(cicd_tools::image_builder::get_additional_tags); do image_tags+=("${additional_tag}") done diff --git a/test/shared_image_builder_lib.bats b/test/shared_image_builder_lib.bats index e9798644..89f0702a 100644 --- a/test/shared_image_builder_lib.bats +++ b/test/shared_image_builder_lib.bats @@ -412,7 +412,9 @@ setup() { IMAGE_NAME="someimage" ADDITIONAL_TAGS=("target1") CONTAINER_FILE='test/data/Containerfile.test' + run cicd_tools::image_builder::build_deploy + assert_success assert_output --regexp "^build.*?-t someimage:source -t someimage:target1" refute_output --partial "push" From 72b9ea360d40ca9e7a3d1c5115189ff685625c07 Mon Sep 17 00:00:00 2001 From: Victor M Date: Wed, 20 Sep 2023 16:48:46 +0200 Subject: [PATCH 24/39] small bits --- test/generate_coverage.sh | 5 +++++ test/shared_image_builder_lib.bats | 1 + 2 files changed, 6 insertions(+) diff --git a/test/generate_coverage.sh b/test/generate_coverage.sh index 61adb6c2..2f3b87bd 100755 --- a/test/generate_coverage.sh +++ b/test/generate_coverage.sh @@ -25,3 +25,8 @@ fi "$BATS_CMD" \ --filter-tags "$IGNORE_TAGS" \ "$TESTS_DIRECTORY" + + +if [ "$CI" != 'true' ]; then + echo "Report ready at: file://${COVERAGE_DIRECTORY}/bats/index.html" +fi diff --git a/test/shared_image_builder_lib.bats b/test/shared_image_builder_lib.bats index 89f0702a..16b93170 100644 --- a/test/shared_image_builder_lib.bats +++ b/test/shared_image_builder_lib.bats @@ -439,6 +439,7 @@ setup() { CONTAINER_FILE='test/data/Containerfile.test' run cicd_tools::image_builder::build_deploy + assert_success assert_output --regexp "^build.*?-t someimage:pr-123-source" refute_output --regexp "^build.*?-t someimage:target1" From 8943a34264b9f28d7bc831eecebb6d2bb1f10a7e Mon Sep 17 00:00:00 2001 From: Victor M Date: Wed, 20 Sep 2023 16:49:07 +0200 Subject: [PATCH 25/39] renamed path --- src/shared/image_builder_lib.sh | 35 +++++++++++++++++------------- test/shared_image_builder_lib.bats | 23 +++++++++++--------- 2 files changed, 33 insertions(+), 25 deletions(-) diff --git a/src/shared/image_builder_lib.sh b/src/shared/image_builder_lib.sh index c981132a..8c713945 100644 --- a/src/shared/image_builder_lib.sh +++ b/src/shared/image_builder_lib.sh @@ -20,6 +20,8 @@ readonly CICD_TOOLS_IMAGE_BUILDER_QUAY_USER="${CICD_TOOLS_IMAGE_BUILDER_QUAY_USE readonly CICD_TOOLS_IMAGE_BUILDER_QUAY_PASSWORD="${CICD_TOOLS_IMAGE_BUILDER_QUAY_PASSWORD:-$QUAY_TOKEN}" readonly CICD_TOOLS_IMAGE_BUILDER_REDHAT_USER="${CICD_TOOLS_IMAGE_BUILDER_REDHAT_USER:-$RH_REGISTRY_USER}" readonly CICD_TOOLS_IMAGE_BUILDER_REDHAT_PASSWORD="${CICD_TOOLS_IMAGE_BUILDER_REDHAT_PASSWORD:-$RH_REGISTRY_TOKEN}" +readonly CICD_TOOLS_IMAGE_BUILDER_DEFAULT_BUILD_CONTEXT='.' +readonly CICD_TOOLS_IMAGE_BUILDER_DEFAULT_CONTAINERFILE_PATH='Dockerfile' cicd_tools::image_builder::build_deploy() { @@ -32,11 +34,12 @@ cicd_tools::image_builder::build_deploy() { cicd_tools::image_builder::tag() { local source_tag target_tag image_name + image_name="$(cicd_tools::image_builder::_get_image_name)" || return 1 - if ! image_name="$(cicd_tools::image_builder::_get_image_name)"; then - cicd_tools::err "Error getting Image name to tag" - return 1 - fi +# if ! image_name="$(cicd_tools::image_builder::_get_image_name)"; then +# cicd_tools::err "Error getting Image name to tag" +# return 1 +# fi source_tag="$(cicd_tools::image_builder::get_image_tag)" @@ -58,16 +61,18 @@ cicd_tools::image_builder::build() { containerfile="$(cicd_tools::image_builder::get_containerfile)" build_context="$(cicd_tools::image_builder::get_build_context)" + image_name="$(cicd_tools::image_builder::_get_image_name)" || return 1 + image_tag=$(cicd_tools::image_builder::get_image_tag) || return 1 - if ! image_name="$(cicd_tools::image_builder::_get_image_name)"; then - cicd_tools::err "Could not get Image name to build" - return 1 - fi - - if ! image_tag=$(cicd_tools::image_builder::get_image_tag); then - cicd_tools::err "Could not get Image tag to build!" - return 1 - fi +# if ! image_name="$(cicd_tools::image_builder::_get_image_name)"; then +# cicd_tools::err "Could not get Image name to build" +# return 1 +# fi +# +# if ! image_tag=$(cicd_tools::image_builder::get_image_tag); then +# cicd_tools::err "Could not get Image tag to build!" +# return 1 +# fi if ! [ -r "$containerfile" ]; then cicd_tools::err "Containerfile '$containerfile' does not exist or is not readable!" @@ -128,10 +133,10 @@ cicd_tools::image_builder::get_build_args() { cicd_tools::image_builder::get_containerfile() { - local containerfile="${CICD_TOOLS_IMAGE_BUILDER_CONTAINER_FILE:-"$CONTAINER_FILE"}" + local containerfile="${CICD_TOOLS_IMAGE_BUILDER_CONTAINERFILE_PATH:-"$CONTAINERFILE_PATH"}" if [ -z "$containerfile" ]; then - containerfile='Dockerfile' + containerfile=$CICD_TOOLS_IMAGE_BUILDER_DEFAULT_CONTAINERFILE_PATH fi echo -n "$containerfile" diff --git a/test/shared_image_builder_lib.bats b/test/shared_image_builder_lib.bats index 16b93170..249ecfa5 100644 --- a/test/shared_image_builder_lib.bats +++ b/test/shared_image_builder_lib.bats @@ -89,16 +89,14 @@ setup() { echo "1abcdef" } - EXPECTED_CONTAINERFILE_NAME='Dockerfile' - source main.sh image_builder + EXPECTED_CONTAINERFILE_PATH='Dockerfile' IMAGE_NAME='quay.io/foo/bar' - touch "${EXPECTED_CONTAINERFILE_NAME}" + touch "${EXPECTED_CONTAINERFILE_PATH}" run cicd_tools::image_builder::build - - rm "${EXPECTED_CONTAINERFILE_NAME}" + rm "${EXPECTED_CONTAINERFILE_PATH}" assert_success assert_output --regexp "^build" @@ -126,7 +124,7 @@ setup() { CICD_TOOLS_IMAGE_BUILDER_ADDITIONAL_TAGS=("test1" "additional-label-2" "security") CICD_TOOLS_IMAGE_BUILDER_BUILD_ARGS=("BUILD_ARG1=foobar" "BUILD_ARG2=bananas") CICD_TOOLS_IMAGE_BUILDER_BUILD_CONTEXT='another/context' - CICD_TOOLS_IMAGE_BUILDER_CONTAINER_FILE='test/data/Containerfile.test' + CICD_TOOLS_IMAGE_BUILDER_CONTAINERFILE_PATH='test/data/Containerfile.test' run cicd_tools::image_builder::build @@ -160,7 +158,7 @@ setup() { ghprbPullId="123" IMAGE_NAME="someimage" - CONTAINER_FILE='test/data/Containerfile.test' + CONTAINERFILE_PATH='test/data/Containerfile.test' run cicd_tools::image_builder::build @@ -185,7 +183,7 @@ setup() { source main.sh image_builder IMAGE_NAME="someimage" - CONTAINER_FILE='test/data/Containerfile.test' + CONTAINERFILE_PATH='test/data/Containerfile.test' run cicd_tools::image_builder::build @@ -274,6 +272,8 @@ setup() { run cicd_tools::image_builder::get_additional_tags + + assert_success assert_output "foo bar baz" } @@ -294,6 +294,7 @@ setup() { ADDITIONAL_TAGS=("target1" "target2" "target3") run cicd_tools::image_builder::tag + assert_success refute_output --partial "tag someimage:source someimage:source" assert_output --partial "tag someimage:source someimage:target1" @@ -343,6 +344,7 @@ setup() { run cicd_tools::image_builder::push + assert_success assert_output --partial "push someimage:abcdef1" assert_output --partial "push someimage:tag1" assert_output --partial "push someimage:tag2" @@ -367,6 +369,7 @@ setup() { run cicd_tools::image_builder::push + assert_success assert_output --partial "push someimage:pr-123-abcdef1" refute_output --partial "push someimage:tag1" refute_output --partial "push someimage:tag2" @@ -411,7 +414,7 @@ setup() { IMAGE_NAME="someimage" ADDITIONAL_TAGS=("target1") - CONTAINER_FILE='test/data/Containerfile.test' + CONTAINERFILE_PATH='test/data/Containerfile.test' run cicd_tools::image_builder::build_deploy @@ -436,7 +439,7 @@ setup() { ghprbPullId='123' IMAGE_NAME="someimage" ADDITIONAL_TAGS=("target1") - CONTAINER_FILE='test/data/Containerfile.test' + CONTAINERFILE_PATH='test/data/Containerfile.test' run cicd_tools::image_builder::build_deploy From a385a705eab12ba80c9cd28be0ac57457d333b6d Mon Sep 17 00:00:00 2001 From: Victor M Date: Wed, 20 Sep 2023 18:42:04 +0200 Subject: [PATCH 26/39] rename to build_and_push --- src/shared/image_builder_lib.sh | 2 +- test/e2e/test_image_builder.sh | 6 +++--- test/shared_image_builder_lib.bats | 6 +++--- 3 files changed, 7 insertions(+), 7 deletions(-) diff --git a/src/shared/image_builder_lib.sh b/src/shared/image_builder_lib.sh index 8c713945..59ac80e3 100644 --- a/src/shared/image_builder_lib.sh +++ b/src/shared/image_builder_lib.sh @@ -23,7 +23,7 @@ readonly CICD_TOOLS_IMAGE_BUILDER_REDHAT_PASSWORD="${CICD_TOOLS_IMAGE_BUILDER_RE readonly CICD_TOOLS_IMAGE_BUILDER_DEFAULT_BUILD_CONTEXT='.' readonly CICD_TOOLS_IMAGE_BUILDER_DEFAULT_CONTAINERFILE_PATH='Dockerfile' -cicd_tools::image_builder::build_deploy() { +cicd_tools::image_builder::build_and_push() { cicd_tools::image_builder::build || return 1 if cicd_tools::image_builder::is_change_request_context; then diff --git a/test/e2e/test_image_builder.sh b/test/e2e/test_image_builder.sh index ad2e348e..e162204f 100755 --- a/test/e2e/test_image_builder.sh +++ b/test/e2e/test_image_builder.sh @@ -15,14 +15,14 @@ MAIN_SCRIPT='./src/main.sh' source "$MAIN_SCRIPT" "image_builder" -EXPECTED_OUTPUT=$(cicd_tools::image_builder::build_deploy) +EXPECTED_OUTPUT=$(cicd_tools::image_builder::build_and_push) if ! [ "build -f ${CICD_TOOLS_IMAGE_BUILDER_CONTAINER_FILE} -t ${IMAGE_REPOSITORY}:abcdef1 ." = "$EXPECTED_OUTPUT" ]; then - echo "image build_deploy not working!" + echo "Build and Push script not working!" exit 1 fi unset podman -cicd_tools::image_builder::build_deploy +cicd_tools::image_builder::build_and_push diff --git a/test/shared_image_builder_lib.bats b/test/shared_image_builder_lib.bats index 249ecfa5..196ec2c3 100644 --- a/test/shared_image_builder_lib.bats +++ b/test/shared_image_builder_lib.bats @@ -416,14 +416,14 @@ setup() { ADDITIONAL_TAGS=("target1") CONTAINERFILE_PATH='test/data/Containerfile.test' - run cicd_tools::image_builder::build_deploy + run cicd_tools::image_builder::build_and_push assert_success assert_output --regexp "^build.*?-t someimage:source -t someimage:target1" refute_output --partial "push" } -@test "build deploy pushes only default tag if on change request context" { +@test "build_and_push pushes only default tag if on change request context" { # git mock git() { @@ -441,7 +441,7 @@ setup() { ADDITIONAL_TAGS=("target1") CONTAINERFILE_PATH='test/data/Containerfile.test' - run cicd_tools::image_builder::build_deploy + run cicd_tools::image_builder::build_and_push assert_success assert_output --regexp "^build.*?-t someimage:pr-123-source" From 5343ffa67017f97560215838c2942b9926ebca3e Mon Sep 17 00:00:00 2001 From: Victor M Date: Wed, 20 Sep 2023 18:58:40 +0200 Subject: [PATCH 27/39] vertical order fix --- src/shared/image_builder_lib.sh | 276 ++++++++++---------------------- 1 file changed, 89 insertions(+), 187 deletions(-) diff --git a/src/shared/image_builder_lib.sh b/src/shared/image_builder_lib.sh index 59ac80e3..18ffe916 100644 --- a/src/shared/image_builder_lib.sh +++ b/src/shared/image_builder_lib.sh @@ -31,31 +31,8 @@ cicd_tools::image_builder::build_and_push() { fi } -cicd_tools::image_builder::tag() { - - local source_tag target_tag image_name - image_name="$(cicd_tools::image_builder::_get_image_name)" || return 1 - -# if ! image_name="$(cicd_tools::image_builder::_get_image_name)"; then -# cicd_tools::err "Error getting Image name to tag" -# return 1 -# fi - - source_tag="$(cicd_tools::image_builder::get_image_tag)" - - for target_tag in $(cicd_tools::image_builder::get_additional_tags); do - if ! cicd_tools::container::cmd tag "${image_name}:${source_tag}" "${image_name}:${target_tag}"; then - cicd_tools::err "Error tagging '${image_name}:${source_tag}' as '${image_name}:${target_tag}'" - return 1 - fi - done -} - cicd_tools::image_builder::build() { -# declare -a image_tag_params -# declare -a build_arg_params - local containerfile build_context image_name image_tags declare -a label_params image_tag_params build_arg_params @@ -64,16 +41,6 @@ cicd_tools::image_builder::build() { image_name="$(cicd_tools::image_builder::_get_image_name)" || return 1 image_tag=$(cicd_tools::image_builder::get_image_tag) || return 1 -# if ! image_name="$(cicd_tools::image_builder::_get_image_name)"; then -# cicd_tools::err "Could not get Image name to build" -# return 1 -# fi -# -# if ! image_tag=$(cicd_tools::image_builder::get_image_tag); then -# cicd_tools::err "Could not get Image tag to build!" -# return 1 -# fi - if ! [ -r "$containerfile" ]; then cicd_tools::err "Containerfile '$containerfile' does not exist or is not readable!" return 1 @@ -87,13 +54,6 @@ cicd_tools::image_builder::build() { done fi -# image_tag_params=('-t' "${image_name}:${image_tag}") - -# for additional_tag in $(cicd_tools::image_builder::get_additional_tags); do -# for tag in $(cicd_tools::image_builder::get_all_tags); do -# image_tag_params=('-t' "${image_name}:${tag}") -# done - for label in $(cicd_tools::image_builder::get_labels); do label_params+=('--label' "${label}") done @@ -109,28 +69,6 @@ cicd_tools::image_builder::build() { fi } -cicd_tools::image_builder::get_additional_tags() { - - declare -a additional_tags=("${CICD_TOOLS_IMAGE_BUILDER_ADDITIONAL_TAGS[@]:-${ADDITIONAL_TAGS[@]}}") - - if cicd_tools::image_builder::_array_empty "${additional_tags[@]}"; then - additional_tags=() - fi - - echo -n "${additional_tags[@]}" -} - -cicd_tools::image_builder::get_build_args() { - - declare -a build_args=("${CICD_TOOLS_IMAGE_BUILDER_BUILD_ARGS[@]:-${BUILD_ARGS[@]}}") - - if cicd_tools::image_builder::_array_empty "${build_args[@]}"; then - build_args=() - fi - - echo -n "${build_args[@]}" -} - cicd_tools::image_builder::get_containerfile() { local containerfile="${CICD_TOOLS_IMAGE_BUILDER_CONTAINERFILE_PATH:-"$CONTAINERFILE_PATH"}" @@ -147,26 +85,22 @@ cicd_tools::image_builder::get_build_context() { local build_context="${CICD_TOOLS_IMAGE_BUILDER_BUILD_CONTEXT:-"$BUILD_CONTEXT"}" if [ -z "$build_context" ]; then - build_context='.' + build_context="$CICD_TOOLS_IMAGE_BUILDER_DEFAULT_BUILD_CONTEXT" fi echo -n "$build_context" } +cicd_tools::image_builder::_get_image_name() { -cicd_tools::image_builder::get_labels() { - - declare -a labels=("${CICD_TOOLS_IMAGE_BUILDER_LABELS[@]:-${LABELS[@]}}") - - if cicd_tools::image_builder::_array_empty "${labels[@]}"; then - labels=() - fi + local image_name="${CICD_TOOLS_IMAGE_BUILDER_IMAGE_NAME:-$IMAGE_NAME}" - if cicd_tools::image_builder::is_change_request_context; then - labels+=("$(cicd_tools::image_builder::_get_expiry_label)") + if [ -z "$image_name" ]; then + cicd_tools::err "Image name not defined, please set IMAGE_NAME environment variable" + return 1 fi - echo -n "${labels[@]}" + echo -n "$image_name" } cicd_tools::image_builder::get_image_tag() { @@ -188,146 +122,114 @@ cicd_tools::image_builder::get_image_tag() { echo -n "${tag}" } +cicd_tools::image_builder::is_change_request_context() { + [ -n "$ghprbPullId" ] || [ -n "$gitlabMergeRequestId" ] +} -#cicd_tools::image_builder::get_() { -# -# local image_name main_tag image_names -# image_name=$(cicd_tools::image_builder::_get_image_name) -# main_tag="$(cicd_tools::image_builder::get_image_tag_from_context)" -# -# image_names=("${image_name}:${main_tag}") -# -# if ! cicd_tools::image_builder::is_change_request_context; then -# for additional_tag in $(cicd_tools::image_builder::get_additional_tags); do -# image_names+=("${image_name}:${additional_tag}") -# done -# fi -# -# echo "${image_names[@]}" -#} - -cicd_tools::image_builder::_get_image_name() { +cicd_tools::image_builder::get_build_id() { - local image_name="${CICD_TOOLS_IMAGE_BUILDER_IMAGE_NAME:-$IMAGE_NAME}" + local build_id - if [ -z "$image_name" ]; then - cicd_tools::err "Image name not defined, please set IMAGE_NAME environment variable" - return 1 + if [ -n "$ghprbPullId" ]; then + build_id="$ghprbPullId" + elif [ -n "$gitlabMergeRequestId" ]; then + build_id="$gitlabMergeRequestId" fi - echo -n "$image_name" + echo -n "$build_id" } -#cicd_tools::image_builder::get_image_tag() { -# -# if ! commit_hash=$(cicd_tools::common::get_7_chars_commit_hash); then -# echo "Cannot retrieve commit hash!" -# return 1 -# fi -# -# if cicd_tools::image_builder::is_change_request_context; then -# build_id=$(cicd_tools::image_builder::get_build_id) -# tag="pr-${build_id}-${commit_hash}" -# else -# tag="$commit_hash" -# fi -# -# echo -n "$tag" -#} +cicd_tools::image_builder::get_additional_tags() { + declare -a additional_tags=("${CICD_TOOLS_IMAGE_BUILDER_ADDITIONAL_TAGS[@]:-${ADDITIONAL_TAGS[@]}}") -#cicd_tools::image_builder::get_main_image_name() { -# -# local repository tag -# repository=$(cicd_tools::image_builder::_get_image_repository) -# tag=$(cicd_tools::image_builder::get_image_tag_from_context) -# -# echo -n "${repository}:${tag}" -#} + if cicd_tools::image_builder::_array_empty "${additional_tags[@]}"; then + additional_tags=() + fi -cicd_tools::image_builder::push() { + echo -n "${additional_tags[@]}" +} - local image_name image_tag +cicd_tools::image_builder::_array_empty() { + local arr=("$1") - if ! image_name="$(cicd_tools::image_builder::_get_image_name)"; then - cicd_tools::err "Could not get Image name to push" - return 1 - fi + [[ "${#arr[@]}" -eq 1 && -z "${arr[0]}" ]] +} - if ! image_tag=$(cicd_tools::image_builder::get_image_tag); then - cicd_tools::err "Could not get Image tag to push!" - return 1 - fi +cicd_tools::image_builder::get_labels() { - image_tags=("$image_tag") + declare -a labels=("${CICD_TOOLS_IMAGE_BUILDER_LABELS[@]:-${LABELS[@]}}") - if ! cicd_tools::image_builder::is_change_request_context; then - for additional_tag in $(cicd_tools::image_builder::get_additional_tags); do - image_tags+=("${additional_tag}") - done + if cicd_tools::image_builder::_array_empty "${labels[@]}"; then + labels=() fi -# tags=("$image_tag") -# -# for additional_tag in $(cicd_tools::image_builder::get_additional_tags); do -# tags+=("$additional_tag") -# done - -# for tag in "${tags[@]}"; do + if cicd_tools::image_builder::is_change_request_context; then + labels+=("$(cicd_tools::image_builder::_get_expiry_label)") + fi - for tag in "${image_tags[@]}"; do - if ! cicd_tools::container::cmd push "${image_name}:${tag}"; then - cicd_tools::err "Error pushing image: '${image_name}:${tag}'" - return 1 - fi - done + echo -n "${labels[@]}" } -#cicd_tools::image_builder::get_all_tags() { -# -# local image_tag tags -# -# if ! image_tag="$(cicd_tools::image_builder::get_image_tag)"; then -# cicd_tools::err "Could not get Image tag to build!" -# return 1 -# fi -# -# tags=("$image_tag") -# -# for additional_tag in $(cicd_tools::image_builder::get_additional_tags); do -# tags+=("$additional_tag") -# done -# -# echo -n "${tags[@]}" -#} - - cicd_tools::image_builder::_get_expiry_label() { echo "quay.expires-after=${CICD_TOOLS_IMAGE_BUILDER_QUAY_EXPIRE_TIME}" } -cicd_tools::image_builder::_array_empty() { - local arr=("$1") +cicd_tools::image_builder::get_build_args() { - [[ "${#arr[@]}" -eq 1 && -z "${arr[0]}" ]] + declare -a build_args=("${CICD_TOOLS_IMAGE_BUILDER_BUILD_ARGS[@]:-${BUILD_ARGS[@]}}") + + if cicd_tools::image_builder::_array_empty "${build_args[@]}"; then + build_args=() + fi + + echo -n "${build_args[@]}" } -cicd_tools::image_builder::is_change_request_context() { - [ -n "$ghprbPullId" ] || [ -n "$gitlabMergeRequestId" ] +cicd_tools::image_builder::tag() { + + local source_tag target_tag image_name + image_name="$(cicd_tools::image_builder::_get_image_name)" || return 1 + source_tag="$(cicd_tools::image_builder::get_image_tag)" || return 1 + + for target_tag in $(cicd_tools::image_builder::get_additional_tags); do + if ! cicd_tools::container::cmd tag "${image_name}:${source_tag}" "${image_name}:${target_tag}"; then + cicd_tools::err "Error tagging '${image_name}:${source_tag}' as '${image_name}:${target_tag}'" + return 1 + fi + done } -# TODO: decide on should this be private? -cicd_tools::image_builder::get_build_id() { +cicd_tools::image_builder::push() { - local build_id + local image_name image_tag + image_name="$(cicd_tools::image_builder::_get_image_name)" || return 1 + image_tag=$(cicd_tools::image_builder::get_image_tag) || return 1 - if [ -n "$ghprbPullId" ]; then - build_id="$ghprbPullId" - elif [ -n "$gitlabMergeRequestId" ]; then - build_id="$gitlabMergeRequestId" +# if ! image_name="$(cicd_tools::image_builder::_get_image_name)"; then +# cicd_tools::err "Could not get Image name to push" +# return 1 +# fi +# +# if ! image_tag=$(cicd_tools::image_builder::get_image_tag); then +# cicd_tools::err "Could not get Image tag to push!" +# return 1 +# fi + + image_tags=("$image_tag") + + if ! cicd_tools::image_builder::is_change_request_context; then + for additional_tag in $(cicd_tools::image_builder::get_additional_tags); do + image_tags+=("${additional_tag}") + done fi - echo -n "$build_id" + for tag in "${image_tags[@]}"; do + if ! cicd_tools::container::cmd push "${image_name}:${tag}"; then + cicd_tools::err "Error pushing image: '${image_name}:${tag}'" + return 1 + fi + done } cicd_tools::image_builder::_image_builder_setup() { @@ -360,9 +262,10 @@ cicd_tools::image_builder::_quay_credentials_found() { [ -n "$CICD_TOOLS_IMAGE_BUILDER_QUAY_PASSWORD" ] } -cicd_tools::image_builder::_redhat_registry_credentials_found() { - [ -n "$CICD_TOOLS_IMAGE_BUILDER_REDHAT_USER" ] && \ - [ -n "$CICD_TOOLS_IMAGE_BUILDER_REDHAT_PASSWORD" ] +cicd_tools::image_builder::_log_in_to_quay_registry() { + cicd_tools::image_builder::_log_in_to_container_registry "$CICD_TOOLS_IMAGE_BUILDER_QUAY_USER" \ + "$CICD_TOOLS_IMAGE_BUILDER_QUAY_PASSWORD" \ + "$CICD_TOOLS_IMAGE_BUILDER_QUAY_REGISTRY" } cicd_tools::image_builder::_log_in_to_container_registry() { @@ -374,10 +277,9 @@ cicd_tools::image_builder::_log_in_to_container_registry() { cicd_tools::container::cmd login "-u=${username}" "--password-stdin" "$registry" <<< "$password" } -cicd_tools::image_builder::_log_in_to_quay_registry() { - cicd_tools::image_builder::_log_in_to_container_registry "$CICD_TOOLS_IMAGE_BUILDER_QUAY_USER" \ - "$CICD_TOOLS_IMAGE_BUILDER_QUAY_PASSWORD" \ - "$CICD_TOOLS_IMAGE_BUILDER_QUAY_REGISTRY" +cicd_tools::image_builder::_redhat_registry_credentials_found() { + [ -n "$CICD_TOOLS_IMAGE_BUILDER_REDHAT_USER" ] && \ + [ -n "$CICD_TOOLS_IMAGE_BUILDER_REDHAT_PASSWORD" ] } cicd_tools::image_builder::_log_in_to_redhat_registry() { From 38f9c95ee670e4aa983e6d3a8ede681308971ed9 Mon Sep 17 00:00:00 2001 From: Victor M Date: Thu, 21 Sep 2023 20:15:05 +0200 Subject: [PATCH 28/39] Add is_ci_context feature --- src/shared/common_lib.sh | 20 ++++++++++++-------- test/shared_common_lib.bats | 17 +++++++++++++++++ test/shared_container_lib.bats | 4 ++++ 3 files changed, 33 insertions(+), 8 deletions(-) diff --git a/src/shared/common_lib.sh b/src/shared/common_lib.sh index 3804e8ec..369828e9 100644 --- a/src/shared/common_lib.sh +++ b/src/shared/common_lib.sh @@ -6,31 +6,35 @@ CICD_TOOLS_COMMON_LOADED=${CICD_TOOLS_COMMON_LOADED:-1} LOCAL_BUILD=${LOCAL_BUILD:-false} if [ "$CICD_TOOLS_COMMON_LOADED" -eq 0 ]; then - cicd_tools::debug "common library already loaded, skipping" - return 0 + cicd_tools::debug "common library already loaded, skipping" + return 0 fi if [ -z "$CICD_TOOLS_SCRIPTS_DIR" ]; then - echo "scripts directory not defined, please load through main.sh script" >&2 - return 1 + echo "scripts directory not defined, please load through main.sh script" >&2 + return 1 fi cicd_tools::debug "loading common lib" cicd_tools::common::command_is_present() { - command -v "$1" > /dev/null 2>&1 + command -v "$1" > /dev/null 2>&1 } cicd_tools::common::_get_n_chars_commit_hash() { - git rev-parse --short="$1" HEAD + git rev-parse --short="$1" HEAD } cicd_tools::common::get_7_chars_commit_hash() { - cicd_tools::common::_get_n_chars_commit_hash 7 + cicd_tools::common::_get_n_chars_commit_hash 7 +} + +cicd_tools::common::is_ci_context() { + [[ "$CI" = "true" ]] } cicd_tools::common::local_build() { - [[ "$LOCAL_BUILD" = true || "$CI" != "true" ]] + [[ "$LOCAL_BUILD" = true ]] || ! cicd_tools::common::is_ci_context } cicd_tools::debug "common lib loaded" diff --git a/test/shared_common_lib.bats b/test/shared_common_lib.bats index 58f84b63..92ba517d 100644 --- a/test/shared_common_lib.bats +++ b/test/shared_common_lib.bats @@ -74,3 +74,20 @@ setup() { assert_output "" assert_failure } + +@test "is_ci_context" { + + source src/main.sh common + + unset CI + assert [ -z "$CI" ] + + run cicd_tools::common::is_ci_context + assert_failure + assert_output "" + + export CI='true' + run cicd_tools::common::is_ci_context + assert_success + assert_output "" +} diff --git a/test/shared_container_lib.bats b/test/shared_container_lib.bats index d3983da2..a84410d9 100644 --- a/test/shared_container_lib.bats +++ b/test/shared_container_lib.bats @@ -140,6 +140,7 @@ setup() { OLDPATH="$PATH" PATH=':' + run cicd_tools::container::cmd --version PATH="$OLDPATH" assert_output --regexp "WARNING.*podman.*not present" @@ -153,6 +154,9 @@ setup() { docker() { echo 'podman version 1' } + date() { + echo -n "Thu Sep 21 06:25:51 PM CEST 2023" + } source main.sh container OLDPATH="$PATH" From 8f942fb51def105019ee806e2abf0ce4db1ab975 Mon Sep 17 00:00:00 2001 From: Victor M Date: Thu, 21 Sep 2023 20:15:27 +0200 Subject: [PATCH 29/39] Add get_full_image_name feature --- src/shared/image_builder_lib.sh | 149 ++++++++++++++++---------------- 1 file changed, 75 insertions(+), 74 deletions(-) diff --git a/src/shared/image_builder_lib.sh b/src/shared/image_builder_lib.sh index 18ffe916..b6eb6e35 100644 --- a/src/shared/image_builder_lib.sh +++ b/src/shared/image_builder_lib.sh @@ -3,12 +3,12 @@ CICD_TOOLS_IMAGE_BUILDER_LOADED=${CICD_TOOLS_IMAGE_BUILDER_LOADED:-1} if [[ "$CICD_TOOLS_IMAGE_BUILDER_LOADED" -eq 0 ]]; then - return 0 + return 0 fi if [ -z "$CICD_TOOLS_SCRIPTS_DIR" ]; then - echo "scripts directory not defined, please load through main.sh script" >&2 - return 1 + echo "scripts directory not defined, please load through main.sh script" >&2 + return 1 fi cicd_tools::debug "loading image builder library" @@ -24,48 +24,47 @@ readonly CICD_TOOLS_IMAGE_BUILDER_DEFAULT_BUILD_CONTEXT='.' readonly CICD_TOOLS_IMAGE_BUILDER_DEFAULT_CONTAINERFILE_PATH='Dockerfile' cicd_tools::image_builder::build_and_push() { - cicd_tools::image_builder::build || return 1 if cicd_tools::image_builder::is_change_request_context; then - cicd_tools::image_builder::push || return 1 + cicd_tools::image_builder::push || return 1 fi } cicd_tools::image_builder::build() { - local containerfile build_context image_name image_tags + local containerfile build_context image_name image_tags default_image_name declare -a label_params image_tag_params build_arg_params containerfile="$(cicd_tools::image_builder::get_containerfile)" build_context="$(cicd_tools::image_builder::get_build_context)" image_name="$(cicd_tools::image_builder::_get_image_name)" || return 1 - image_tag=$(cicd_tools::image_builder::get_image_tag) || return 1 + default_image_name=$(cicd_tools::image_builder::get_full_image_name) || return 1 if ! [ -r "$containerfile" ]; then - cicd_tools::err "Containerfile '$containerfile' does not exist or is not readable!" - return 1 + cicd_tools::err "Containerfile '$containerfile' does not exist or is not readable!" + return 1 fi - image_tag_params=('-t' "${image_name}:${image_tag}") + image_tag_params=('-t' "$default_image_name") if ! cicd_tools::image_builder::is_change_request_context; then - for additional_tag in $(cicd_tools::image_builder::get_additional_tags); do - image_tag_params+=('-t' "${image_name}:${additional_tag}") - done + for additional_tag in $(cicd_tools::image_builder::get_additional_tags); do + image_tag_params+=('-t' "${image_name}:${additional_tag}") + done fi for label in $(cicd_tools::image_builder::get_labels); do - label_params+=('--label' "${label}") + label_params+=('--label' "${label}") done for build_arg in $(cicd_tools::image_builder::get_build_args); do - build_arg_params+=('--build-arg' "${build_arg}") + build_arg_params+=('--build-arg' "${build_arg}") done if ! cicd_tools::container::cmd build -f "$containerfile" "${image_tag_params[@]}" \ - "${build_arg_params[@]}" "${label_params[@]}" "$build_context"; then - cicd_tools::err "Error building image" - return 1 + "${build_arg_params[@]}" "${label_params[@]}" "$build_context"; then + cicd_tools::err "Error building image" + return 1 fi } @@ -74,7 +73,7 @@ cicd_tools::image_builder::get_containerfile() { local containerfile="${CICD_TOOLS_IMAGE_BUILDER_CONTAINERFILE_PATH:-"$CONTAINERFILE_PATH"}" if [ -z "$containerfile" ]; then - containerfile=$CICD_TOOLS_IMAGE_BUILDER_DEFAULT_CONTAINERFILE_PATH + containerfile=$CICD_TOOLS_IMAGE_BUILDER_DEFAULT_CONTAINERFILE_PATH fi echo -n "$containerfile" @@ -85,19 +84,21 @@ cicd_tools::image_builder::get_build_context() { local build_context="${CICD_TOOLS_IMAGE_BUILDER_BUILD_CONTEXT:-"$BUILD_CONTEXT"}" if [ -z "$build_context" ]; then - build_context="$CICD_TOOLS_IMAGE_BUILDER_DEFAULT_BUILD_CONTEXT" + build_context="$CICD_TOOLS_IMAGE_BUILDER_DEFAULT_BUILD_CONTEXT" fi echo -n "$build_context" } + + cicd_tools::image_builder::_get_image_name() { local image_name="${CICD_TOOLS_IMAGE_BUILDER_IMAGE_NAME:-$IMAGE_NAME}" if [ -z "$image_name" ]; then - cicd_tools::err "Image name not defined, please set IMAGE_NAME environment variable" - return 1 + cicd_tools::err "Image name not defined, please set IMAGE_NAME environment variable" + return 1 fi echo -n "$image_name" @@ -108,15 +109,15 @@ cicd_tools::image_builder::get_image_tag() { local commit_hash build_id tag if ! commit_hash=$(cicd_tools::common::get_7_chars_commit_hash); then - echo "Cannot retrieve commit hash!" - return 1 + echo "Cannot retrieve commit hash!" + return 1 fi if cicd_tools::image_builder::is_change_request_context; then - build_id=$(cicd_tools::image_builder::get_build_id) - tag="pr-${build_id}-${commit_hash}" + build_id=$(cicd_tools::image_builder::get_build_id) + tag="pr-${build_id}-${commit_hash}" else - tag="${commit_hash}" + tag="${commit_hash}" fi echo -n "${tag}" @@ -131,9 +132,9 @@ cicd_tools::image_builder::get_build_id() { local build_id if [ -n "$ghprbPullId" ]; then - build_id="$ghprbPullId" + build_id="$ghprbPullId" elif [ -n "$gitlabMergeRequestId" ]; then - build_id="$gitlabMergeRequestId" + build_id="$gitlabMergeRequestId" fi echo -n "$build_id" @@ -144,16 +145,16 @@ cicd_tools::image_builder::get_additional_tags() { declare -a additional_tags=("${CICD_TOOLS_IMAGE_BUILDER_ADDITIONAL_TAGS[@]:-${ADDITIONAL_TAGS[@]}}") if cicd_tools::image_builder::_array_empty "${additional_tags[@]}"; then - additional_tags=() + additional_tags=() fi echo -n "${additional_tags[@]}" } cicd_tools::image_builder::_array_empty() { - local arr=("$1") + local arr=("$1") - [[ "${#arr[@]}" -eq 1 && -z "${arr[0]}" ]] + [[ "${#arr[@]}" -eq 1 && -z "${arr[0]}" ]] } cicd_tools::image_builder::get_labels() { @@ -161,11 +162,11 @@ cicd_tools::image_builder::get_labels() { declare -a labels=("${CICD_TOOLS_IMAGE_BUILDER_LABELS[@]:-${LABELS[@]}}") if cicd_tools::image_builder::_array_empty "${labels[@]}"; then - labels=() + labels=() fi if cicd_tools::image_builder::is_change_request_context; then - labels+=("$(cicd_tools::image_builder::_get_expiry_label)") + labels+=("$(cicd_tools::image_builder::_get_expiry_label)") fi echo -n "${labels[@]}" @@ -180,7 +181,7 @@ cicd_tools::image_builder::get_build_args() { declare -a build_args=("${CICD_TOOLS_IMAGE_BUILDER_BUILD_ARGS[@]:-${BUILD_ARGS[@]}}") if cicd_tools::image_builder::_array_empty "${build_args[@]}"; then - build_args=() + build_args=() fi echo -n "${build_args[@]}" @@ -188,15 +189,15 @@ cicd_tools::image_builder::get_build_args() { cicd_tools::image_builder::tag() { - local source_tag target_tag image_name + local source_image target_tag image_name image_name="$(cicd_tools::image_builder::_get_image_name)" || return 1 - source_tag="$(cicd_tools::image_builder::get_image_tag)" || return 1 + source_image="$(cicd_tools::image_builder::get_full_image_name)" || return 1 for target_tag in $(cicd_tools::image_builder::get_additional_tags); do - if ! cicd_tools::container::cmd tag "${image_name}:${source_tag}" "${image_name}:${target_tag}"; then - cicd_tools::err "Error tagging '${image_name}:${source_tag}' as '${image_name}:${target_tag}'" - return 1 - fi + if ! cicd_tools::container::cmd tag "$source_image" "${image_name}:${target_tag}"; then + cicd_tools::err "Error tagging '$source_image' as '${image_name}:${target_tag}'" + return 1 + fi done } @@ -206,66 +207,66 @@ cicd_tools::image_builder::push() { image_name="$(cicd_tools::image_builder::_get_image_name)" || return 1 image_tag=$(cicd_tools::image_builder::get_image_tag) || return 1 -# if ! image_name="$(cicd_tools::image_builder::_get_image_name)"; then -# cicd_tools::err "Could not get Image name to push" -# return 1 -# fi -# -# if ! image_tag=$(cicd_tools::image_builder::get_image_tag); then -# cicd_tools::err "Could not get Image tag to push!" -# return 1 -# fi - image_tags=("$image_tag") if ! cicd_tools::image_builder::is_change_request_context; then - for additional_tag in $(cicd_tools::image_builder::get_additional_tags); do - image_tags+=("${additional_tag}") - done + for additional_tag in $(cicd_tools::image_builder::get_additional_tags); do + image_tags+=("${additional_tag}") + done fi for tag in "${image_tags[@]}"; do - if ! cicd_tools::container::cmd push "${image_name}:${tag}"; then - cicd_tools::err "Error pushing image: '${image_name}:${tag}'" - return 1 - fi + if ! cicd_tools::container::cmd push "${image_name}:${tag}"; then + cicd_tools::err "Error pushing image: '${image_name}:${tag}'" + return 1 + fi done } +cicd_tools::image_builder::get_full_image_name() { + + local image_name image_tag + image_name="$(cicd_tools::image_builder::_get_image_name)" || return 1 + image_tag=$(cicd_tools::image_builder::get_image_tag) || return 1 + + echo -n "${image_name}:${image_tag}" +} + + cicd_tools::image_builder::_image_builder_setup() { if ! cicd_tools::image_builder::_try_log_in_to_image_registries; then - cicd_tools::err "Error trying to log into the image registries!" - return 1 + cicd_tools::err "Error trying to log into the image registries!" + return 1 fi } cicd_tools::image_builder::_try_log_in_to_image_registries() { if cicd_tools::image_builder::_quay_credentials_found; then - if ! cicd_tools::image_builder::_log_in_to_quay_registry; then - cicd_tools::err "Error logging in to Quay.io!" - return 1 - fi + if ! cicd_tools::image_builder::_log_in_to_quay_registry; then + cicd_tools::err "Error logging in to Quay.io!" + return 1 + fi fi if cicd_tools::image_builder::_redhat_registry_credentials_found; then - if ! cicd_tools::image_builder::_log_in_to_redhat_registry; then - cicd_tools::err "Error logging in to Red Hat Registry!" - return 1 - fi + if ! cicd_tools::image_builder::_log_in_to_redhat_registry; then + cicd_tools::err "Error logging in to Red Hat Registry!" + return 1 + fi fi } cicd_tools::image_builder::_quay_credentials_found() { [ -n "$CICD_TOOLS_IMAGE_BUILDER_QUAY_USER" ] && \ - [ -n "$CICD_TOOLS_IMAGE_BUILDER_QUAY_PASSWORD" ] + [ -n "$CICD_TOOLS_IMAGE_BUILDER_QUAY_PASSWORD" ] } cicd_tools::image_builder::_log_in_to_quay_registry() { cicd_tools::image_builder::_log_in_to_container_registry "$CICD_TOOLS_IMAGE_BUILDER_QUAY_USER" \ - "$CICD_TOOLS_IMAGE_BUILDER_QUAY_PASSWORD" \ - "$CICD_TOOLS_IMAGE_BUILDER_QUAY_REGISTRY" + "$CICD_TOOLS_IMAGE_BUILDER_QUAY_PASSWORD" \ + "$CICD_TOOLS_IMAGE_BUILDER_QUAY_REGISTRY" } cicd_tools::image_builder::_log_in_to_container_registry() { @@ -279,13 +280,13 @@ cicd_tools::image_builder::_log_in_to_container_registry() { cicd_tools::image_builder::_redhat_registry_credentials_found() { [ -n "$CICD_TOOLS_IMAGE_BUILDER_REDHAT_USER" ] && \ - [ -n "$CICD_TOOLS_IMAGE_BUILDER_REDHAT_PASSWORD" ] + [ -n "$CICD_TOOLS_IMAGE_BUILDER_REDHAT_PASSWORD" ] } cicd_tools::image_builder::_log_in_to_redhat_registry() { cicd_tools::image_builder::_log_in_to_container_registry "$CICD_TOOLS_IMAGE_BUILDER_REDHAT_USER" \ - "$CICD_TOOLS_IMAGE_BUILDER_REDHAT_PASSWORD" \ - "$CICD_TOOLS_IMAGE_BUILDER_REDHAT_REGISTRY" + "$CICD_TOOLS_IMAGE_BUILDER_REDHAT_PASSWORD" \ + "$CICD_TOOLS_IMAGE_BUILDER_REDHAT_REGISTRY" } if ! cicd_tools::image_builder::_image_builder_setup; then From 5682f4025982715c4eab62cb38b72388302223b3 Mon Sep 17 00:00:00 2001 From: Victor M Date: Thu, 21 Sep 2023 20:47:14 +0200 Subject: [PATCH 30/39] increase coverage --- src/shared/image_builder_lib.sh | 4 +- test/shared_image_builder_lib.bats | 65 ++++++++++++++++++++++++++++++ 2 files changed, 67 insertions(+), 2 deletions(-) diff --git a/src/shared/image_builder_lib.sh b/src/shared/image_builder_lib.sh index b6eb6e35..c39f846b 100644 --- a/src/shared/image_builder_lib.sh +++ b/src/shared/image_builder_lib.sh @@ -109,8 +109,8 @@ cicd_tools::image_builder::get_image_tag() { local commit_hash build_id tag if ! commit_hash=$(cicd_tools::common::get_7_chars_commit_hash); then - echo "Cannot retrieve commit hash!" - return 1 + cicd_tools::err "Cannot retrieve commit hash!" + return 1 fi if cicd_tools::image_builder::is_change_request_context; then diff --git a/test/shared_image_builder_lib.bats b/test/shared_image_builder_lib.bats index 196ec2c3..cdfd00d3 100644 --- a/test/shared_image_builder_lib.bats +++ b/test/shared_image_builder_lib.bats @@ -77,6 +77,71 @@ setup() { } +@test "Image build fails if Dockerfile doesn't exist" { + + # podman mock + podman() { + echo "$@" + } + + # git mock + git() { + echo "1abcdef" + } + + source main.sh image_builder + + EXPECTED_CONTAINERFILE_PATH='Dockerfile' + IMAGE_NAME='quay.io/foo/bar' + + refute [ -r "$EXPECTED_CONTAINERFILE_PATH" ] + run ! cicd_tools::image_builder::build + assert_failure + assert_output --regexp "$EXPECTED_CONTAINERFILE_PATH.*does not exist" + refute_output --regexp "build" +} + +@test "Image build fails if no image name is defined" { + + # podman mock + podman() { + echo "$@" + } + + # git mock + git() { + echo "1abcdef" + } + + source main.sh image_builder + + run ! cicd_tools::image_builder::build + assert_failure + assert_output --partial "Image name not defined" + refute_output --partial "build" +} + +@test "Image build fails if git hash cannot be retrieved" { + + # podman mock + podman() { + echo "$@" + } + + # git mock + git() { + return 1 + } + + IMAGE_NAME='quay.io/foo/bar' + source main.sh image_builder + + run ! cicd_tools::image_builder::build + assert_failure + assert_output --partial "Cannot retrieve commit hash" + refute_output --partial "build" +} + @test "Image build works as expected with default values" { # podman mock From 30a835c2fe8588fde7bd4464ca1befbfa2e5891c Mon Sep 17 00:00:00 2001 From: Victor M Date: Mon, 25 Sep 2023 11:07:31 +0200 Subject: [PATCH 31/39] auto formatting --- src/bootstrap.sh | 36 ++++++------ src/main.sh | 2 +- src/shared/container_lib.sh | 98 ++++++++++++++++----------------- src/shared/image_builder_lib.sh | 85 ++++++++++++++-------------- 4 files changed, 109 insertions(+), 112 deletions(-) diff --git a/src/bootstrap.sh b/src/bootstrap.sh index 24203b14..e06ea75f 100644 --- a/src/bootstrap.sh +++ b/src/bootstrap.sh @@ -8,37 +8,37 @@ CICD_TOOLS_SKIP_CLEANUP=${CICD_TOOLS_SKIP_CLEANUP:-} clone_cicd_tools_repo() { - if [ -d "${CICD_TOOLS_ROOTDIR}" ]; then - _delete_cicd_tools_rootdir - fi + if [ -d "${CICD_TOOLS_ROOTDIR}" ]; then + _delete_cicd_tools_rootdir + fi - git clone -q \ - --branch "$CICD_TOOLS_REPO_BRANCH" \ - "https://github.com/${CICD_TOOLS_REPO_ORG}/cicd-tools.git" "$CICD_TOOLS_ROOTDIR" + git clone -q \ + --branch "$CICD_TOOLS_REPO_BRANCH" \ + "https://github.com/${CICD_TOOLS_REPO_ORG}/cicd-tools.git" "$CICD_TOOLS_ROOTDIR" } _delete_cicd_tools_rootdir() { - cicd_tools::debug "Removing existing CICD tools directory: '${CICD_TOOLS_ROOTDIR}'" - rm -rf "${CICD_TOOLS_ROOTDIR}" + cicd_tools::debug "Removing existing CICD tools directory: '${CICD_TOOLS_ROOTDIR}'" + rm -rf "${CICD_TOOLS_ROOTDIR}" } cleanup() { - _delete_cicd_tools_rootdir - unset clone_cicd_tools_repo _delete_cicd_tools_rootdir cleanup + _delete_cicd_tools_rootdir + unset clone_cicd_tools_repo _delete_cicd_tools_rootdir cleanup } if [ -z "$CICD_TOOLS_SKIP_GIT_CLONE" ]; then - if ! clone_cicd_tools_repo; then - echo "couldn't clone cicd-tools repository!" - exit 1 - fi + if ! clone_cicd_tools_repo; then + echo "couldn't clone cicd-tools repository!" + exit 1 + fi fi # shellcheck source=src/main.sh source "$CICD_TOOLS_SCRIPTS_DIR/main.sh" "$@" || exit 1 if [ -z "$CICD_TOOLS_SKIP_CLEANUP" ]; then - if ! cleanup; then - echo "couldn't perform cicd tools cleanup!" - exit 1 - fi + if ! cleanup; then + echo "couldn't perform cicd tools cleanup!" + exit 1 + fi fi diff --git a/src/main.sh b/src/main.sh index 663d4a92..dc611ccb 100644 --- a/src/main.sh +++ b/src/main.sh @@ -4,7 +4,7 @@ CICD_TOOLS_COMMON_LIB_LOADED=${CICD_TOOLS_COMMON_LIB_LOADED:-1} CICD_TOOLS_CONTAINER_LIB_LOADED=${CICD_TOOLS_CONTAINER_LIB_LOADED:-1} CICD_TOOLS_DEBUG="${CICD_TOOLS_DEBUG:-}" # https://stackoverflow.com/a/246128 -SCRIPT_DIR="$( cd -- "$( dirname -- "${BASH_SOURCE[0]}" )" &> /dev/null && pwd )" +SCRIPT_DIR="$(cd -- "$(dirname -- "${BASH_SOURCE[0]}")" &> /dev/null && pwd)" CICD_TOOLS_SCRIPTS_DIR="${CICD_TOOLS_SCRIPTS_DIR:-$SCRIPT_DIR}" LIB_TO_LOAD=${1:-container} diff --git a/src/shared/container_lib.sh b/src/shared/container_lib.sh index dd6bb929..a4ae41a8 100644 --- a/src/shared/container_lib.sh +++ b/src/shared/container_lib.sh @@ -5,13 +5,13 @@ CICD_TOOLS_CONTAINER_ENGINE_LOADED=${CICD_TOOLS_CONTAINER_ENGINE_LOADED:-1} if [[ "$CICD_TOOLS_CONTAINER_ENGINE_LOADED" -eq 0 ]]; then - cicd_tools::debug "container engine library already loaded, skipping" - return 0 + cicd_tools::debug "container engine library already loaded, skipping" + return 0 fi if [ -z "$CICD_TOOLS_SCRIPTS_DIR" ]; then - echo "scripts directory not defined, please load through main.sh script" >&2 - return 1 + echo "scripts directory not defined, please load through main.sh script" >&2 + return 1 fi cicd_tools::debug "loading container lib" @@ -21,91 +21,91 @@ PREFER_CONTAINER_ENGINE=${PREFER_CONTAINER_ENGINE:-} cicd_tools::container::cmd() { - if [[ -z "$CONTAINER_ENGINE_CMD" ]]; then - if ! cicd_tools::container::_set_container_engine_cmd; then - return 1 - fi + if [[ -z "$CONTAINER_ENGINE_CMD" ]]; then + if ! cicd_tools::container::_set_container_engine_cmd; then + return 1 fi + fi - "$CONTAINER_ENGINE_CMD" "$@" + "$CONTAINER_ENGINE_CMD" "$@" } cicd_tools::container::_set_container_engine_cmd() { - if cicd_tools::container::_preferred_container_engine_available; then - CONTAINER_ENGINE_CMD="$PREFER_CONTAINER_ENGINE" + if cicd_tools::container::_preferred_container_engine_available; then + CONTAINER_ENGINE_CMD="$PREFER_CONTAINER_ENGINE" + else + if cicd_tools::container::_container_engine_available 'podman'; then + CONTAINER_ENGINE_CMD='podman' + elif cicd_tools::container::_container_engine_available 'docker'; then + CONTAINER_ENGINE_CMD='docker' else - if cicd_tools::container::_container_engine_available 'podman'; then - CONTAINER_ENGINE_CMD='podman' - elif cicd_tools::container::_container_engine_available 'docker'; then - CONTAINER_ENGINE_CMD='docker' - else - cicd_tools::err "ERROR, no container engine found, please install either podman or docker first" - return 1 - fi + cicd_tools::err "ERROR, no container engine found, please install either podman or docker first" + return 1 fi + fi - cicd_tools::debug "Container engine selected: $CONTAINER_ENGINE_CMD" + cicd_tools::debug "Container engine selected: $CONTAINER_ENGINE_CMD" } cicd_tools::container::_preferred_container_engine_available() { - local CONTAINER_ENGINE_AVAILABLE=1 + local CONTAINER_ENGINE_AVAILABLE=1 - if [ -n "$PREFER_CONTAINER_ENGINE" ]; then - if cicd_tools::container::_container_engine_available "$PREFER_CONTAINER_ENGINE"; then - CONTAINER_ENGINE_AVAILABLE=0 - else - cicd_tools::log "WARNING: preferred container engine '${PREFER_CONTAINER_ENGINE}' not present, or isn't supported, finding alternative..." - fi + if [ -n "$PREFER_CONTAINER_ENGINE" ]; then + if cicd_tools::container::_container_engine_available "$PREFER_CONTAINER_ENGINE"; then + CONTAINER_ENGINE_AVAILABLE=0 + else + cicd_tools::log "WARNING: preferred container engine '${PREFER_CONTAINER_ENGINE}' not present, or isn't supported, finding alternative..." fi + fi - return "$CONTAINER_ENGINE_AVAILABLE" + return "$CONTAINER_ENGINE_AVAILABLE" } cicd_tools::container::_container_engine_available() { - local cmd="$1" - local available=1 + local cmd="$1" + local available=1 - if cicd_tools::container::_cmd_exists_and_is_supported "$cmd"; then - available=0 - fi + if cicd_tools::container::_cmd_exists_and_is_supported "$cmd"; then + available=0 + fi - return "$available" + return "$available" } cicd_tools::container::_cmd_exists_and_is_supported() { - local cmd="$1" - local result=0 + local cmd="$1" + local result=0 - if cicd_tools::container::_supported_container_engine "$cmd" && cicd_tools::common::command_is_present "$cmd"; then - if [[ "$cmd" == 'docker' ]] && cicd_tools::container::_docker_seems_emulated; then - cicd_tools::log "WARNING: docker seems emulated, skipping." - result=1 - fi - else - result=1 + if cicd_tools::container::_supported_container_engine "$cmd" && cicd_tools::common::command_is_present "$cmd"; then + if [[ "$cmd" == 'docker' ]] && cicd_tools::container::_docker_seems_emulated; then + cicd_tools::log "WARNING: docker seems emulated, skipping." + result=1 fi + else + result=1 + fi - return "$result" + return "$result" } cicd_tools::container::_supported_container_engine() { - local CONTAINER_ENGINE_TO_CHECK="$1" + local CONTAINER_ENGINE_TO_CHECK="$1" - [ "$CONTAINER_ENGINE_TO_CHECK" = 'docker' ] || \ - [ "$CONTAINER_ENGINE_TO_CHECK" = 'podman' ] + [ "$CONTAINER_ENGINE_TO_CHECK" = 'docker' ] || + [ "$CONTAINER_ENGINE_TO_CHECK" = 'podman' ] } cicd_tools::container::_docker_seems_emulated() { - [[ "$(docker 2>/dev/null --version)" =~ podman\ +version ]] + [[ "$(docker 2> /dev/null --version)" =~ podman\ +version ]] } cicd_tools::container::_podman_version_under_4_5_0() { - [ "$(echo -en "4.5.0\n$(_podman_version)" | sort -V | head -1)" != "4.5.0" ] + [ "$(echo -en "4.5.0\n$(_podman_version)" | sort -V | head -1)" != "4.5.0" ] } CICD_TOOLS_CONTAINER_ENGINE_LOADED=0 diff --git a/src/shared/image_builder_lib.sh b/src/shared/image_builder_lib.sh index c39f846b..1e7f8d3f 100644 --- a/src/shared/image_builder_lib.sh +++ b/src/shared/image_builder_lib.sh @@ -26,7 +26,7 @@ readonly CICD_TOOLS_IMAGE_BUILDER_DEFAULT_CONTAINERFILE_PATH='Dockerfile' cicd_tools::image_builder::build_and_push() { cicd_tools::image_builder::build || return 1 if cicd_tools::image_builder::is_change_request_context; then - cicd_tools::image_builder::push || return 1 + cicd_tools::image_builder::push || return 1 fi } @@ -41,8 +41,8 @@ cicd_tools::image_builder::build() { default_image_name=$(cicd_tools::image_builder::get_full_image_name) || return 1 if ! [ -r "$containerfile" ]; then - cicd_tools::err "Containerfile '$containerfile' does not exist or is not readable!" - return 1 + cicd_tools::err "Containerfile '$containerfile' does not exist or is not readable!" + return 1 fi image_tag_params=('-t' "$default_image_name") @@ -52,19 +52,19 @@ cicd_tools::image_builder::build() { image_tag_params+=('-t' "${image_name}:${additional_tag}") done fi - + for label in $(cicd_tools::image_builder::get_labels); do - label_params+=('--label' "${label}") + label_params+=('--label' "${label}") done for build_arg in $(cicd_tools::image_builder::get_build_args); do - build_arg_params+=('--build-arg' "${build_arg}") + build_arg_params+=('--build-arg' "${build_arg}") done if ! cicd_tools::container::cmd build -f "$containerfile" "${image_tag_params[@]}" \ - "${build_arg_params[@]}" "${label_params[@]}" "$build_context"; then - cicd_tools::err "Error building image" - return 1 + "${build_arg_params[@]}" "${label_params[@]}" "$build_context"; then + cicd_tools::err "Error building image" + return 1 fi } @@ -73,7 +73,7 @@ cicd_tools::image_builder::get_containerfile() { local containerfile="${CICD_TOOLS_IMAGE_BUILDER_CONTAINERFILE_PATH:-"$CONTAINERFILE_PATH"}" if [ -z "$containerfile" ]; then - containerfile=$CICD_TOOLS_IMAGE_BUILDER_DEFAULT_CONTAINERFILE_PATH + containerfile=$CICD_TOOLS_IMAGE_BUILDER_DEFAULT_CONTAINERFILE_PATH fi echo -n "$containerfile" @@ -84,14 +84,12 @@ cicd_tools::image_builder::get_build_context() { local build_context="${CICD_TOOLS_IMAGE_BUILDER_BUILD_CONTEXT:-"$BUILD_CONTEXT"}" if [ -z "$build_context" ]; then - build_context="$CICD_TOOLS_IMAGE_BUILDER_DEFAULT_BUILD_CONTEXT" + build_context="$CICD_TOOLS_IMAGE_BUILDER_DEFAULT_BUILD_CONTEXT" fi echo -n "$build_context" } - - cicd_tools::image_builder::_get_image_name() { local image_name="${CICD_TOOLS_IMAGE_BUILDER_IMAGE_NAME:-$IMAGE_NAME}" @@ -114,10 +112,10 @@ cicd_tools::image_builder::get_image_tag() { fi if cicd_tools::image_builder::is_change_request_context; then - build_id=$(cicd_tools::image_builder::get_build_id) - tag="pr-${build_id}-${commit_hash}" + build_id=$(cicd_tools::image_builder::get_build_id) + tag="pr-${build_id}-${commit_hash}" else - tag="${commit_hash}" + tag="${commit_hash}" fi echo -n "${tag}" @@ -132,9 +130,9 @@ cicd_tools::image_builder::get_build_id() { local build_id if [ -n "$ghprbPullId" ]; then - build_id="$ghprbPullId" + build_id="$ghprbPullId" elif [ -n "$gitlabMergeRequestId" ]; then - build_id="$gitlabMergeRequestId" + build_id="$gitlabMergeRequestId" fi echo -n "$build_id" @@ -145,7 +143,7 @@ cicd_tools::image_builder::get_additional_tags() { declare -a additional_tags=("${CICD_TOOLS_IMAGE_BUILDER_ADDITIONAL_TAGS[@]:-${ADDITIONAL_TAGS[@]}}") if cicd_tools::image_builder::_array_empty "${additional_tags[@]}"; then - additional_tags=() + additional_tags=() fi echo -n "${additional_tags[@]}" @@ -162,11 +160,11 @@ cicd_tools::image_builder::get_labels() { declare -a labels=("${CICD_TOOLS_IMAGE_BUILDER_LABELS[@]:-${LABELS[@]}}") if cicd_tools::image_builder::_array_empty "${labels[@]}"; then - labels=() + labels=() fi if cicd_tools::image_builder::is_change_request_context; then - labels+=("$(cicd_tools::image_builder::_get_expiry_label)") + labels+=("$(cicd_tools::image_builder::_get_expiry_label)") fi echo -n "${labels[@]}" @@ -181,7 +179,7 @@ cicd_tools::image_builder::get_build_args() { declare -a build_args=("${CICD_TOOLS_IMAGE_BUILDER_BUILD_ARGS[@]:-${BUILD_ARGS[@]}}") if cicd_tools::image_builder::_array_empty "${build_args[@]}"; then - build_args=() + build_args=() fi echo -n "${build_args[@]}" @@ -195,8 +193,8 @@ cicd_tools::image_builder::tag() { for target_tag in $(cicd_tools::image_builder::get_additional_tags); do if ! cicd_tools::container::cmd tag "$source_image" "${image_name}:${target_tag}"; then - cicd_tools::err "Error tagging '$source_image' as '${image_name}:${target_tag}'" - return 1 + cicd_tools::err "Error tagging '$source_image' as '${image_name}:${target_tag}'" + return 1 fi done } @@ -210,16 +208,16 @@ cicd_tools::image_builder::push() { image_tags=("$image_tag") if ! cicd_tools::image_builder::is_change_request_context; then - for additional_tag in $(cicd_tools::image_builder::get_additional_tags); do - image_tags+=("${additional_tag}") - done + for additional_tag in $(cicd_tools::image_builder::get_additional_tags); do + image_tags+=("${additional_tag}") + done fi for tag in "${image_tags[@]}"; do - if ! cicd_tools::container::cmd push "${image_name}:${tag}"; then - cicd_tools::err "Error pushing image: '${image_name}:${tag}'" - return 1 - fi + if ! cicd_tools::container::cmd push "${image_name}:${tag}"; then + cicd_tools::err "Error pushing image: '${image_name}:${tag}'" + return 1 + fi done } @@ -232,7 +230,6 @@ cicd_tools::image_builder::get_full_image_name() { echo -n "${image_name}:${image_tag}" } - cicd_tools::image_builder::_image_builder_setup() { if ! cicd_tools::image_builder::_try_log_in_to_image_registries; then @@ -244,29 +241,29 @@ cicd_tools::image_builder::_image_builder_setup() { cicd_tools::image_builder::_try_log_in_to_image_registries() { if cicd_tools::image_builder::_quay_credentials_found; then - if ! cicd_tools::image_builder::_log_in_to_quay_registry; then + if ! cicd_tools::image_builder::_log_in_to_quay_registry; then cicd_tools::err "Error logging in to Quay.io!" return 1 - fi + fi fi if cicd_tools::image_builder::_redhat_registry_credentials_found; then - if ! cicd_tools::image_builder::_log_in_to_redhat_registry; then + if ! cicd_tools::image_builder::_log_in_to_redhat_registry; then cicd_tools::err "Error logging in to Red Hat Registry!" return 1 - fi + fi fi } cicd_tools::image_builder::_quay_credentials_found() { - [ -n "$CICD_TOOLS_IMAGE_BUILDER_QUAY_USER" ] && \ - [ -n "$CICD_TOOLS_IMAGE_BUILDER_QUAY_PASSWORD" ] + [ -n "$CICD_TOOLS_IMAGE_BUILDER_QUAY_USER" ] && + [ -n "$CICD_TOOLS_IMAGE_BUILDER_QUAY_PASSWORD" ] } cicd_tools::image_builder::_log_in_to_quay_registry() { cicd_tools::image_builder::_log_in_to_container_registry "$CICD_TOOLS_IMAGE_BUILDER_QUAY_USER" \ - "$CICD_TOOLS_IMAGE_BUILDER_QUAY_PASSWORD" \ - "$CICD_TOOLS_IMAGE_BUILDER_QUAY_REGISTRY" + "$CICD_TOOLS_IMAGE_BUILDER_QUAY_PASSWORD" \ + "$CICD_TOOLS_IMAGE_BUILDER_QUAY_REGISTRY" } cicd_tools::image_builder::_log_in_to_container_registry() { @@ -279,14 +276,14 @@ cicd_tools::image_builder::_log_in_to_container_registry() { } cicd_tools::image_builder::_redhat_registry_credentials_found() { - [ -n "$CICD_TOOLS_IMAGE_BUILDER_REDHAT_USER" ] && \ - [ -n "$CICD_TOOLS_IMAGE_BUILDER_REDHAT_PASSWORD" ] + [ -n "$CICD_TOOLS_IMAGE_BUILDER_REDHAT_USER" ] && + [ -n "$CICD_TOOLS_IMAGE_BUILDER_REDHAT_PASSWORD" ] } cicd_tools::image_builder::_log_in_to_redhat_registry() { cicd_tools::image_builder::_log_in_to_container_registry "$CICD_TOOLS_IMAGE_BUILDER_REDHAT_USER" \ - "$CICD_TOOLS_IMAGE_BUILDER_REDHAT_PASSWORD" \ - "$CICD_TOOLS_IMAGE_BUILDER_REDHAT_REGISTRY" + "$CICD_TOOLS_IMAGE_BUILDER_REDHAT_PASSWORD" \ + "$CICD_TOOLS_IMAGE_BUILDER_REDHAT_REGISTRY" } if ! cicd_tools::image_builder::_image_builder_setup; then From a7b807231558e06ed7e32919cf2952421b12c41b Mon Sep 17 00:00:00 2001 From: Victor M Date: Mon, 25 Sep 2023 11:42:00 +0200 Subject: [PATCH 32/39] reformat README --- README.md | 82 ++++++++++++++++++++++++++++++++----------------------- 1 file changed, 48 insertions(+), 34 deletions(-) diff --git a/README.md b/README.md index caf007c0..5ffea7ba 100644 --- a/README.md +++ b/README.md @@ -1,39 +1,47 @@ # CI/CD Tools ## Description + Utilities used to run smoke tests in an ephemeral environment within a CI/CD pipeline ## Getting Started -Grab the Jenkinsfile template for your [backend](examples/backend-pipeline-pr-checks/Jenkinsfile) or [frontend](examples/frontends-pipeline-pr-checks/Jenkinsfile) and cater it to your specific needs. This file should reside in your git repositories root directory. That Jenkinsfile will download the necessary files from this repository. It does not have a unit test file so that will need to be made in your repository. You can find a unit test template file [here](examples/unit_test_example.sh). + +Grab the Jenkinsfile template for your [backend](examples/backend-pipeline-pr-checks/Jenkinsfile) +or [frontend](examples/frontends-pipeline-pr-checks/Jenkinsfile) and cater it to your specific +needs. This file should reside in your git repositories root directory. That Jenkinsfile will +download the necessary files from this repository. It does not have a unit test file so that will +need to be made in your repository. You can find a unit test template +file [here](examples/unit_test_example.sh). ## Scripts -| Script | Description | -| ----------------------- | ----------- | -| bootstrap.sh | Clone bonfire into workspace, setup python venv, modify PATH, login to container registries, login to Kube/OCP, and set envvars used by following scripts. | +| Script | Description | +|-------------------------|------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------| +| bootstrap.sh | Clone bonfire into workspace, setup python venv, modify PATH, login to container registries, login to Kube/OCP, and set envvars used by following scripts. | | build.sh | Using docker (rhel7) or podman (else) build, tag, and push an image to Quay and Red Hat registries. If its a GitHub or GitLab PR/MR triggered script execution, tag image with `pr-123-SHA` and `pr-123-testing`, else use a short SHA for the target repo HEAD. | -| deploy_ephemeral_db.sh | Deploy using `bonfire process` and ` apply`, removing dependencies and setting up database envvars. | -| deploy_ephemeral_env.sh | Deploy using `bonfire deploy` into ephemeral, specifying app, component, and relevant image tag args. Passes `EXTRA_DEPLOY_ARGS` which can be set by the caller via pr_checks.sh. -| cji_smoke_test.sh | Run iqe-tests container for the relevant app plugin using `bonfire deploy-iqe-cji`. Waits for tests to complete, and fetches artifacts using minio. -| post_test_results.sh | Using artifacts fetched from `cji_smoke_test.sh`, add a GitHub status or GitLab comment linking to the relevant test results in Ibutsu. -| smoke_test.sh | **DEPRECATED**, use [cji_smoke_test.sh](cji_smoke_test.sh) | -| iqe_pod | **DEPRECATED**, use [cji_smoke_test.sh](cji_smoke_test.sh) | +| deploy_ephemeral_db.sh | Deploy using `bonfire process` and ` apply`, removing dependencies and setting up database envvars. | +| deploy_ephemeral_env.sh | Deploy using `bonfire deploy` into ephemeral, specifying app, component, and relevant image tag args. Passes `EXTRA_DEPLOY_ARGS` which can be set by the caller via pr_checks.sh. | +| cji_smoke_test.sh | Run iqe-tests container for the relevant app plugin using `bonfire deploy-iqe-cji`. Waits for tests to complete, and fetches artifacts using minio. | +| post_test_results.sh | Using artifacts fetched from `cji_smoke_test.sh`, add a GitHub status or GitLab comment linking to the relevant test results in Ibutsu. | +| smoke_test.sh | **DEPRECATED**, use [cji_smoke_test.sh](cji_smoke_test.sh) | +| iqe_pod | **DEPRECATED**, use [cji_smoke_test.sh](cji_smoke_test.sh) | ## Bash script helper scripts usage -The collection of helper libraries are expected to be loaded using the provided [src/bootstrap.sh](bootstrap) script. +The collection of helper libraries are expected to be loaded using the +provided [src/bootstrap.sh](bootstrap) script. -Currently there are 2 supported libraries: +Currently, there are 2 supported libraries: -|Library ID|Description| -|----------|-----------| -|container | Provides wrapper functions for invoking container engine agnostic commands| -|image_builder| Provides helper functions to simplify the image building process| +| Library ID | Description | +|---------------|----------------------------------------------------------------------------| +| container | Provides wrapper functions for invoking container engine agnostic commands | +| image_builder | Provides helper functions to simplify the image building process | ### How to use the helper libraries -To use any of the provided libraries, you must source the [src/bootstrap.sh](bootstrap.sh) script and pass -the unique library ID to be loaded as a paramter. +To use any of the provided libraries, you must source the [src/bootstrap.sh](bootstrap.sh) script +and pass the unique library ID to be loaded as a paramter. One can simply either source the [src/bootstrap.sh](bootstrap) script directly: @@ -66,20 +74,24 @@ you can select which collection needs to load independently as a parameter: source bootstrap.sh container ``` -The bootstrap script will download the selected version of the CICD scripts (or `latest` if none specified) into the directory defined by -the `CICD_TOOLS_WORKDIR` variable (defaults to `.cicd_tools` in the current directory). +The bootstrap script will download the selected version of the CICD scripts (or `latest` if none +specified) into the directory defined by the `CICD_TOOLS_WORKDIR` variable (defaults +to `.cicd_tools` in the current directory). -**Please note** that when cloning the repo, the directory defined by the `CICD_TOOLS_WORKDIR` will be deleted! +**Please note** that when cloning the repo, the directory defined by the `CICD_TOOLS_WORKDIR` will +be deleted! You can disable running the `git clone` by setting the `CICD_TOOLS_SKIP_GIT_CLONE` variable The bootstrap.sh can be invoked multiple times but it has a status control to ensure each -of the libraries is loaded only once. This is to prevent potential issues with collections +of the libraries is loaded only once. This is to prevent potential issues with collections that are not supposed to be loaded many times. An example of this is the _container_ library, where the selected container engine -is **set only once the first command using the library helper function `cicd_tools::container::cmd` is used**. +is **set only once the first command using the library helper function `cicd_tools::container::cmd` +is used**. -Each of the libraries will export to the shell sourcing the bootstrap script the helper functions. +Each of the libraries will export their functions and variables to the shell when sourcing the +bootstrap script the helper functions. These functions are all namespaced, meaning the names follow the naming format: ``` @@ -87,23 +99,25 @@ cicd_tools::library::function ``` where: + - cicd_tools represents the namespace root, which is shared by all functions - library would match with each of the imported library IDs. - ## Template Scripts -| Script | Description | -| ----------------------- | ----------- | -| examples/backend-pipeline-pr-checks/Jenkinsfile | Templated example of the pr-check pipeline for backend apps | + +| Script | Description | +|---------------------------------------------------|--------------------------------------------------------------| +| examples/backend-pipeline-pr-checks/Jenkinsfile | Templated example of the pr-check pipeline for backend apps | | examples/frontends-pipeline-pr-checks/Jenkinsfile | Templated example of the pr-check pipeline for frontend apps | -| examples/pr_check_template.sh | | -| examples/unit_test_example.sh | | -| examples/unit_test_example_ephemeral_db.sh | | +| examples/pr_check_template.sh | | +| examples/unit_test_example.sh | | +| examples/unit_test_example_ephemeral_db.sh | | ## Contributing Suggested method for testing changes to these scripts: + - Modify `bootstrap.sh` to `git clone` your fork and branch of bonfire. -- Open a PR in a repo using bonfire pr_checks and the relevant scripts, modifying `pr_check` script to clone your fork and branch of bonfire. -- Observe modified scripts running in the relevant CI/CD pipeline. -# +- Open a PR in a repo using bonfire pr_checks and the relevant scripts, modifying `pr_check` script + to clone your fork and branch of bonfire. +- Observe modified scripts running in the relevant CI/CD pipeline. \ No newline at end of file From d98594618ce853068daa1449b9d9e9af932728af Mon Sep 17 00:00:00 2001 From: Victor M Date: Thu, 28 Sep 2023 12:21:47 +0200 Subject: [PATCH 33/39] Add note about style guide used --- README.md | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/README.md b/README.md index 5ffea7ba..5b351016 100644 --- a/README.md +++ b/README.md @@ -92,7 +92,9 @@ is used**. Each of the libraries will export their functions and variables to the shell when sourcing the bootstrap script the helper functions. -These functions are all namespaced, meaning the names follow the naming format: + +This library follows [Google's Shell style guide](https://google.github.io/styleguide/shellguide.html), +so the functions are all namespaced, meaning the names follow the naming format: ``` cicd_tools::library::function From e759cb99a7450c93cdc37af99c91aa67dc69f92e Mon Sep 17 00:00:00 2001 From: Victor M Date: Thu, 28 Sep 2023 12:32:55 +0200 Subject: [PATCH 34/39] rename from cicd_tools to cicd --- .gitignore | 2 + README.md | 6 +- src/bootstrap.sh | 2 +- src/main.sh | 46 +++--- src/shared/common_lib.sh | 20 +-- src/shared/container_lib.sh | 44 ++--- src/shared/image_builder_lib.sh | 150 +++++++++--------- test/e2e/test_bootstrap_script_main.sh | 8 +- ..._e2e_load_library_from_bootstrap_script.sh | 8 +- .../test_e2e_load_library_from_function.sh | 8 +- test/e2e/test_e2e_load_library_locally.sh | 8 +- test/e2e/test_image_builder.sh | 4 +- test/main.bats | 4 +- test/shared_common_lib.bats | 18 +-- test/shared_container_lib.bats | 36 ++--- test/shared_image_builder_lib.bats | 38 ++--- 16 files changed, 202 insertions(+), 200 deletions(-) diff --git a/.gitignore b/.gitignore index 4a6d65f7..4e8f6013 100644 --- a/.gitignore +++ b/.gitignore @@ -24,3 +24,5 @@ tags # End of https://www.toptal.com/developers/gitignore/api/vim .cicd_tools +coverage +.idea diff --git a/README.md b/README.md index 5b351016..78db5161 100644 --- a/README.md +++ b/README.md @@ -48,7 +48,7 @@ One can simply either source the [src/bootstrap.sh](bootstrap) script directly: ``` $ source <(curl -sSL https://raw.githubusercontent.com/RedHatInsights/cicd-tools/main/src/bootstrap.sh) container -$ cicd_tools::container::cmd --version +$ cicd::container::cmd --version podman version 4.6.1 ``` @@ -87,7 +87,7 @@ of the libraries is loaded only once. This is to prevent potential issues with c that are not supposed to be loaded many times. An example of this is the _container_ library, where the selected container engine -is **set only once the first command using the library helper function `cicd_tools::container::cmd` +is **set only once the first command using the library helper function `cicd::container::cmd` is used**. Each of the libraries will export their functions and variables to the shell when sourcing the @@ -97,7 +97,7 @@ This library follows [Google's Shell style guide](https://google.github.io/style so the functions are all namespaced, meaning the names follow the naming format: ``` -cicd_tools::library::function +cicd::library::function ``` where: diff --git a/src/bootstrap.sh b/src/bootstrap.sh index e06ea75f..d1d1d3dc 100644 --- a/src/bootstrap.sh +++ b/src/bootstrap.sh @@ -18,7 +18,7 @@ clone_cicd_tools_repo() { } _delete_cicd_tools_rootdir() { - cicd_tools::debug "Removing existing CICD tools directory: '${CICD_TOOLS_ROOTDIR}'" + cicd::debug "Removing existing CICD tools directory: '${CICD_TOOLS_ROOTDIR}'" rm -rf "${CICD_TOOLS_ROOTDIR}" } diff --git a/src/main.sh b/src/main.sh index dc611ccb..bad23c04 100644 --- a/src/main.sh +++ b/src/main.sh @@ -8,57 +8,57 @@ SCRIPT_DIR="$(cd -- "$(dirname -- "${BASH_SOURCE[0]}")" &> /dev/null && pwd)" CICD_TOOLS_SCRIPTS_DIR="${CICD_TOOLS_SCRIPTS_DIR:-$SCRIPT_DIR}" LIB_TO_LOAD=${1:-container} -cicd_tools::debug() { - if cicd_tools::_debug_mode; then - cicd_tools::log "$*" +cicd::debug() { + if cicd::_debug_mode; then + cicd::log "$*" fi } -cicd_tools::_debug_mode() { +cicd::_debug_mode() { [[ -n "$CICD_TOOLS_DEBUG" ]] } -cicd_tools::log() { +cicd::log() { echo "[$(date +'%Y-%m-%dT%H:%M:%S%z')]: $*" } -cicd_tools::err() { +cicd::err() { echo "[$(date +'%Y-%m-%dT%H:%M:%S%z')]: $*" >&2 } -cicd_tools::load_library() { +cicd::load_library() { case $LIB_TO_LOAD in - all) cicd_tools::_load_all ;; - common) cicd_tools::_load_common_lib ;; - container) cicd_tools::_load_container_lib ;; - image_builder) cicd_tools::_load_image_builder_lib ;; - *) cicd_tools::err "Unsupported library: '$LIB_TO_LOAD'" && return 1 ;; + all) cicd::_load_all ;; + common) cicd::_load_common_lib ;; + container) cicd::_load_container_lib ;; + image_builder) cicd::_load_image_builder_lib ;; + *) cicd::err "Unsupported library: '$LIB_TO_LOAD'" && return 1 ;; esac } -cicd_tools::_load_all() { - cicd_tools::_load_common_lib - cicd_tools::_load_container_lib - cicd_tools::_load_image_builder_lib +cicd::_load_all() { + cicd::_load_common_lib + cicd::_load_container_lib + cicd::_load_image_builder_lib } -cicd_tools::_load_common_lib() { +cicd::_load_common_lib() { # shellcheck source=src/shared/common_lib.sh source "${CICD_TOOLS_SCRIPTS_DIR}/shared/common_lib.sh" } -cicd_tools::_load_container_lib() { - cicd_tools::_load_common_lib +cicd::_load_container_lib() { + cicd::_load_common_lib # shellcheck source=src/shared/container_lib.sh source "${CICD_TOOLS_SCRIPTS_DIR}/shared/container_lib.sh" } -cicd_tools::_load_image_builder_lib() { - cicd_tools::_load_common_lib - cicd_tools::_load_container_lib +cicd::_load_image_builder_lib() { + cicd::_load_common_lib + cicd::_load_container_lib # shellcheck source=src/shared/image_builder_lib.sh source "${CICD_TOOLS_SCRIPTS_DIR}/shared/image_builder_lib.sh" } -cicd_tools::load_library "$LIB_TO_LOAD" +cicd::load_library "$LIB_TO_LOAD" diff --git a/src/shared/common_lib.sh b/src/shared/common_lib.sh index 369828e9..cd494788 100644 --- a/src/shared/common_lib.sh +++ b/src/shared/common_lib.sh @@ -6,7 +6,7 @@ CICD_TOOLS_COMMON_LOADED=${CICD_TOOLS_COMMON_LOADED:-1} LOCAL_BUILD=${LOCAL_BUILD:-false} if [ "$CICD_TOOLS_COMMON_LOADED" -eq 0 ]; then - cicd_tools::debug "common library already loaded, skipping" + cicd::debug "common library already loaded, skipping" return 0 fi @@ -15,28 +15,28 @@ if [ -z "$CICD_TOOLS_SCRIPTS_DIR" ]; then return 1 fi -cicd_tools::debug "loading common lib" +cicd::debug "loading common lib" -cicd_tools::common::command_is_present() { +cicd::common::command_is_present() { command -v "$1" > /dev/null 2>&1 } -cicd_tools::common::_get_n_chars_commit_hash() { +cicd::common::_get_n_chars_commit_hash() { git rev-parse --short="$1" HEAD } -cicd_tools::common::get_7_chars_commit_hash() { - cicd_tools::common::_get_n_chars_commit_hash 7 +cicd::common::get_7_chars_commit_hash() { + cicd::common::_get_n_chars_commit_hash 7 } -cicd_tools::common::is_ci_context() { +cicd::common::is_ci_context() { [[ "$CI" = "true" ]] } -cicd_tools::common::local_build() { - [[ "$LOCAL_BUILD" = true ]] || ! cicd_tools::common::is_ci_context +cicd::common::local_build() { + [[ "$LOCAL_BUILD" = true ]] || ! cicd::common::is_ci_context } -cicd_tools::debug "common lib loaded" +cicd::debug "common lib loaded" CICD_TOOLS_COMMON_LOADED=0 diff --git a/src/shared/container_lib.sh b/src/shared/container_lib.sh index a4ae41a8..9e6388fe 100644 --- a/src/shared/container_lib.sh +++ b/src/shared/container_lib.sh @@ -5,7 +5,7 @@ CICD_TOOLS_CONTAINER_ENGINE_LOADED=${CICD_TOOLS_CONTAINER_ENGINE_LOADED:-1} if [[ "$CICD_TOOLS_CONTAINER_ENGINE_LOADED" -eq 0 ]]; then - cicd_tools::debug "container engine library already loaded, skipping" + cicd::debug "container engine library already loaded, skipping" return 0 fi @@ -14,15 +14,15 @@ if [ -z "$CICD_TOOLS_SCRIPTS_DIR" ]; then return 1 fi -cicd_tools::debug "loading container lib" +cicd::debug "loading container lib" CONTAINER_ENGINE_CMD='' PREFER_CONTAINER_ENGINE=${PREFER_CONTAINER_ENGINE:-} -cicd_tools::container::cmd() { +cicd::container::cmd() { if [[ -z "$CONTAINER_ENGINE_CMD" ]]; then - if ! cicd_tools::container::_set_container_engine_cmd; then + if ! cicd::container::_set_container_engine_cmd; then return 1 fi fi @@ -30,59 +30,59 @@ cicd_tools::container::cmd() { "$CONTAINER_ENGINE_CMD" "$@" } -cicd_tools::container::_set_container_engine_cmd() { +cicd::container::_set_container_engine_cmd() { - if cicd_tools::container::_preferred_container_engine_available; then + if cicd::container::_preferred_container_engine_available; then CONTAINER_ENGINE_CMD="$PREFER_CONTAINER_ENGINE" else - if cicd_tools::container::_container_engine_available 'podman'; then + if cicd::container::_container_engine_available 'podman'; then CONTAINER_ENGINE_CMD='podman' - elif cicd_tools::container::_container_engine_available 'docker'; then + elif cicd::container::_container_engine_available 'docker'; then CONTAINER_ENGINE_CMD='docker' else - cicd_tools::err "ERROR, no container engine found, please install either podman or docker first" + cicd::err "ERROR, no container engine found, please install either podman or docker first" return 1 fi fi - cicd_tools::debug "Container engine selected: $CONTAINER_ENGINE_CMD" + cicd::debug "Container engine selected: $CONTAINER_ENGINE_CMD" } -cicd_tools::container::_preferred_container_engine_available() { +cicd::container::_preferred_container_engine_available() { local CONTAINER_ENGINE_AVAILABLE=1 if [ -n "$PREFER_CONTAINER_ENGINE" ]; then - if cicd_tools::container::_container_engine_available "$PREFER_CONTAINER_ENGINE"; then + if cicd::container::_container_engine_available "$PREFER_CONTAINER_ENGINE"; then CONTAINER_ENGINE_AVAILABLE=0 else - cicd_tools::log "WARNING: preferred container engine '${PREFER_CONTAINER_ENGINE}' not present, or isn't supported, finding alternative..." + cicd::log "WARNING: preferred container engine '${PREFER_CONTAINER_ENGINE}' not present, or isn't supported, finding alternative..." fi fi return "$CONTAINER_ENGINE_AVAILABLE" } -cicd_tools::container::_container_engine_available() { +cicd::container::_container_engine_available() { local cmd="$1" local available=1 - if cicd_tools::container::_cmd_exists_and_is_supported "$cmd"; then + if cicd::container::_cmd_exists_and_is_supported "$cmd"; then available=0 fi return "$available" } -cicd_tools::container::_cmd_exists_and_is_supported() { +cicd::container::_cmd_exists_and_is_supported() { local cmd="$1" local result=0 - if cicd_tools::container::_supported_container_engine "$cmd" && cicd_tools::common::command_is_present "$cmd"; then - if [[ "$cmd" == 'docker' ]] && cicd_tools::container::_docker_seems_emulated; then - cicd_tools::log "WARNING: docker seems emulated, skipping." + if cicd::container::_supported_container_engine "$cmd" && cicd::common::command_is_present "$cmd"; then + if [[ "$cmd" == 'docker' ]] && cicd::container::_docker_seems_emulated; then + cicd::log "WARNING: docker seems emulated, skipping." result=1 fi else @@ -92,7 +92,7 @@ cicd_tools::container::_cmd_exists_and_is_supported() { return "$result" } -cicd_tools::container::_supported_container_engine() { +cicd::container::_supported_container_engine() { local CONTAINER_ENGINE_TO_CHECK="$1" @@ -100,11 +100,11 @@ cicd_tools::container::_supported_container_engine() { [ "$CONTAINER_ENGINE_TO_CHECK" = 'podman' ] } -cicd_tools::container::_docker_seems_emulated() { +cicd::container::_docker_seems_emulated() { [[ "$(docker 2> /dev/null --version)" =~ podman\ +version ]] } -cicd_tools::container::_podman_version_under_4_5_0() { +cicd::container::_podman_version_under_4_5_0() { [ "$(echo -en "4.5.0\n$(_podman_version)" | sort -V | head -1)" != "4.5.0" ] } diff --git a/src/shared/image_builder_lib.sh b/src/shared/image_builder_lib.sh index 1e7f8d3f..9c0cacbd 100644 --- a/src/shared/image_builder_lib.sh +++ b/src/shared/image_builder_lib.sh @@ -11,7 +11,7 @@ if [ -z "$CICD_TOOLS_SCRIPTS_DIR" ]; then return 1 fi -cicd_tools::debug "loading image builder library" +cicd::debug "loading image builder library" readonly CICD_TOOLS_IMAGE_BUILDER_REDHAT_REGISTRY='registry.redhat.io' readonly CICD_TOOLS_IMAGE_BUILDER_QUAY_REGISTRY='quay.io' @@ -23,52 +23,52 @@ readonly CICD_TOOLS_IMAGE_BUILDER_REDHAT_PASSWORD="${CICD_TOOLS_IMAGE_BUILDER_RE readonly CICD_TOOLS_IMAGE_BUILDER_DEFAULT_BUILD_CONTEXT='.' readonly CICD_TOOLS_IMAGE_BUILDER_DEFAULT_CONTAINERFILE_PATH='Dockerfile' -cicd_tools::image_builder::build_and_push() { - cicd_tools::image_builder::build || return 1 - if cicd_tools::image_builder::is_change_request_context; then - cicd_tools::image_builder::push || return 1 +cicd::image_builder::build_and_push() { + cicd::image_builder::build || return 1 + if cicd::image_builder::is_change_request_context; then + cicd::image_builder::push || return 1 fi } -cicd_tools::image_builder::build() { +cicd::image_builder::build() { local containerfile build_context image_name image_tags default_image_name declare -a label_params image_tag_params build_arg_params - containerfile="$(cicd_tools::image_builder::get_containerfile)" - build_context="$(cicd_tools::image_builder::get_build_context)" - image_name="$(cicd_tools::image_builder::_get_image_name)" || return 1 - default_image_name=$(cicd_tools::image_builder::get_full_image_name) || return 1 + containerfile="$(cicd::image_builder::get_containerfile)" + build_context="$(cicd::image_builder::get_build_context)" + image_name="$(cicd::image_builder::_get_image_name)" || return 1 + default_image_name=$(cicd::image_builder::get_full_image_name) || return 1 if ! [ -r "$containerfile" ]; then - cicd_tools::err "Containerfile '$containerfile' does not exist or is not readable!" + cicd::err "Containerfile '$containerfile' does not exist or is not readable!" return 1 fi image_tag_params=('-t' "$default_image_name") - if ! cicd_tools::image_builder::is_change_request_context; then - for additional_tag in $(cicd_tools::image_builder::get_additional_tags); do + if ! cicd::image_builder::is_change_request_context; then + for additional_tag in $(cicd::image_builder::get_additional_tags); do image_tag_params+=('-t' "${image_name}:${additional_tag}") done fi - for label in $(cicd_tools::image_builder::get_labels); do + for label in $(cicd::image_builder::get_labels); do label_params+=('--label' "${label}") done - for build_arg in $(cicd_tools::image_builder::get_build_args); do + for build_arg in $(cicd::image_builder::get_build_args); do build_arg_params+=('--build-arg' "${build_arg}") done - if ! cicd_tools::container::cmd build -f "$containerfile" "${image_tag_params[@]}" \ + if ! cicd::container::cmd build -f "$containerfile" "${image_tag_params[@]}" \ "${build_arg_params[@]}" "${label_params[@]}" "$build_context"; then - cicd_tools::err "Error building image" + cicd::err "Error building image" return 1 fi } -cicd_tools::image_builder::get_containerfile() { +cicd::image_builder::get_containerfile() { local containerfile="${CICD_TOOLS_IMAGE_BUILDER_CONTAINERFILE_PATH:-"$CONTAINERFILE_PATH"}" @@ -79,7 +79,7 @@ cicd_tools::image_builder::get_containerfile() { echo -n "$containerfile" } -cicd_tools::image_builder::get_build_context() { +cicd::image_builder::get_build_context() { local build_context="${CICD_TOOLS_IMAGE_BUILDER_BUILD_CONTEXT:-"$BUILD_CONTEXT"}" @@ -90,29 +90,29 @@ cicd_tools::image_builder::get_build_context() { echo -n "$build_context" } -cicd_tools::image_builder::_get_image_name() { +cicd::image_builder::_get_image_name() { local image_name="${CICD_TOOLS_IMAGE_BUILDER_IMAGE_NAME:-$IMAGE_NAME}" if [ -z "$image_name" ]; then - cicd_tools::err "Image name not defined, please set IMAGE_NAME environment variable" + cicd::err "Image name not defined, please set IMAGE_NAME environment variable" return 1 fi echo -n "$image_name" } -cicd_tools::image_builder::get_image_tag() { +cicd::image_builder::get_image_tag() { local commit_hash build_id tag - if ! commit_hash=$(cicd_tools::common::get_7_chars_commit_hash); then - cicd_tools::err "Cannot retrieve commit hash!" + if ! commit_hash=$(cicd::common::get_7_chars_commit_hash); then + cicd::err "Cannot retrieve commit hash!" return 1 fi - if cicd_tools::image_builder::is_change_request_context; then - build_id=$(cicd_tools::image_builder::get_build_id) + if cicd::image_builder::is_change_request_context; then + build_id=$(cicd::image_builder::get_build_id) tag="pr-${build_id}-${commit_hash}" else tag="${commit_hash}" @@ -121,11 +121,11 @@ cicd_tools::image_builder::get_image_tag() { echo -n "${tag}" } -cicd_tools::image_builder::is_change_request_context() { +cicd::image_builder::is_change_request_context() { [ -n "$ghprbPullId" ] || [ -n "$gitlabMergeRequestId" ] } -cicd_tools::image_builder::get_build_id() { +cicd::image_builder::get_build_id() { local build_id @@ -138,159 +138,159 @@ cicd_tools::image_builder::get_build_id() { echo -n "$build_id" } -cicd_tools::image_builder::get_additional_tags() { +cicd::image_builder::get_additional_tags() { declare -a additional_tags=("${CICD_TOOLS_IMAGE_BUILDER_ADDITIONAL_TAGS[@]:-${ADDITIONAL_TAGS[@]}}") - if cicd_tools::image_builder::_array_empty "${additional_tags[@]}"; then + if cicd::image_builder::_array_empty "${additional_tags[@]}"; then additional_tags=() fi echo -n "${additional_tags[@]}" } -cicd_tools::image_builder::_array_empty() { +cicd::image_builder::_array_empty() { local arr=("$1") [[ "${#arr[@]}" -eq 1 && -z "${arr[0]}" ]] } -cicd_tools::image_builder::get_labels() { +cicd::image_builder::get_labels() { declare -a labels=("${CICD_TOOLS_IMAGE_BUILDER_LABELS[@]:-${LABELS[@]}}") - if cicd_tools::image_builder::_array_empty "${labels[@]}"; then + if cicd::image_builder::_array_empty "${labels[@]}"; then labels=() fi - if cicd_tools::image_builder::is_change_request_context; then - labels+=("$(cicd_tools::image_builder::_get_expiry_label)") + if cicd::image_builder::is_change_request_context; then + labels+=("$(cicd::image_builder::_get_expiry_label)") fi echo -n "${labels[@]}" } -cicd_tools::image_builder::_get_expiry_label() { +cicd::image_builder::_get_expiry_label() { echo "quay.expires-after=${CICD_TOOLS_IMAGE_BUILDER_QUAY_EXPIRE_TIME}" } -cicd_tools::image_builder::get_build_args() { +cicd::image_builder::get_build_args() { declare -a build_args=("${CICD_TOOLS_IMAGE_BUILDER_BUILD_ARGS[@]:-${BUILD_ARGS[@]}}") - if cicd_tools::image_builder::_array_empty "${build_args[@]}"; then + if cicd::image_builder::_array_empty "${build_args[@]}"; then build_args=() fi echo -n "${build_args[@]}" } -cicd_tools::image_builder::tag() { +cicd::image_builder::tag() { local source_image target_tag image_name - image_name="$(cicd_tools::image_builder::_get_image_name)" || return 1 - source_image="$(cicd_tools::image_builder::get_full_image_name)" || return 1 + image_name="$(cicd::image_builder::_get_image_name)" || return 1 + source_image="$(cicd::image_builder::get_full_image_name)" || return 1 - for target_tag in $(cicd_tools::image_builder::get_additional_tags); do - if ! cicd_tools::container::cmd tag "$source_image" "${image_name}:${target_tag}"; then - cicd_tools::err "Error tagging '$source_image' as '${image_name}:${target_tag}'" + for target_tag in $(cicd::image_builder::get_additional_tags); do + if ! cicd::container::cmd tag "$source_image" "${image_name}:${target_tag}"; then + cicd::err "Error tagging '$source_image' as '${image_name}:${target_tag}'" return 1 fi done } -cicd_tools::image_builder::push() { +cicd::image_builder::push() { local image_name image_tag - image_name="$(cicd_tools::image_builder::_get_image_name)" || return 1 - image_tag=$(cicd_tools::image_builder::get_image_tag) || return 1 + image_name="$(cicd::image_builder::_get_image_name)" || return 1 + image_tag=$(cicd::image_builder::get_image_tag) || return 1 image_tags=("$image_tag") - if ! cicd_tools::image_builder::is_change_request_context; then - for additional_tag in $(cicd_tools::image_builder::get_additional_tags); do + if ! cicd::image_builder::is_change_request_context; then + for additional_tag in $(cicd::image_builder::get_additional_tags); do image_tags+=("${additional_tag}") done fi for tag in "${image_tags[@]}"; do - if ! cicd_tools::container::cmd push "${image_name}:${tag}"; then - cicd_tools::err "Error pushing image: '${image_name}:${tag}'" + if ! cicd::container::cmd push "${image_name}:${tag}"; then + cicd::err "Error pushing image: '${image_name}:${tag}'" return 1 fi done } -cicd_tools::image_builder::get_full_image_name() { +cicd::image_builder::get_full_image_name() { local image_name image_tag - image_name="$(cicd_tools::image_builder::_get_image_name)" || return 1 - image_tag=$(cicd_tools::image_builder::get_image_tag) || return 1 + image_name="$(cicd::image_builder::_get_image_name)" || return 1 + image_tag=$(cicd::image_builder::get_image_tag) || return 1 echo -n "${image_name}:${image_tag}" } -cicd_tools::image_builder::_image_builder_setup() { +cicd::image_builder::_image_builder_setup() { - if ! cicd_tools::image_builder::_try_log_in_to_image_registries; then - cicd_tools::err "Error trying to log into the image registries!" + if ! cicd::image_builder::_try_log_in_to_image_registries; then + cicd::err "Error trying to log into the image registries!" return 1 fi } -cicd_tools::image_builder::_try_log_in_to_image_registries() { +cicd::image_builder::_try_log_in_to_image_registries() { - if cicd_tools::image_builder::_quay_credentials_found; then - if ! cicd_tools::image_builder::_log_in_to_quay_registry; then - cicd_tools::err "Error logging in to Quay.io!" + if cicd::image_builder::_quay_credentials_found; then + if ! cicd::image_builder::_log_in_to_quay_registry; then + cicd::err "Error logging in to Quay.io!" return 1 fi fi - if cicd_tools::image_builder::_redhat_registry_credentials_found; then - if ! cicd_tools::image_builder::_log_in_to_redhat_registry; then - cicd_tools::err "Error logging in to Red Hat Registry!" + if cicd::image_builder::_redhat_registry_credentials_found; then + if ! cicd::image_builder::_log_in_to_redhat_registry; then + cicd::err "Error logging in to Red Hat Registry!" return 1 fi fi } -cicd_tools::image_builder::_quay_credentials_found() { +cicd::image_builder::_quay_credentials_found() { [ -n "$CICD_TOOLS_IMAGE_BUILDER_QUAY_USER" ] && [ -n "$CICD_TOOLS_IMAGE_BUILDER_QUAY_PASSWORD" ] } -cicd_tools::image_builder::_log_in_to_quay_registry() { - cicd_tools::image_builder::_log_in_to_container_registry "$CICD_TOOLS_IMAGE_BUILDER_QUAY_USER" \ +cicd::image_builder::_log_in_to_quay_registry() { + cicd::image_builder::_log_in_to_container_registry "$CICD_TOOLS_IMAGE_BUILDER_QUAY_USER" \ "$CICD_TOOLS_IMAGE_BUILDER_QUAY_PASSWORD" \ "$CICD_TOOLS_IMAGE_BUILDER_QUAY_REGISTRY" } -cicd_tools::image_builder::_log_in_to_container_registry() { +cicd::image_builder::_log_in_to_container_registry() { local username="$1" local password="$2" local registry="$3" - cicd_tools::container::cmd login "-u=${username}" "--password-stdin" "$registry" <<< "$password" + cicd::container::cmd login "-u=${username}" "--password-stdin" "$registry" <<< "$password" } -cicd_tools::image_builder::_redhat_registry_credentials_found() { +cicd::image_builder::_redhat_registry_credentials_found() { [ -n "$CICD_TOOLS_IMAGE_BUILDER_REDHAT_USER" ] && [ -n "$CICD_TOOLS_IMAGE_BUILDER_REDHAT_PASSWORD" ] } -cicd_tools::image_builder::_log_in_to_redhat_registry() { - cicd_tools::image_builder::_log_in_to_container_registry "$CICD_TOOLS_IMAGE_BUILDER_REDHAT_USER" \ +cicd::image_builder::_log_in_to_redhat_registry() { + cicd::image_builder::_log_in_to_container_registry "$CICD_TOOLS_IMAGE_BUILDER_REDHAT_USER" \ "$CICD_TOOLS_IMAGE_BUILDER_REDHAT_PASSWORD" \ "$CICD_TOOLS_IMAGE_BUILDER_REDHAT_REGISTRY" } -if ! cicd_tools::image_builder::_image_builder_setup; then - cicd_tools::err "Image builder setup failed!" +if ! cicd::image_builder::_image_builder_setup; then + cicd::err "Image builder setup failed!" return 1 fi -cicd_tools::debug "Image builder lib loaded" +cicd::debug "Image builder lib loaded" CICD_TOOLS_IMAGE_BUILDER_LOADED=0 diff --git a/test/e2e/test_bootstrap_script_main.sh b/test/e2e/test_bootstrap_script_main.sh index 68b890d2..9a0a768c 100755 --- a/test/e2e/test_bootstrap_script_main.sh +++ b/test/e2e/test_bootstrap_script_main.sh @@ -17,12 +17,12 @@ load_cicd_helper_functions() { source <(curl -sSL "$CICD_TOOLS_URL") "$LIBRARY_TO_LOAD" # required to persist container preferrence - cicd_tools::container::cmd --version + cicd::container::cmd --version } load_cicd_helper_functions container -EXPECTED_OUTPUT=$(cicd_tools::container::cmd --version) +EXPECTED_OUTPUT=$(cicd::container::cmd --version) # Assert there's an actual output if ! [ "Docker version 99" == "$EXPECTED_OUTPUT" ]; then @@ -33,12 +33,12 @@ fi load_cicd_helper_functions # Assert output doesn't change -if ! [ "$(cicd_tools::container::cmd --version)" == "$EXPECTED_OUTPUT" ]; then +if ! [ "$(cicd::container::cmd --version)" == "$EXPECTED_OUTPUT" ]; then echo "Container command not preserved between runs!" exit 1 fi -if ! [ "$(cicd_tools::container::cmd --version)" == "$EXPECTED_OUTPUT" ]; then +if ! [ "$(cicd::container::cmd --version)" == "$EXPECTED_OUTPUT" ]; then echo "Container command not preserved between runs!" exit 1 fi diff --git a/test/e2e/test_e2e_load_library_from_bootstrap_script.sh b/test/e2e/test_e2e_load_library_from_bootstrap_script.sh index 74fd4acf..0f9c1592 100755 --- a/test/e2e/test_e2e_load_library_from_bootstrap_script.sh +++ b/test/e2e/test_e2e_load_library_from_bootstrap_script.sh @@ -29,12 +29,12 @@ load_cicd_helper_functions() { fi # required to persist container preferrence - cicd_tools::container::cmd --version + cicd::container::cmd --version } load_cicd_helper_functions container -EXPECTED_OUTPUT=$(cicd_tools::container::cmd --version) +EXPECTED_OUTPUT=$(cicd::container::cmd --version) # Assert there's an actual output if ! [ "Docker version 99" == "$EXPECTED_OUTPUT" ]; then @@ -45,12 +45,12 @@ fi load_cicd_helper_functions container # Assert output doesn't change -if ! [ "$(cicd_tools::container::cmd --version)" == "$EXPECTED_OUTPUT" ]; then +if ! [ "$(cicd::container::cmd --version)" == "$EXPECTED_OUTPUT" ]; then echo "Container command not preserved between runs!" exit 1 fi -if ! [ "$(cicd_tools::container::cmd --version)" == "$EXPECTED_OUTPUT" ]; then +if ! [ "$(cicd::container::cmd --version)" == "$EXPECTED_OUTPUT" ]; then echo "Container command not preserved between runs!" exit 1 fi diff --git a/test/e2e/test_e2e_load_library_from_function.sh b/test/e2e/test_e2e_load_library_from_function.sh index 41eceac4..0dfc0e05 100755 --- a/test/e2e/test_e2e_load_library_from_function.sh +++ b/test/e2e/test_e2e_load_library_from_function.sh @@ -16,11 +16,11 @@ load_common_helper_cicd_tools() { local LIBRARY_TO_LOAD=${1:-all} local MAIN_SCRIPT='./src/main.sh' source "$MAIN_SCRIPT" "$LIBRARY_TO_LOAD" - cicd_tools::container::cmd --version + cicd::container::cmd --version } load_common_helper_cicd_tools container -EXPECTED_OUTPUT=$(cicd_tools::container::cmd --version) +EXPECTED_OUTPUT=$(cicd::container::cmd --version) # Assert there's an actual output if ! [ "Docker version 99" == "$EXPECTED_OUTPUT" ]; then @@ -31,12 +31,12 @@ fi load_cicd_helper_functions # Assert output doesn't change -if ! [ "$(cicd_tools::container::cmd --version)" == "$EXPECTED_OUTPUT" ]; then +if ! [ "$(cicd::container::cmd --version)" == "$EXPECTED_OUTPUT" ]; then echo "Container command not preserved between runs!" exit 1 fi -if ! [ "$(cicd_tools::container::cmd --version)" == "$EXPECTED_OUTPUT" ]; then +if ! [ "$(cicd::container::cmd --version)" == "$EXPECTED_OUTPUT" ]; then echo "Container command not preserved between runs!" exit 1 fi diff --git a/test/e2e/test_e2e_load_library_locally.sh b/test/e2e/test_e2e_load_library_locally.sh index 7eff61ed..a05dc658 100755 --- a/test/e2e/test_e2e_load_library_locally.sh +++ b/test/e2e/test_e2e_load_library_locally.sh @@ -15,9 +15,9 @@ MAIN_SCRIPT='./src/main.sh' source "$MAIN_SCRIPT" "$LIBRARY_TO_LOAD" -cicd_tools::container::cmd --version >/dev/null +cicd::container::cmd --version >/dev/null -EXPECTED_OUTPUT=$(cicd_tools::container::cmd --version) +EXPECTED_OUTPUT=$(cicd::container::cmd --version) # Assert there's an actual output if ! [ "Docker version 99" == "$EXPECTED_OUTPUT" ]; then @@ -28,12 +28,12 @@ fi load_cicd_helper_functions # Assert output doesn't change -if ! [ "$(cicd_tools::container::cmd --version)" == "$EXPECTED_OUTPUT" ]; then +if ! [ "$(cicd::container::cmd --version)" == "$EXPECTED_OUTPUT" ]; then echo "Container command not preserved between runs!" exit 1 fi -if ! [ "$(cicd_tools::container::cmd --version)" == "$EXPECTED_OUTPUT" ]; then +if ! [ "$(cicd::container::cmd --version)" == "$EXPECTED_OUTPUT" ]; then echo "Container command not preserved between runs!" exit 1 fi diff --git a/test/e2e/test_image_builder.sh b/test/e2e/test_image_builder.sh index e162204f..fa434702 100755 --- a/test/e2e/test_image_builder.sh +++ b/test/e2e/test_image_builder.sh @@ -15,7 +15,7 @@ MAIN_SCRIPT='./src/main.sh' source "$MAIN_SCRIPT" "image_builder" -EXPECTED_OUTPUT=$(cicd_tools::image_builder::build_and_push) +EXPECTED_OUTPUT=$(cicd::image_builder::build_and_push) if ! [ "build -f ${CICD_TOOLS_IMAGE_BUILDER_CONTAINER_FILE} -t ${IMAGE_REPOSITORY}:abcdef1 ." = "$EXPECTED_OUTPUT" ]; then echo "Build and Push script not working!" @@ -25,4 +25,4 @@ fi unset podman -cicd_tools::image_builder::build_and_push +cicd::image_builder::build_and_push diff --git a/test/main.bats b/test/main.bats index 82bb720f..30f20a22 100644 --- a/test/main.bats +++ b/test/main.bats @@ -35,14 +35,14 @@ setup() { podman() { echo "podman here" } - run ! cicd_tools::container::cmd + run ! cicd::container::cmd assert_failure CICD_TOOLS_DEBUG=1 run source main.sh container assert_success assert_output --partial "loading container lib" source main.sh container - run cicd_tools::container::cmd + run cicd::container::cmd assert_success assert_output --partial "podman here" } diff --git a/test/shared_common_lib.bats b/test/shared_common_lib.bats index 92ba517d..45e97c92 100644 --- a/test/shared_common_lib.bats +++ b/test/shared_common_lib.bats @@ -36,10 +36,10 @@ setup() { } source main.sh common - run ! cicd_tools::common::command_is_present foo + run ! cicd::common::command_is_present foo assert_failure - run cicd_tools::common::command_is_present cat + run cicd::common::command_is_present cat assert_success assert_output "" } @@ -47,7 +47,7 @@ setup() { @test "get_7_chars_commit_hash works" { source main.sh common - run cicd_tools::common::get_7_chars_commit_hash + run cicd::common::get_7_chars_commit_hash assert_success assert_output --regexp '^[0-9a-f]{7}$' } @@ -59,18 +59,18 @@ setup() { assert [ -z "$LOCAL_BUILD" ] assert [ -z "$CI" ] source src/main.sh common - run cicd_tools::common::local_build + run cicd::common::local_build assert_success CI='true' - run cicd_tools::common::local_build + run cicd::common::local_build assert_failure assert_output "" LOCAL_BUILD='true' - run cicd_tools::common::local_build + run cicd::common::local_build assert_output "" assert_success unset LOCAL_BUILD - run ! cicd_tools::common::local_build + run ! cicd::common::local_build assert_output "" assert_failure } @@ -82,12 +82,12 @@ setup() { unset CI assert [ -z "$CI" ] - run cicd_tools::common::is_ci_context + run cicd::common::is_ci_context assert_failure assert_output "" export CI='true' - run cicd_tools::common::is_ci_context + run cicd::common::is_ci_context assert_success assert_output "" } diff --git a/test/shared_container_lib.bats b/test/shared_container_lib.bats index a84410d9..bce10902 100644 --- a/test/shared_container_lib.bats +++ b/test/shared_container_lib.bats @@ -41,21 +41,21 @@ setup() { PREFER_CONTAINER_ENGINE="docker" - run ! cicd_tools::container::cmd + run ! cicd::container::cmd assert_failure - assert_output --partial "cicd_tools::container::cmd: command not found" + assert_output --partial "cicd::container::cmd: command not found" source src/main.sh container - cicd_tools::container::cmd --version - run cicd_tools::container::cmd --version + cicd::container::cmd --version + run cicd::container::cmd --version assert_success assert_output "docker version 1" unset PREFER_container source main.sh container - run cicd_tools::container::cmd --version + run cicd::container::cmd --version assert_success assert_output "docker version 1" } @@ -69,22 +69,22 @@ setup() { echo "podman version 1" } - run ! cicd_tools::container::cmd + run ! cicd::container::cmd assert_failure - assert_output --partial "cicd_tools::container::cmd: command not found" + assert_output --partial "cicd::container::cmd: command not found" source src/main.sh container - cicd_tools::container::cmd --version + cicd::container::cmd --version PREFER_CONTAINER_ENGINE="docker" - run cicd_tools::container::cmd --version + run cicd::container::cmd --version assert_success assert_output "podman version 1" source main.sh container - run cicd_tools::container::cmd --version + run cicd::container::cmd --version assert_success assert_output "podman version 1" } @@ -96,7 +96,7 @@ setup() { } source main.sh container - run cicd_tools::container::cmd --version + run cicd::container::cmd --version assert_output --partial "podman version 1" } @@ -113,7 +113,7 @@ setup() { } source main.sh container - run cicd_tools::container::cmd --version + run cicd::container::cmd --version assert_output --regexp "WARNING.*docker.*seems emulated" assert_output --partial "podman version 1" } @@ -123,7 +123,7 @@ setup() { source main.sh container OLDPATH="$PATH" PATH=':' - run ! cicd_tools::container::cmd --version + run ! cicd::container::cmd --version PATH="$OLDPATH" assert_failure assert_output --partial "ERROR, no container engine found" @@ -141,7 +141,7 @@ setup() { OLDPATH="$PATH" PATH=':' - run cicd_tools::container::cmd --version + run cicd::container::cmd --version PATH="$OLDPATH" assert_output --regexp "WARNING.*podman.*not present" assert_output --partial "docker version 1" @@ -161,7 +161,7 @@ setup() { OLDPATH="$PATH" PATH=':' - run cicd_tools::container::cmd --version + run cicd::container::cmd --version PATH="$OLDPATH" assert [ $status -eq 1 ] assert_output --regexp "WARNING.*docker seems emulated" @@ -179,7 +179,7 @@ setup() { } source main.sh container - run cicd_tools::container::cmd --version + run cicd::container::cmd --version assert_success assert_output --partial "podman version 1" } @@ -195,7 +195,7 @@ setup() { echo 'docker version 1' } source main.sh container - run cicd_tools::container::cmd --version + run cicd::container::cmd --version assert_success assert_output --partial "docker version 1" } @@ -212,7 +212,7 @@ setup() { echo 'podman version 1' } source main.sh container - run cicd_tools::container::cmd --version + run cicd::container::cmd --version assert_success assert_output --regexp "WARNING.*'cat'.*isn't supported" assert_output --partial "podman version 1" diff --git a/test/shared_image_builder_lib.bats b/test/shared_image_builder_lib.bats index cdfd00d3..e8736d55 100644 --- a/test/shared_image_builder_lib.bats +++ b/test/shared_image_builder_lib.bats @@ -38,7 +38,7 @@ setup() { } source main.sh image_builder - run cicd_tools::image_builder::get_image_tag + run cicd::image_builder::get_image_tag assert_success assert_output '1abcdef' } @@ -53,7 +53,7 @@ setup() { ghprbPullId=123 source main.sh image_builder - run cicd_tools::image_builder::get_image_tag + run cicd::image_builder::get_image_tag assert_success assert_output 'pr-123-1abcdef' @@ -70,7 +70,7 @@ setup() { source main.sh image_builder - run cicd_tools::image_builder::get_image_tag + run cicd::image_builder::get_image_tag assert_success assert_output 'pr-4321-1abcdef' @@ -95,7 +95,7 @@ setup() { IMAGE_NAME='quay.io/foo/bar' refute [ -r "$EXPECTED_CONTAINERFILE_PATH" ] - run ! cicd_tools::image_builder::build + run ! cicd::image_builder::build assert_failure assert_output --regexp "$EXPECTED_CONTAINERFILE_PATH.*does not exist" refute_output --regexp "build" @@ -115,7 +115,7 @@ setup() { source main.sh image_builder - run ! cicd_tools::image_builder::build + run ! cicd::image_builder::build assert_failure assert_output --partial "Image name not defined" refute_output --partial "build" @@ -136,7 +136,7 @@ setup() { IMAGE_NAME='quay.io/foo/bar' source main.sh image_builder - run ! cicd_tools::image_builder::build + run ! cicd::image_builder::build assert_failure assert_output --partial "Cannot retrieve commit hash" refute_output --partial "build" @@ -160,7 +160,7 @@ setup() { IMAGE_NAME='quay.io/foo/bar' touch "${EXPECTED_CONTAINERFILE_PATH}" - run cicd_tools::image_builder::build + run cicd::image_builder::build rm "${EXPECTED_CONTAINERFILE_PATH}" assert_success @@ -191,7 +191,7 @@ setup() { CICD_TOOLS_IMAGE_BUILDER_BUILD_CONTEXT='another/context' CICD_TOOLS_IMAGE_BUILDER_CONTAINERFILE_PATH='test/data/Containerfile.test' - run cicd_tools::image_builder::build + run cicd::image_builder::build assert_success assert_output --regexp "^build.*" @@ -225,7 +225,7 @@ setup() { IMAGE_NAME="someimage" CONTAINERFILE_PATH='test/data/Containerfile.test' - run cicd_tools::image_builder::build + run cicd::image_builder::build assert_success assert_output --partial "-t someimage:pr-123-1abcdef" @@ -250,7 +250,7 @@ setup() { IMAGE_NAME="someimage" CONTAINERFILE_PATH='test/data/Containerfile.test' - run cicd_tools::image_builder::build + run cicd::image_builder::build assert_failure assert_output --partial "went really wrong" @@ -330,13 +330,13 @@ setup() { IMAGE_NAME="someimage" ADDITIONAL_TAGS=("foo" "bar" "baz") - run cicd_tools::image_builder::get_image_tag + run cicd::image_builder::get_image_tag assert_success assert_output "1abcdef" - run cicd_tools::image_builder::get_additional_tags + run cicd::image_builder::get_additional_tags assert_success assert_output "foo bar baz" @@ -358,7 +358,7 @@ setup() { IMAGE_NAME="someimage" ADDITIONAL_TAGS=("target1" "target2" "target3") - run cicd_tools::image_builder::tag + run cicd::image_builder::tag assert_success refute_output --partial "tag someimage:source someimage:source" @@ -384,7 +384,7 @@ setup() { IMAGE_NAME="someimage" ADDITIONAL_TAGS=("target1") - run ! cicd_tools::image_builder::tag + run ! cicd::image_builder::tag assert_failure assert_output --partial "tag someimage:source someimage:target1" @@ -407,7 +407,7 @@ setup() { IMAGE_NAME="someimage" ADDITIONAL_TAGS=("tag1" "tag2") - run cicd_tools::image_builder::push + run cicd::image_builder::push assert_success assert_output --partial "push someimage:abcdef1" @@ -432,7 +432,7 @@ setup() { ghprbPullId="123" ADDITIONAL_TAGS=("tag1" "tag2") - run cicd_tools::image_builder::push + run cicd::image_builder::push assert_success assert_output --partial "push someimage:pr-123-abcdef1" @@ -457,7 +457,7 @@ setup() { IMAGE_NAME="someimage" ADDITIONAL_TAGS=("target1") - run ! cicd_tools::image_builder::push + run ! cicd::image_builder::push assert_failure assert_output --partial "push someimage:source" @@ -481,7 +481,7 @@ setup() { ADDITIONAL_TAGS=("target1") CONTAINERFILE_PATH='test/data/Containerfile.test' - run cicd_tools::image_builder::build_and_push + run cicd::image_builder::build_and_push assert_success assert_output --regexp "^build.*?-t someimage:source -t someimage:target1" @@ -506,7 +506,7 @@ setup() { ADDITIONAL_TAGS=("target1") CONTAINERFILE_PATH='test/data/Containerfile.test' - run cicd_tools::image_builder::build_and_push + run cicd::image_builder::build_and_push assert_success assert_output --regexp "^build.*?-t someimage:pr-123-source" From 59fe7b07c15a80f3668dde4e43e4019428693fa1 Mon Sep 17 00:00:00 2001 From: Victor M Date: Thu, 28 Sep 2023 13:02:05 +0200 Subject: [PATCH 35/39] Clarify usage of main and bootstrap scripts --- README.md | 56 +++++++++++++++++++++++++++++++++++++++++++++---------- 1 file changed, 46 insertions(+), 10 deletions(-) diff --git a/README.md b/README.md index 78db5161..cc3c607b 100644 --- a/README.md +++ b/README.md @@ -40,8 +40,35 @@ Currently, there are 2 supported libraries: ### How to use the helper libraries -To use any of the provided libraries, you must source the [src/bootstrap.sh](bootstrap.sh) script -and pass the unique library ID to be loaded as a paramter. +This library is intended to be used to gather the most common shell scripts used in pipelines in a +centralized way. This should be helpful to reduce the amount of code needed to write the most common +operations in a pipeline for routine tasks, such as operating with containers or building container +images. + +The [src/main.sh](main.sh) script is the main entrypoint and should be used to load the modules +included in this library. This script requires all the other scripts available in a local directory +following the same structure in this repository. + +To use any of the provided libraries, you must source the [src/main.sh](main.sh) script +and pass the unique library ID to be loaded as a parameter. + +There's two different approaches for loading these scripts, depending on if you're a contributor or +an end user. + +#### Contributing to the repository + +This is the intended way when developing new modules for this library. The recommended approach for +contributing is to create a new fork and then open a pull request against the `main` branch. + +When working with a local copy of the repository, you should source the [src/main.sh](main.sh) +script directly. + +#### Using the library from other scripts + +There is an existing helper script named [src/bootstrap.sh](bootstrap) to help with sourcing the +[src/main.sh](main.sh) script if you're not contributing to this repo. + +**This is the intended way of using this library from external projects**. One can simply either source the [src/bootstrap.sh](bootstrap) script directly: @@ -53,7 +80,11 @@ $ cicd::container::cmd --version ``` -In case you want to refactor some of your scripts using this library, here's a snippet you can use: +Or choose to be more specific and select a specific repository and branch name (useful for working +with forks and testing new WIP features) + +The following is a snippet you can use to place on top of a script to load the helper module you +need: ``` load_cicd_helper_functions() { @@ -82,9 +113,12 @@ to `.cicd_tools` in the current directory). be deleted! You can disable running the `git clone` by setting the `CICD_TOOLS_SKIP_GIT_CLONE` variable -The bootstrap.sh can be invoked multiple times but it has a status control to ensure each -of the libraries is loaded only once. This is to prevent potential issues with collections -that are not supposed to be loaded many times. +After loading the requested module the `CICD_TOOLS_WORKDIR` directory will be automatically removed +by the [src/bootstrap.sh](bootstrap) script. + +the [src/bootstrap.sh](bootstrap) script can be invoked multiple times, but it has a status control +to ensure each of the libraries is loaded only once. This is to prevent potential issues with +collections that are not supposed to be loaded many times. An example of this is the _container_ library, where the selected container engine is **set only once the first command using the library helper function `cicd::container::cmd` @@ -93,8 +127,10 @@ is used**. Each of the libraries will export their functions and variables to the shell when sourcing the bootstrap script the helper functions. -This library follows [Google's Shell style guide](https://google.github.io/styleguide/shellguide.html), -so the functions are all namespaced, meaning the names follow the naming format: +This library +follows [Google's Shell style guide](https://google.github.io/styleguide/shellguide.html), and the +functions are all namespaced to its corresponding module, meaning the names follow the naming +format: ``` cicd::library::function @@ -102,8 +138,8 @@ cicd::library::function where: -- cicd_tools represents the namespace root, which is shared by all functions -- library would match with each of the imported library IDs. +- *cicd* represents the namespace root, which is shared by all functions +- *library* would match with each of the imported library IDs. ## Template Scripts From a2d833f3268ce9de4e4ef8b97199d3f8106096bf Mon Sep 17 00:00:00 2001 From: Victor M Date: Thu, 28 Sep 2023 14:14:37 +0200 Subject: [PATCH 36/39] refactor build --- src/shared/image_builder_lib.sh | 16 +++++++++------- 1 file changed, 9 insertions(+), 7 deletions(-) diff --git a/src/shared/image_builder_lib.sh b/src/shared/image_builder_lib.sh index 9c0cacbd..ff554a73 100644 --- a/src/shared/image_builder_lib.sh +++ b/src/shared/image_builder_lib.sh @@ -33,7 +33,7 @@ cicd::image_builder::build_and_push() { cicd::image_builder::build() { local containerfile build_context image_name image_tags default_image_name - declare -a label_params image_tag_params build_arg_params + declare -a build_params containerfile="$(cicd::image_builder::get_containerfile)" build_context="$(cicd::image_builder::get_build_context)" @@ -45,24 +45,26 @@ cicd::image_builder::build() { return 1 fi - image_tag_params=('-t' "$default_image_name") + build_params=("-f" "$containerfile") + build_params+=('-t' "$default_image_name") if ! cicd::image_builder::is_change_request_context; then for additional_tag in $(cicd::image_builder::get_additional_tags); do - image_tag_params+=('-t' "${image_name}:${additional_tag}") + build_params+=('-t' "${image_name}:${additional_tag}") done fi for label in $(cicd::image_builder::get_labels); do - label_params+=('--label' "${label}") + build_params+=('--label' "${label}") done for build_arg in $(cicd::image_builder::get_build_args); do - build_arg_params+=('--build-arg' "${build_arg}") + build_params+=('--build-arg' "${build_arg}") done - if ! cicd::container::cmd build -f "$containerfile" "${image_tag_params[@]}" \ - "${build_arg_params[@]}" "${label_params[@]}" "$build_context"; then + build_params+=("$build_context") + + if ! cicd::container::cmd build "${build_params[@]}"; then cicd::err "Error building image" return 1 fi From 94d1504f17ba0882826ce1403bfdb97c92971d11 Mon Sep 17 00:00:00 2001 From: Victor M Date: Thu, 28 Sep 2023 15:10:55 +0200 Subject: [PATCH 37/39] Force new container registry credentials on CI context --- src/shared/image_builder_lib.sh | 8 +++++++- test/shared_image_builder_lib.bats | 22 ++++++++++++++++++++-- 2 files changed, 27 insertions(+), 3 deletions(-) diff --git a/src/shared/image_builder_lib.sh b/src/shared/image_builder_lib.sh index ff554a73..5283a422 100644 --- a/src/shared/image_builder_lib.sh +++ b/src/shared/image_builder_lib.sh @@ -25,7 +25,7 @@ readonly CICD_TOOLS_IMAGE_BUILDER_DEFAULT_CONTAINERFILE_PATH='Dockerfile' cicd::image_builder::build_and_push() { cicd::image_builder::build || return 1 - if cicd::image_builder::is_change_request_context; then + if ! cicd::common::local_build; then cicd::image_builder::push || return 1 fi } @@ -242,6 +242,12 @@ cicd::image_builder::_image_builder_setup() { cicd::image_builder::_try_log_in_to_image_registries() { + if cicd::common::is_ci_context; then + DOCKER_CONFIG="$(mktemp -d)" + export DOCKER_CONFIG + echo -n '{}' > "${DOCKER_CONFIG}/config.json" + fi + if cicd::image_builder::_quay_credentials_found; then if ! cicd::image_builder::_log_in_to_quay_registry; then cicd::err "Error logging in to Quay.io!" diff --git a/test/shared_image_builder_lib.bats b/test/shared_image_builder_lib.bats index e8736d55..9cd11cde 100644 --- a/test/shared_image_builder_lib.bats +++ b/test/shared_image_builder_lib.bats @@ -512,6 +512,24 @@ setup() { assert_output --regexp "^build.*?-t someimage:pr-123-source" refute_output --regexp "^build.*?-t someimage:target1" assert_output --regexp "^build.*?--label quay.expires-after" - assert_output --partial "push someimage:pr-123-source" - refute_output --partial "push someimage:target1" + assert_output --regexp "^build.*?-t someimage:pr-123-source" + refute_output --regexp "^build.*?-t someimage:target1" +} + +@test "Image build setup does not forces fresh DOCKER_CONF if not in CI context" { + + assert [ -z "$DOCKER_CONFIG" ] + source main.sh image_builder + assert [ -z "$DOCKER_CONFIG" ] } + +@test "build on CI forces fresh DOCKER_CONF creds in CI context" { + + CI="true" + + assert [ -z "$DOCKER_CONFIG" ] + source main.sh image_builder + assert [ -n "$DOCKER_CONFIG" ] + assert [ -w "${DOCKER_CONFIG}/config.json" ] + +} \ No newline at end of file From 75308eef0004014aceee8c227bb9a88d99820ef7 Mon Sep 17 00:00:00 2001 From: Victor M Date: Thu, 28 Sep 2023 15:20:02 +0200 Subject: [PATCH 38/39] use local_build as condition --- src/shared/image_builder_lib.sh | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/shared/image_builder_lib.sh b/src/shared/image_builder_lib.sh index 5283a422..41737d7f 100644 --- a/src/shared/image_builder_lib.sh +++ b/src/shared/image_builder_lib.sh @@ -242,7 +242,7 @@ cicd::image_builder::_image_builder_setup() { cicd::image_builder::_try_log_in_to_image_registries() { - if cicd::common::is_ci_context; then + if ! cicd::common::local_build; then DOCKER_CONFIG="$(mktemp -d)" export DOCKER_CONFIG echo -n '{}' > "${DOCKER_CONFIG}/config.json" From 8d5dc07e788693786a08a08c3661aea8538b555c Mon Sep 17 00:00:00 2001 From: Victor M Date: Thu, 28 Sep 2023 15:26:58 +0200 Subject: [PATCH 39/39] Fix tests for local builds --- test/shared_image_builder_lib.bats | 43 +++++++++++++++++++++++++++--- 1 file changed, 39 insertions(+), 4 deletions(-) diff --git a/test/shared_image_builder_lib.bats b/test/shared_image_builder_lib.bats index 9cd11cde..38f84806 100644 --- a/test/shared_image_builder_lib.bats +++ b/test/shared_image_builder_lib.bats @@ -464,7 +464,7 @@ setup() { assert_output --partial "Error pushing image" } -@test "build deploy does not push if not on change request context" { +@test "build and push does not push if not on local build context" { # git mock git() { @@ -475,6 +475,10 @@ setup() { echo "$@" } + if [ -n "$CI" ]; then + unset CI + fi + source main.sh image_builder IMAGE_NAME="someimage" @@ -488,6 +492,35 @@ setup() { refute_output --partial "push" } +@test "build and push pushes if not on local build context" { + + # git mock + git() { + echo "source" + } + # podman mock + podman() { + echo "$@" + } + + if [ -n "CI" ]; then + CI="true" + fi + + source main.sh image_builder + + IMAGE_NAME="someimage" + ADDITIONAL_TAGS=("target1") + CONTAINERFILE_PATH='test/data/Containerfile.test' + + run cicd::image_builder::build_and_push + + assert_success + assert_output --regexp "^build.*?-t someimage:source -t someimage:target1" + assert_output --partial "push" +} + + @test "build_and_push pushes only default tag if on change request context" { # git mock @@ -516,9 +549,11 @@ setup() { refute_output --regexp "^build.*?-t someimage:target1" } -@test "Image build setup does not forces fresh DOCKER_CONF if not in CI context" { +@test "Image build setup doesn't force fresh DOCKER_CONF if not in CI context" { + + unset DOCKER_CONFIG + unset CI - assert [ -z "$DOCKER_CONFIG" ] source main.sh image_builder assert [ -z "$DOCKER_CONFIG" ] } @@ -526,8 +561,8 @@ setup() { @test "build on CI forces fresh DOCKER_CONF creds in CI context" { CI="true" + unset DOCKER_CONFIG - assert [ -z "$DOCKER_CONFIG" ] source main.sh image_builder assert [ -n "$DOCKER_CONFIG" ] assert [ -w "${DOCKER_CONFIG}/config.json" ]