mirror of
https://github.com/flatcar/scripts.git
synced 2025-08-07 04:56:58 +02:00
- Make cosmetic fixes in help output. - There is usually no need for putting variables inside quotes in assignments. - Use [[ ]] to avoid putting everything into strings. - Use arrays instead of relying on strings to be split on whitespace as it was the case for invoking docker and getting GPG volume flags for docker. - Make sure that some cleanup and trap strings quote variables properly. - Add a "call_docker" function to avoid dealing with "docker" and a new "docker_a" variables when willing to invoke docker. The "docker" variable rather shouldn't be used, but it is still there in case some other scripts were using it.
308 lines
9.3 KiB
Bash
308 lines
9.3 KiB
Bash
# Copyright (c) 2021 The Flatcar Maintainers.
|
|
# Use of this source code is governed by a BSD-style license that can be
|
|
# found in the LICENSE file.
|
|
#
|
|
# This file contains common functions used across SDK container scripts.
|
|
|
|
#
|
|
# globals
|
|
#
|
|
sdk_container_common_versionfile="sdk_container/.repo/manifests/version.txt"
|
|
sdk_container_common_registry="ghcr.io/flatcar"
|
|
sdk_container_common_env_file="sdk_container/.sdkenv"
|
|
|
|
# Check for podman and docker; use docker if present, podman alternatively.
|
|
# Podman needs 'sudo' since we need privileged containers for the SDK.
|
|
|
|
is_podman=false
|
|
if command -v podman >/dev/null; then
|
|
# podman is present
|
|
if command -v docker >/dev/null ; then
|
|
# docker is present, too
|
|
if docker help | grep -q -i podman; then
|
|
# "docker" is actually podman.
|
|
# NOTE that 'docker --version' does not reliably work for podman detection
|
|
# since 'podman' uses argv[0] in its version string.
|
|
# A symlink docker->podman will result in 'podman' using the 'docker' argv[0].
|
|
is_podman=true
|
|
fi
|
|
else
|
|
# docker is not present
|
|
is_podman=true
|
|
fi
|
|
fi
|
|
|
|
docker_a=( docker )
|
|
if "${is_podman}"; then
|
|
docker_a=( sudo podman )
|
|
fi
|
|
docker=${docker_a[*]}
|
|
|
|
function call_docker() {
|
|
"${docker_a[@]}" "${@}"
|
|
}
|
|
# --
|
|
|
|
# Common "echo" function
|
|
|
|
function yell() {
|
|
echo -e "\n###### $@ ######"
|
|
}
|
|
# --
|
|
|
|
# Guess the SDK version from the current git commit.
|
|
#
|
|
function get_git_version() {
|
|
local tag="$(git tag --points-at HEAD)"
|
|
if [ -z "$tag" ] ; then
|
|
git describe --tags
|
|
else
|
|
echo "$tag"
|
|
fi
|
|
}
|
|
# --
|
|
|
|
function get_sdk_version_from_versionfile() {
|
|
( source "$sdk_container_common_versionfile"; echo "$FLATCAR_SDK_VERSION"; )
|
|
}
|
|
# --
|
|
|
|
function get_version_from_versionfile() {
|
|
( source "$sdk_container_common_versionfile"; echo "$FLATCAR_VERSION"; )
|
|
}
|
|
# --
|
|
|
|
# return true if a given version number is an official build
|
|
#
|
|
function is_official() {
|
|
local vernum="$1"
|
|
|
|
local official="$(echo "$vernum" | sed -n 's/^[0-9]\+\.[0-9]\+\.[0-9]\+$/true/p')"
|
|
|
|
test -n "$official"
|
|
}
|
|
# --
|
|
|
|
# extract the build ID suffix from a version string ("alpha-3244.0.1-nightly2" => "nightly2")
|
|
#
|
|
function build_id_from_version() {
|
|
local version="$1"
|
|
|
|
# support vernums and versions ("alpha-"... is optional)
|
|
echo "${version}" | sed -n 's/^\([a-z]\+-\)\?[0-9.]\+[-+]\(.*\)$/\2/p'
|
|
}
|
|
# --
|
|
|
|
# Get channel from a version string ("alpha-3244.0.1-nightly2" => "alpha")
|
|
#
|
|
function channel_from_version() {
|
|
local version="$1"
|
|
local channel=""
|
|
|
|
channel=$(echo "${version}" | cut -d - -f 1)
|
|
if [ "${channel}" != "alpha" ] && [ "${channel}" != "beta" ] && [ "${channel}" != "stable" ] && [ "${channel}" != "lts" ]; then
|
|
channel="developer"
|
|
fi
|
|
echo "${channel}"
|
|
}
|
|
# --
|
|
|
|
function get_git_channel() {
|
|
channel_from_version "$(get_git_version)"
|
|
}
|
|
# --
|
|
|
|
# extract the version number (w/o build ID) from a version string ("alpha-3244.0.1-nightly2" => "3244.0.1")
|
|
#
|
|
function vernum_from_version() {
|
|
local version="$1"
|
|
|
|
# support vernums and versions ("alpha-"... is optional)
|
|
echo "${version}" | sed -n 's/^\([a-z]\+-\)\?\([0-9.]\+\).*/\2/p'
|
|
}
|
|
# --
|
|
|
|
# Strip prefix from version string if present ("alpha-3233.0.0[-...]" => "3233.0.0[-...]")
|
|
# and add a "+[build suffix]" if this is a non-official build. The "+" matches the version
|
|
# string generation in the build scripts.
|
|
function strip_version_prefix() {
|
|
local version="$1"
|
|
|
|
local build_id="$(build_id_from_version "${version}")"
|
|
local version_id="$(vernum_from_version "${version}")"
|
|
|
|
if [ -n "${build_id}" ] ; then
|
|
echo "${version_id}+${build_id}"
|
|
else
|
|
echo "${version_id}"
|
|
fi
|
|
}
|
|
# --
|
|
|
|
# Derive docker-safe image version string from vernum.
|
|
# Keep in sync with ci-automation/ci_automation_common.sh
|
|
function vernum_to_docker_image_version() {
|
|
local vernum="$1"
|
|
echo "$vernum" | sed 's/[+]/-/g'
|
|
}
|
|
# --
|
|
|
|
# Creates the Flatcar build / SDK version file.
|
|
# Must be called from the script root.
|
|
#
|
|
# In the versionfile, FLATCAR_VERSION is the OS image version _number_ plus a build ID if this is no
|
|
# official build. The FLATCAR_VERSION_ID is the plain vernum w/o build ID - it's the same as FLATCAR_VERSION
|
|
# for official builds. The FLATCAR_BUILD_ID is the build ID suffix for non-official builds.
|
|
# Lastly, the FLATCAR_SDK_VERSION is the full version number (including build ID if no official SDK release)
|
|
# the OS image is to be built with.
|
|
#
|
|
function create_versionfile() {
|
|
local sdk_version="$1"
|
|
local os_version="${2:-$sdk_version}"
|
|
local build_id="$(build_id_from_version "${os_version}")"
|
|
local version_id="$(vernum_from_version "${os_version}")"
|
|
|
|
sdk_version="$(strip_version_prefix "${sdk_version}")"
|
|
os_version="$(strip_version_prefix "${os_version}")"
|
|
yell "Writing versionfile '$sdk_container_common_versionfile' to SDK '$sdk_version', OS '$os_version'."
|
|
|
|
cat >"$sdk_container_common_versionfile" <<EOF
|
|
FLATCAR_VERSION=${os_version}
|
|
FLATCAR_VERSION_ID=${version_id}
|
|
FLATCAR_BUILD_ID="${build_id}"
|
|
FLATCAR_SDK_VERSION=${sdk_version}
|
|
EOF
|
|
}
|
|
# --
|
|
|
|
#
|
|
# Set up SDK environment variables.
|
|
# Environment vars are put in a file that is sourced by the container's
|
|
# .bashrc (if present). GNUPGHOME and SSH_AUTH_SOCK are set
|
|
# to container-specific paths if applicable.
|
|
|
|
function setup_sdk_env() {
|
|
local var
|
|
|
|
rm -f "$sdk_container_common_env_file"
|
|
|
|
# conditionally set up gnupg, ssh socket, and gcloud auth / boto
|
|
# depending on availability on the host
|
|
GNUPGHOME="${GNUPGHOME:-$HOME/.gnupg}"
|
|
if [ -d "${GNUPGHOME}" ] ; then
|
|
echo "GNUPGHOME=\"/home/sdk/.gnupg\"" >> "$sdk_container_common_env_file"
|
|
echo "export GNUPGHOME" >> "$sdk_container_common_env_file"
|
|
export GNUPGHOME
|
|
fi
|
|
|
|
if [ -e "${SSH_AUTH_SOCK:-}" ] ; then
|
|
local sockname="$(basename "${SSH_AUTH_SOCK}")"
|
|
echo "SSH_AUTH_SOCK=\"/run/sdk/ssh/$sockname\"" >> "$sdk_container_common_env_file"
|
|
echo "export SSH_AUTH_SOCK" >> "$sdk_container_common_env_file"
|
|
fi
|
|
|
|
# keep in sync with 90_env_keep, without GNUPGHOME and
|
|
# SSH_AUTH_SOCK as those are set up above, and without BOTO_PATH
|
|
# and GOOGLE_APPLICATION_CREDENTIALS as those are set up in the
|
|
# setup_gsutil function.
|
|
for var in FLATCAR_BUILD_ID COREOS_OFFICIAL \
|
|
EMAIL GIT_AUTHOR_EMAIL GIT_AUTHOR_NAME \
|
|
GIT_COMMITTER_EMAIL GIT_COMMITTER_NAME \
|
|
GIT_PROXY_COMMAND GIT_SSH RSYNC_PROXY \
|
|
GPG_AGENT_INFO \
|
|
\
|
|
USE FEATURES PORTAGE_USERNAME FORCE_STAGES \
|
|
SIGNER \
|
|
all_proxy ftp_proxy http_proxy https_proxy no_proxy; do
|
|
|
|
if [ -n "${!var:-}" ] ; then
|
|
echo "${var}=\"${!var}\"" >> "$sdk_container_common_env_file"
|
|
echo "export ${var}" >> "$sdk_container_common_env_file"
|
|
fi
|
|
done
|
|
}
|
|
# --
|
|
|
|
# Set up gcloud legacy creds (via GOOGLE_APPLICATION_CREDENTIALS)
|
|
# for the SDK container.
|
|
# This will also create a boto config right next to the
|
|
# GOOGLE_APPLICATION_CREDENTIALS json file.
|
|
|
|
function setup_gsutil() {
|
|
local creds="${GOOGLE_APPLICATION_CREDENTIALS:-$HOME/.config/gcloud/application_default_credentials.json}"
|
|
if [ ! -e "$creds" ]; then
|
|
return
|
|
fi
|
|
|
|
local creds_dir="$(dirname "$creds")"
|
|
local botofile="$creds_dir/boto-flatcar-sdk"
|
|
|
|
# TODO t-lo: move generation of boto file to sdk_entry so
|
|
# it's only created inside the container.
|
|
|
|
# read creds file and create boto file for gsutil
|
|
local tmp="$(mktemp)"
|
|
trap "rm -f '$tmp'" EXIT
|
|
|
|
local oauth_refresh="$(jq -r '.refresh_token' "$creds")"
|
|
local client_id="$(jq -r '.client_id' "$creds")"
|
|
local client_secret="$(jq -r '.client_secret' "$creds")"
|
|
|
|
cat >>"$tmp" <<EOF
|
|
[Credentials]
|
|
gs_oauth2_refresh_token = $oauth_refresh
|
|
|
|
[OAuth2]
|
|
client_id = $client_id
|
|
client_secret = $client_secret
|
|
EOF
|
|
mv "$tmp" "$botofile"
|
|
|
|
echo "BOTO_PATH=\"$botofile\"" >> "$sdk_container_common_env_file"
|
|
echo "export BOTO_PATH" >> "$sdk_container_common_env_file"
|
|
echo "GOOGLE_APPLICATION_CREDENTIALS=\"$creds\"" >> "$sdk_container_common_env_file"
|
|
echo "export GOOGLE_APPLICATION_CREDENTIALS" >> "$sdk_container_common_env_file"
|
|
|
|
BOTO_PATH="$botofile"
|
|
GOOGLE_APPLICATION_CREDENTIALS="$creds"
|
|
export BOTO_PATH
|
|
export GOOGLE_APPLICATION_CREDENTIALS
|
|
}
|
|
|
|
# --
|
|
|
|
# Generate volume mount command line options for docker
|
|
# to pass gpg, ssh, and gcloud auth host directories
|
|
# into the SDK container.
|
|
|
|
function gnupg_ssh_gcloud_mount_opts() {
|
|
local -n args_ref="${1}"; shift
|
|
|
|
local sdk_gnupg_home="/home/sdk/.gnupg"
|
|
local gpgagent_dir="/run/user/$(id -u)/gnupg"
|
|
|
|
args_ref=()
|
|
# pass host GPG home and Agent directories to container
|
|
if [[ -d ${GNUPGHOME} ]] ; then
|
|
args_ref+=( -v "$GNUPGHOME:$sdk_gnupg_home" )
|
|
fi
|
|
if [[ -d ${gpgagent_dir} ]] ; then
|
|
args_ref+=( -v "${gpgagent_dir}:${gpgagent_dir}" )
|
|
fi
|
|
|
|
local sshsockdir
|
|
if [[ -e ${SSH_AUTH_SOCK:-} ]] ; then
|
|
sshsockdir=$(dirname "$SSH_AUTH_SOCK")
|
|
args_ref+=( -v "${sshsockdir}:/run/sdk/ssh" )
|
|
fi
|
|
|
|
local creds_dir
|
|
if [[ -e ${GOOGLE_APPLICATION_CREDENTIALS:-} ]] ; then
|
|
creds_dir=$(dirname "${GOOGLE_APPLICATION_CREDENTIALS}")
|
|
if [[ -d ${creds_dir} ]] ; then
|
|
echo "-v $creds_dir:$creds_dir"
|
|
args_ref+=( -v "${creds_dir}:${creds_dir}" )
|
|
fi
|
|
fi
|
|
}
|