Merge pull request #1306 from flatcar/krnowak/mount-in-sdk

run_sdk_container: Clean up a bit and add mounting of custom volumes
This commit is contained in:
Krzesimir Nowak 2023-11-02 14:36:05 +01:00 committed by GitHub
commit def3c9649e
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
2 changed files with 98 additions and 75 deletions

View File

@ -12,89 +12,93 @@ source sdk_lib/sdk_container_common.sh
arch="all" arch="all"
name="" name=""
os_version="$(get_git_version)" os_version=$(get_git_version)
sdk_version="$(get_sdk_version_from_versionfile)" sdk_version=$(get_sdk_version_from_versionfile)
custom_image="" custom_image=""
tty="" tty=()
remove="" remove=""
cleanup="" cleanup=""
mounts=()
usage() { usage() {
echo " Usage:" echo " Usage:"
echo " $0 [-t] [-v <version>] [-V sdk version] [-a arch] [-n <name> ] [-x <script>] [-C custom-container] [--rm] [container-command]" echo " $0 [-t] [-v <version>] [-V <SDK version>] [-a <amd64|arm64|all>] [-n <name> ] [-x <script>] [-C <custom-container>] [--rm] [-U] [-m <src>:<dest>] [<container-command>]"
echo " Start an SDK container of a given SDK release version." echo " Start an SDK container of a given SDK release version."
echo " This will create the container if it does not exist, otherwise start the existing container." echo " This will create the container if it does not exist, otherwise start the existing container."
echo " If the container is already running then it will exec into the container." echo " If the container is already running then it will exec into the container."
echo echo
echo " container-command - command to be run in the container instead of" echo " <container-command> - Command to be run in the container instead of"
echo " an interactive shell." echo " an interactive shell."
echo " -t Attach docker to a TTY (docker -t)" echo " -t Attach docker to a TTY (docker -t)."
echo " -v <version> - Sourcetree (OS image) version to use." echo " -v <version> - Sourcetree (OS image) version to use."
echo " Defaults to '$os_version' (current git commit)." echo " Defaults to '$os_version' (current git commit)."
echo " FLATCAR_VERSION[_ID] in '$sdk_container_common_versionfile'" echo " FLATCAR_VERSION[_ID] in '$sdk_container_common_versionfile'"
echo " will be updated accordingly." echo " will be updated accordingly."
echo " -V <SDK ver> - SDK version to use. Defaults to '${sdk_version}'" echo " -V <SDK version> - SDK version to use. Defaults to '${sdk_version}'"
echo " (FLATCAR_SDK_VERSION from '$sdk_container_common_versionfile')." echo " (FLATCAR_SDK_VERSION from '$sdk_container_common_versionfile')."
echo " -a <amd64|arm64|all> - Target architecture (board support) of the SDK." echo " -a <amd64|arm64|all> - Target architecture (board support) of the SDK."
echo " 'all' (the default) contains support for both amd64 and arm64." echo " 'all' (the default) contains support for both amd64 and arm64."
echo " -n <name> - Custom name to use for the container." echo " -n <name> - Custom name to use for the container."
echo " --rm Remove container afterwards" echo " --rm Remove container afterwards."
echo " -x <script> - For each resource generated during build (container etc.)" echo " -x <script> - For each resource generated during build (container etc.)"
echo " add a cleanup line to <script> which, when run, will free" echo " add a cleanup line to <script> which, when run, will free"
echo " the resource. Useful for CI." echo " the resource. Useful for CI."
echo " -C - Use an entirely custom container image instead of the SDK's" echo " -C <custom-container> - Use an entirely custom container image instead of the SDK's"
echo " $sdk_container_common_registry/flatcar-sdk-[ARCH]:[SDK VERSION]" echo " $sdk_container_common_registry/flatcar-sdk-[ARCH]:[SDK VERSION]."
echo " Useful for CI." echo " Useful for CI."
echo " -U Do not update the versionfile. Instead, use the version from the versionfile as-is." echo " -U Do not update the versionfile. Instead, use the version from the versionfile as-is."
echo " -m <src>:<dest> - Mount local file or directory inside the container."
echo " Can be specified multiple times."
echo " -h Print this help." echo " -h Print this help."
echo echo
} }
# -- # --
update_versionfile=x update_versionfile=x
while [ 0 -lt $# ] ; do while [[ $# -gt 0 ]] ; do
case "$1" in case "$1" in
-h) usage; exit 0;; -h) usage; exit 0;;
--help) usage; exit 0;; --help) usage; exit 0;;
-t) tty="-t"; shift;; -t) tty=( -t ); shift;;
-v) os_version="$2"; shift; shift;; -v) os_version=$2; shift; shift;;
-V) sdk_version="$2"; shift; shift;; -V) sdk_version=$2; shift; shift;;
-a) arch="$2"; shift; shift;; -a) arch=$2; shift; shift;;
-n) name="$2"; shift; shift;; -n) name=$2; shift; shift;;
--rm) remove=true; shift;; --rm) remove=x; shift;;
-x) cleanup="$2"; shift; shift;; -x) cleanup=$2; shift; shift;;
-C) custom_image="$2"; shift; shift;; -C) custom_image=$2; shift; shift;;
-U) sdk_version="$(get_sdk_version_from_versionfile)" -U) sdk_version=$(get_sdk_version_from_versionfile)
os_version="$(get_version_from_versionfile)" os_version=$(get_version_from_versionfile)
update_versionfile= update_versionfile=
shift;; shift;;
-m) mounts+=( -v "$2" ); shift; shift;;
*) break;; *) break;;
esac esac
done done
if [ -n "$custom_image" ] ; then if [[ -n ${custom_image} ]] ; then
container_image_name="${custom_image}" container_image_name=${custom_image}
else else
docker_sdk_vernum="$(vernum_to_docker_image_version "${sdk_version}")" docker_sdk_vernum=$(vernum_to_docker_image_version "${sdk_version}")
container_image_name="$sdk_container_common_registry/flatcar-sdk-${arch}:${docker_sdk_vernum}" container_image_name="${sdk_container_common_registry}/flatcar-sdk-${arch}:${docker_sdk_vernum}"
fi fi
if [[ -n ${update_versionfile} ]] ; then if [[ -n ${update_versionfile} ]] ; then
create_versionfile "$sdk_version" "$os_version" create_versionfile "$sdk_version" "$os_version"
fi fi
if [ -z "$name" ] ; then if [[ -z ${name} ]] ; then
docker_sdk_vernum="$(vernum_to_docker_image_version "${sdk_version}")" docker_sdk_vernum=$(vernum_to_docker_image_version "${sdk_version}")
docker_os_vernum="$(vernum_to_docker_image_version "${os_version}")" docker_os_vernum=$(vernum_to_docker_image_version "${os_version}")
name="flatcar-sdk-${arch}-${docker_sdk_vernum}_os-${docker_os_vernum}" name="flatcar-sdk-${arch}-${docker_sdk_vernum}_os-${docker_os_vernum}"
fi fi
filter="^/" filter="^/"
if "${is_podman}"; then if "${is_podman}"; then
filter="" filter=""
fi fi
stat="$($docker ps --all --no-trunc --filter name="${filter}$name\$" --format '{{.Status}}'\ stat=$(call_docker ps --all --no-trunc --filter name="${filter}${name}\$" --format '{{.Status}}' \
| cut -f1 -d' ')" | cut -f1 -d' ')
# pass SDK related environment variables and gcloud auth # pass SDK related environment variables and gcloud auth
# into container # into container
@ -104,59 +108,67 @@ setup_gsutil
mkdir -p "__build__/images" mkdir -p "__build__/images"
mkdir -p "sdk_container/.cache/sdks" mkdir -p "sdk_container/.cache/sdks"
hostname="${name:0:63}" hostname=${name:0:63}
hostname="${hostname//./_}" hostname=${hostname//./_}
if [ -n "$cleanup" ] ; then if [[ -n ${cleanup} ]] ; then
echo "$docker container rm -f '${name}'" >> "$cleanup" echo "${docker_a[@]@Q} container rm -f ${name@Q}" >>"${cleanup}"
fi fi
if [ -z "$stat" ] ; then if [[ -z ${stat} ]] ; then
yell "Creating a new container '$name'" yell "Creating a new container '$name'"
gpg_volumes=$(gnupg_ssh_gcloud_mount_opts) gpg_volumes=()
gnupg_ssh_gcloud_mount_opts gpg_volumes
if [ -z "$custom_image" ]; then if [[ -z ${custom_image} ]]; then
( (
source ci-automation/ci_automation_common.sh source ci-automation/ci_automation_common.sh
docker_image_from_registry_or_buildcache "flatcar-sdk-${arch}" "${docker_sdk_vernum}" docker_image_from_registry_or_buildcache "flatcar-sdk-${arch}" "${docker_sdk_vernum}"
) )
else else
# We could split the container_image_name in parts to call docker_image_from_registry_or_buildcache # We could split the container_image_name in parts to call docker_image_from_registry_or_buildcache
# bur for now just try to ensure that we use the latest image if using a container registry, # bur for now just try to ensure that we use the latest image if using a container registry,
# for the tar-ball-imported images we rely on the ci-automation scripts to call # for the tar-ball-imported images we rely on the ci-automation scripts to call
# docker_image_from_registry_or_buildcache explicitly. # docker_image_from_registry_or_buildcache explicitly.
$docker pull "${container_image_name}" || true call_docker pull "${container_image_name}" || true
fi fi
$docker create $tty -i \ docker_flags=(
-v /dev:/dev \ "${tty[@]}"
-v "$(pwd)/sdk_container:/mnt/host/source/" \ -i
-v "$(pwd)/__build__/images:/mnt/host/source/src/build" \ -v /dev:/dev
-v "$(pwd):/mnt/host/source/src/scripts" \ -v "${PWD}/sdk_container:/mnt/host/source/"
$gpg_volumes \ -v "${PWD}/__build__/images:/mnt/host/source/src/build"
--privileged \ -v "${PWD}:/mnt/host/source/src/scripts"
--network host \ "${gpg_volumes[@]}"
-e SDK_USER_ID="$(id -u)" \ "${mounts[@]}"
-e SDK_GROUP_ID="$(id -g)" \ --privileged
--name="$name" \ --network host
--hostname="$hostname" \ -e SDK_USER_ID="$(id -u)"
--entrypoint /bin/bash \ -e SDK_GROUP_ID="$(id -g)"
"${container_image_name}" -l --name="${name}"
--hostname="${hostname}"
--entrypoint /bin/bash
"${container_image_name}"
-l
)
call_docker create "${docker_flags[@]}"
fi fi
if [ "$stat" != "Up" ] ; then if [[ ${stat} != "Up" ]] ; then
yell "Starting stopped container '$name'" yell "Starting stopped container '$name'"
if [ "${remove}" = "true" ]; then if [[ -n ${remove} ]]; then
remove_command="$docker rm -f $name" remove_command="call_docker rm -f ${name@Q}"
else else
remove_command=":" remove_command=":"
fi fi
trap "$docker stop -t 0 $name ; ${remove_command}" EXIT trap "call_docker stop -t 0 ${name@Q} ; ${remove_command}" EXIT
$docker start "$name" call_docker start "${name}"
fi fi
# Workaround: The SDK expects to be able to write to /etc/hosts # Workaround: The SDK expects to be able to write to /etc/hosts
$docker exec "$name" sh -c 'cp /etc/hosts /etc/hosts2; umount /etc/hosts ; mv /etc/hosts2 /etc/hosts' call_docker exec "${name}" sh -c 'cp /etc/hosts /etc/hosts2; umount /etc/hosts ; mv /etc/hosts2 /etc/hosts'
$docker exec $tty -i "$name" /mnt/host/source/src/scripts/sdk_lib/sdk_entry.sh "$@" call_docker exec "${tty[@]}" -i "${name}" /mnt/host/source/src/scripts/sdk_lib/sdk_entry.sh "$@"

View File

@ -32,10 +32,16 @@ if command -v podman >/dev/null; then
fi fi
fi fi
docker="docker" docker_a=( docker )
if "${is_podman}"; then if "${is_podman}"; then
docker="sudo podman" docker_a=( sudo podman )
fi fi
docker=${docker_a[*]}
function call_docker() {
"${docker_a[@]}" "${@}"
}
# --
# Common "echo" function # Common "echo" function
@ -263,7 +269,6 @@ EOF
export GOOGLE_APPLICATION_CREDENTIALS export GOOGLE_APPLICATION_CREDENTIALS
} }
# -- # --
# Generate volume mount command line options for docker # Generate volume mount command line options for docker
@ -271,26 +276,32 @@ EOF
# into the SDK container. # into the SDK container.
function gnupg_ssh_gcloud_mount_opts() { function gnupg_ssh_gcloud_mount_opts() {
local -n args_ref="${1}"; shift
local sdk_gnupg_home="/home/sdk/.gnupg" local sdk_gnupg_home="/home/sdk/.gnupg"
local gpgagent_dir="/run/user/$(id -u)/gnupg" local gpgagent_dir="/run/user/$(id -u)/gnupg"
args_ref=()
# pass host GPG home and Agent directories to container # pass host GPG home and Agent directories to container
if [ -d "$GNUPGHOME" ] ; then if [[ -d ${GNUPGHOME} ]] ; then
echo "-v $GNUPGHOME:$sdk_gnupg_home" args_ref+=( -v "$GNUPGHOME:$sdk_gnupg_home" )
fi fi
if [ -d "$gpgagent_dir" ] ; then if [[ -d ${gpgagent_dir} ]] ; then
echo "-v $gpgagent_dir:$gpgagent_dir" args_ref+=( -v "${gpgagent_dir}:${gpgagent_dir}" )
fi fi
if [ -e "${SSH_AUTH_SOCK:-}" ] ; then local sshsockdir
local sshsockdir="$(dirname "$SSH_AUTH_SOCK")" if [[ -e ${SSH_AUTH_SOCK:-} ]] ; then
echo "-v $sshsockdir:/run/sdk/ssh" sshsockdir=$(dirname "$SSH_AUTH_SOCK")
args_ref+=( -v "${sshsockdir}:/run/sdk/ssh" )
fi fi
if [ -e "${GOOGLE_APPLICATION_CREDENTIALS:-}" ] ; then local creds_dir
local creds_dir="$(dirname "${GOOGLE_APPLICATION_CREDENTIALS}")" if [[ -e ${GOOGLE_APPLICATION_CREDENTIALS:-} ]] ; then
if [ -d "$creds_dir" ] ; then creds_dir=$(dirname "${GOOGLE_APPLICATION_CREDENTIALS}")
if [[ -d ${creds_dir} ]] ; then
echo "-v $creds_dir:$creds_dir" echo "-v $creds_dir:$creds_dir"
args_ref+=( -v "${creds_dir}:${creds_dir}" )
fi fi
fi fi
} }