github.com/opensuse/umoci@v0.4.2/test/helpers.bash (about) 1 #!/bin/bash 2 # umoci: Umoci Modifies Open Containers' Images 3 # Copyright (C) 2016, 2017, 2018 SUSE LLC. 4 # 5 # Licensed under the Apache License, Version 2.0 (the "License"); 6 # you may not use this file except in compliance with the License. 7 # You may obtain a copy of the License at 8 # 9 # http://www.apache.org/licenses/LICENSE-2.0 10 # 11 # Unless required by applicable law or agreed to in writing, software 12 # distributed under the License is distributed on an "AS IS" BASIS, 13 # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 14 # See the License for the specific language governing permissions and 15 # limitations under the License. 16 17 # Root directory of integration tests. 18 INTEGRATION_ROOT=$(dirname "$(readlink -f "$BASH_SOURCE")") 19 UMOCI="${UMOCI:-${INTEGRATION_ROOT}/../umoci}" 20 GOMTREE="/usr/bin/gomtree" # For some reason $(whence ...) and $(where ...) are broken. 21 22 # The source OCI image path, which we will make a copy of for each test. 23 SOURCE_IMAGE="${SOURCE_IMAGE:-/image}" 24 SOURCE_TAG="${SOURCE_TAG:-latest}" 25 26 # Where we're going to copy the images and bundle to. 27 IMAGE="${BATS_TMPDIR}/image" 28 TAG="${SOURCE_TAG}" 29 30 # We need to store the coverage outputs somewhere. 31 COVERAGE_DIR="${COVERAGE_DIR:-}" 32 33 # Are we rootless? 34 ROOTLESS="$(id -u)" 35 36 # Allows a test to specify what things it requires. If the environment can't 37 # support it, the test is skipped with a message. 38 function requires() { 39 for var in "$@"; do 40 case $var in 41 root) 42 if [ "$ROOTLESS" -ne 0 ]; then 43 skip "test requires ${var}" 44 fi 45 ;; 46 *) 47 fail "BUG: Invalid requires ${var}." 48 ;; 49 esac 50 done 51 } 52 53 function image-verify() { 54 oci-image-tool validate --type "imageLayout" "$@" 55 return $? 56 } 57 58 function bundle-verify() { 59 args=() 60 61 for arg in "$@"; do 62 args+=( --path="$arg" ) 63 done 64 65 oci-runtime-tool validate "${args[@]}" 66 return $? 67 } 68 69 function umoci() { 70 local args=() 71 if [[ "$COVER" == 1 ]]; then 72 if [ "$COVERAGE_DIR" ]; then 73 args+=("-test.coverprofile=$(mktemp -p "$COVERAGE_DIR" umoci.cov.XXXXXX)") 74 fi 75 args+=("__DEVEL--i-heard-you-like-tests") 76 fi 77 78 if [[ "$1" == "raw" ]]; then 79 args+=("$1") 80 shift 1 81 fi 82 83 # Set the first argument (the subcommand). 84 args+=("$1") 85 86 # We're rootless if we're asked to unpack something. 87 if [[ "$ROOTLESS" != 0 && "$1" == "unpack" ]]; then 88 args+=("--rootless") 89 fi 90 91 shift 92 args+=("$@") 93 sane_run "$UMOCI" "${args[@]}" 94 95 if [[ "$COVER" == 1 ]]; then 96 # Because this is running as a -test.cover test, we need to remove the last 97 # two lines. 98 if [ "$status" -eq 0 ]; then 99 export output="$(echo "$output" | head -n-2)" 100 unset 'lines[${#lines[@]}-1]' 101 unset 'lines[${#lines[@]}-1]' 102 fi 103 fi 104 } 105 106 function gomtree() { 107 local args=("$@") 108 109 # We're rootless. Note that this is _not_ available in the upstream 110 # version of go-mtree and is unlikely to be accepted there (see 111 # https://github.com/vbatts/go-mtree/pull/96). 112 # It's maintained instead as an openSUSE extension: 113 # https://build.opensuse.org/package/view_file/Virtualization:containers/go-mtree/0001-gomtree-add-rootless-flag.patch?expand=1 114 if [[ "$ROOTLESS" != 0 ]]; then 115 args+=("-rootless") 116 fi 117 118 sane_run "$GOMTREE" -K sha256digest "${args[@]}" 119 } 120 121 function sane_run() { 122 local cmd="$1" 123 shift 124 125 run "$cmd" "$@" 126 127 # Some debug information to make life easier. 128 echo "$(basename "$cmd") $@ (status=$status)" >&2 129 echo "$output" >&2 130 } 131 132 function setup_image() { 133 cp -r "${SOURCE_IMAGE}" "${IMAGE}" 134 df >/dev/stderr 135 du -h -d 2 "$BATS_TMPDIR" >/dev/stderr 136 image-verify "${IMAGE}" 137 } 138 139 function teardown_image() { 140 rm -rf "${IMAGE}" 141 } 142 143 # Stores the set of tmpdirs that still have to be cleaned up. Calling 144 # teardown_tmpdirs will set this to an empty array (and all the tmpdirs 145 # contained within are removed). 146 export TESTDIR_LIST="$(mktemp --tmpdir="$BATS_TMPDIR" umoci-integration-tmpdirs.XXXXXX)" 147 148 # setup_tmpdir creates a new temporary directory and returns its name. Note 149 # that if "$ROOTLESS" is true, then removing this tmpdir might be harder than 150 # expected -- so tests should not really attempt to clean up tmpdirs. 151 function setup_tmpdir() { 152 mktemp -d --tmpdir="$BATS_TMPDIR" umoci-integration-tmpdir.XXXXXXXX | tee -a "$TESTDIR_LIST" 153 } 154 155 # teardown_tmpdirs removes all tmpdirs created with setup_tmpdir. 156 function teardown_tmpdirs() { 157 # Do nothing if TESTDIR_LIST doesn't exist. 158 [ -e "$TESTDIR_LIST" ] || return 159 160 # Remove all of the tmpdirs. 161 while read tmpdir; do 162 [ -e "$tmpdir" ] || continue 163 chmod -R 0777 "$tmpdir" 164 rm -rf "$tmpdir" 165 done < "$TESTDIR_LIST" 166 167 # Clear tmpdir list. 168 rm -f "$TESTDIR_LIST" 169 } 170 171 # Generate a new $BUNDLE and $ROOTFS combination. 172 function new_bundle_rootfs() { 173 declare -g BUNDLE="$(setup_tmpdir)" 174 declare -g ROOTFS="$BUNDLE/rootfs" 175 } 176 177 # _getfattr is a sane wrapper around getfattr(1) which only extracts the value 178 # of the requested xattr (and removes any of the other crap that it spits out). 179 # The usage is "sane_getfattr <xattr name> <path>" and outputs the hex 180 # representation in a single line. Exit status is non-zero if the xattr isn't 181 # set. 182 function _getfattr() { 183 # We only support single-file inputs. 184 [ "$#" -eq 2 ] || return 1 185 186 local xattr="$1" 187 local path="$2" 188 189 # Run getfattr. 190 ( 191 set -o pipefail 192 getfattr -e hex -n "$xattr" "$path" 2>/dev/null \ 193 | grep "^$xattr=" | sed "s|^$xattr=||g" 194 ) 195 return $? 196 }