| #!/bin/bash | |
| set -e | |
| set -o pipefail | |
| TOOLBOX_DOCKER_IMAGE=fedora | |
| TOOLBOX_DOCKER_TAG=latest | |
| TOOLBOX_USER=root | |
| TOOLBOX_DIRECTORY="/var/lib/toolbox" | |
| TOOLBOX_BIND="--bind=/:/media/root --bind=/usr:/media/root/usr --bind=/run:/media/root/run" | |
| # Ex: "--setenv=KEY=VALUE" | |
| TOOLBOX_ENV="" | |
| TOOLBOX_DOCKER_IMAGE_TARBALL="" | |
| TOOLBOX_TEMP_DIR=$(mktemp -d) | |
| COS_PROJECT="/cos-cloud/" | |
| ARTIFACT_REGISTRY_REGIONS=("us" "eu" "asia") | |
| toolboxrc="${HOME}"/.toolboxrc | |
| # System defaults | |
| if [ -f "/etc/default/toolbox" ]; then | |
| source "/etc/default/toolbox" | |
| fi | |
| # User overrides | |
| if [ -f "${toolboxrc}" ]; then | |
| source "${toolboxrc}" | |
| fi | |
| if [[ -f /etc/cloud-api-domains ]]; then | |
| source "/etc/cloud-api-domains" | |
| fi | |
| if [[ -n "$API_DOMAIN" && $API_DOMAIN != "googleapis.com" && "${TOOLBOX_DOCKER_IMAGE}" == *"${COS_PROJECT}"* ]]; then | |
| TOOLBOX_DOCKER_IMAGE="docker.${ARTIFACT_REGISTRY_DOMAIN}/${PROJECT_PREFIX::-1}/cos-cloud/toolbox/toolbox" | |
| fi | |
| # Change toolbox container image name if location of the vm is available | |
| # and it's from cos-cloud project. | |
| if [[ "${TOOLBOX_DOCKER_IMAGE}" == *"${COS_PROJECT}"* ]]; then | |
| INSTANCE_ZONE="$(curl -s "http://metadata.google.internal/computeMetadata/v1/instance/zone?alt=text" -H "Metadata-Flavor: Google" || true)" | |
| if [[ -n "${INSTANCE_ZONE}" ]]; then | |
| # Syntax of INSTANCE_ZONE: projects/<project-id>/zones/<region> | |
| # Example: projects/475556798229/zones/us-central1-a | |
| INSTANCE_REGION="$(echo "${INSTANCE_ZONE}" | cut -d/ -f4 | cut -d- -f1)" | |
| for region in ${ARTIFACT_REGISTRY_REGIONS[@]}; do | |
| if [[ "${region}" == "${INSTANCE_REGION}" ]]; then | |
| TOOLBOX_DOCKER_IMAGE="${INSTANCE_REGION}.${TOOLBOX_DOCKER_IMAGE}" | |
| break | |
| fi | |
| done | |
| fi | |
| fi | |
| machinename=$(echo "${USER}-${TOOLBOX_DOCKER_IMAGE}-${TOOLBOX_DOCKER_TAG}" | sed -r 's/[^a-zA-Z0-9_.-]/_/g') | |
| machinepath="${TOOLBOX_DIRECTORY}/${machinename}" | |
| osrelease="${machinepath}/etc/os-release" | |
| if [ ! -f ${osrelease} ] ; then | |
| sudo mkdir -p "${machinepath}" | |
| sudo mkdir -p "${TOOLBOX_TEMP_DIR}" | |
| sudo chown "${USER}": "${machinepath}" | |
| if [ ! -z "${TOOLBOX_DOCKER_IMAGE_TARBALL}" ] ; then | |
| sudo ctr image import "${TOOLBOX_DOCKER_IMAGE_TARBALL}" | |
| else | |
| if [[ "${TOOLBOX_DOCKER_IMAGE}" =~ ^[a-z.]*gcr.io/ ]]; then | |
| # Get a host part of the container name | |
| registry_host="${TOOLBOX_DOCKER_IMAGE/gcr.io*/gcr.io}" | |
| elif [[ "${TOOLBOX_DOCKER_IMAGE}" =~ ^[0-9a-z.-]*docker.pkg.dev/ ]]; then | |
| registry_host="${TOOLBOX_DOCKER_IMAGE/docker.pkg.dev*/docker.pkg.dev}" | |
| elif [[ -n "${ARTIFACT_REGISTRY_DOMAIN}" ]]; then | |
| registry_host="docker.${ARTIFACT_REGISTRY_DOMAIN}" | |
| fi | |
| if [[ -n "${registry_host}" ]]; then | |
| # docker-credential-gcr can fail if it runs in a | |
| # non-GCP env, so let it fail and proceed without | |
| # --user flag in this case | |
| credentials=$(echo "${registry_host}" | \ | |
| (/usr/bin/docker-credential-gcr get || true) 2>/dev/null | \ | |
| (jq -r '.Username + ":" + .Secret' || true)) | |
| if [[ -n "${credentials}" ]]; then | |
| user_flags=('--user' "${credentials}") | |
| fi | |
| fi | |
| sudo ctr image pull "${user_flags[@]}" "${TOOLBOX_DOCKER_IMAGE}:${TOOLBOX_DOCKER_TAG}" | |
| fi | |
| # The below command is finding the short SHA256 prefix of the container | |
| # image. | |
| container256hash=$(sudo ctr image ls | grep "${TOOLBOX_DOCKER_IMAGE}:${TOOLBOX_DOCKER_TAG}" | awk '{ print $3 }' | cut -d':' -f2 | cut -c-12) | |
| containername=$(echo "${USER}-${container256hash}" | sed -r 's/[^a-zA-Z0-9_.-]/_/g') | |
| sudo ctr containers create "${TOOLBOX_DOCKER_IMAGE}:${TOOLBOX_DOCKER_TAG}" ${containername} /bin/true | |
| sudo ctr snapshot mounts "${TOOLBOX_TEMP_DIR}" ${containername} | xargs sudo | |
| sudo rsync -a "${TOOLBOX_TEMP_DIR}/" "${machinepath}" | |
| sudo umount "${TOOLBOX_TEMP_DIR}" | |
| sudo ctr container rm ${containername} | |
| sudo rm -rf "${TOOLBOX_TEMP_DIR}" | |
| sudo touch ${osrelease} | |
| fi | |
| sudo \ | |
| SYSTEMD_NSPAWN_UNIFIED_HIERARCHY=yes \ | |
| SYSTEMD_NSPAWN_SHARE_SYSTEM=1 \ | |
| systemd-nspawn \ | |
| --directory="${machinepath}" \ | |
| --capability=all \ | |
| --resolv-conf="replace-host" \ | |
| ${TOOLBOX_BIND} \ | |
| ${TOOLBOX_ENV} \ | |
| --user="${TOOLBOX_USER}" "$@" |