mirror of
https://github.com/flatcar/scripts.git
synced 2025-08-06 04:26:59 +02:00
At least with Podman it's not possible to call "container rm" on a running container without the force flag. Add the force flag which is also used elsewhere already.
252 lines
9.2 KiB
Bash
Executable File
252 lines
9.2 KiB
Bash
Executable File
#!/bin/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 script will generate an SDK container image from an SDK tarball
|
|
# (which in turn is generated by bootstrap_sdk[_container]).
|
|
#
|
|
# It uses a number of intermediate build steps:
|
|
# 1. Import the SDK tarball into a "tarball" container image.
|
|
# 2. Build a "plain" SDK container image which creates the "sdk" user
|
|
# and runs "update_chroot" to initialise the x86 and aarch64 SDK cross env.
|
|
# This step uses sdk_lib/Dockerfile.sdk-import.
|
|
# 3. Using the "plain" SDK image, start a temporary "toolchain" container
|
|
# to build toolchain binary packages.
|
|
# 4. Inheriting from the "plain" SDK image and using the toolchain packages,
|
|
# build a "full" SDK container image, with board support for both amd64-usr and arm64-usr.
|
|
# A temporary HTTP server on the Docker interface IP is spun up in this step
|
|
# to serve the toolchain binpkgs to the build container.
|
|
# This step uses sdk_lib/Dockerfile.sdk-build.
|
|
# 5. In a last step, all unnecessary binaries are removed from the "full" image and 3
|
|
# output SDK images are produced:
|
|
# - "all", with both amd64 and arm64 target support, and
|
|
# - "amd64" and "arm64, with only amd64 or arm64 target support respectively.
|
|
# This step uses sdk_lib/Dockerfile.lean-arch.
|
|
|
|
set -eu
|
|
|
|
cd $(dirname "$0")
|
|
source sdk_lib/sdk_container_common.sh
|
|
|
|
arch="amd64"
|
|
official="0"
|
|
tarball=""
|
|
os_version=""
|
|
|
|
keep="false"
|
|
cleanup=""
|
|
|
|
usage() {
|
|
echo " $0 - Create SDK container image from an SDK tarball"
|
|
echo " This script will set up a new SDK container from a tarball."
|
|
echo " The resulting container comes in 3 flavours:"
|
|
echo " 1. flatcar-sdk-all - includes both ARM64 and AMD64 support"
|
|
echo " 2.+3. flatcar-sdk-(amd64|arm64) - only includes support for one target."
|
|
echo " Usage:"
|
|
echo " $0 <tarball>] [-k] [-v <os-version>] [-x <script>]"
|
|
echo
|
|
echo " <tarball> - Local tarball to build SDK from."
|
|
echo " The tarball must follow the format"
|
|
echo " flatcar-sdk-(amd64|arm64)-<version>.tar.bz2."
|
|
echo " -v <version> - Use custom OS version (defaults to tarball's SDK version)."
|
|
echo " -k - Keep intermediate build containers (sdk-import / sdk-tarball)."
|
|
echo " (Useful for sdk container build script development.)"
|
|
echo " -x <script> - For each resource generated during build (container etc.)"
|
|
echo " add a cleanup line to <script> which, when run, will free"
|
|
echo " the resource. Useful for CI."
|
|
echo " -h - Print this help."
|
|
echo
|
|
}
|
|
|
|
# --
|
|
|
|
while [ 0 -lt $# ] ; do
|
|
case "$1" in
|
|
-h) usage; exit 0;;
|
|
-k) keep="true"; shift;;
|
|
-v) os_version="$2"; shift; shift;;
|
|
-x) cleanup="$2"; shift; shift;;
|
|
*) if [ -z "$tarball" ] ; then
|
|
tarball="$1"; shift
|
|
else
|
|
echo "ERROR: spurious positional parameter '$@'."
|
|
usage
|
|
exit 1
|
|
fi;;
|
|
esac
|
|
done
|
|
|
|
if [ -z "$tarball" -o ! -s "$tarball" ] ; then
|
|
echo "ERROR: missing / invalid SDK tarball argument"
|
|
exit 1
|
|
fi
|
|
# --
|
|
|
|
# Grok version / arch from tarball name, set official if version is a release version
|
|
version="$(echo "$tarball" | sed -n 's/.*flatcar-sdk-\(arm64\|amd64\)-\(.\+\)\.tar\.bz2/\2/p')"
|
|
arch="$(echo "$tarball" | sed -n 's/.*flatcar-sdk-\(arm64\|amd64\)-.*\.tar\.bz2/\1/p')"
|
|
if [ -z "$version" -o -z "$arch" ]; then
|
|
echo "ERROR: Unable to determine version / arch from '$tarball'"
|
|
exit 1
|
|
fi
|
|
|
|
if [ -z "${os_version}" ] ; then
|
|
os_version="${version}"
|
|
fi
|
|
|
|
if is_official "$version" && [ "${version}" = "${os_version}" ] ; then
|
|
official="1"
|
|
else
|
|
official="0"
|
|
fi
|
|
|
|
# --
|
|
|
|
# import tarball
|
|
#
|
|
yell "\n######\n###### Building SDK container for version $version from '$tarball'"
|
|
create_versionfile "$version" "${os_version}"
|
|
|
|
docker_vernum="$(vernum_to_docker_image_version "${version}")"
|
|
import_tarball="flatcar-sdk-tarball:${docker_vernum}"
|
|
image_present="$($docker image ls "$import_tarball" --format '{{.Repository}}:{{.Tag}}')"
|
|
|
|
if [ "${image_present}" = "${import_tarball}" ] ; then
|
|
yell "Using existing SDK tarball image '${import_tarball}'"
|
|
else
|
|
yell "Importing SDK tarball"
|
|
if [ -n "$cleanup" ] ; then
|
|
echo "$docker image rm -f '${import_tarball}'" >> "$cleanup"
|
|
fi
|
|
$docker import "${tarball}" "${import_tarball}"
|
|
fi
|
|
|
|
# --
|
|
|
|
# build plain SDK container w/o board support
|
|
#
|
|
import_image="flatcar-sdk-import:${docker_vernum}"
|
|
image_present="$($docker image ls "${import_image}" --format '{{.Repository}}:{{.Tag}}')"
|
|
|
|
if [ "$image_present" = "${import_image}" ] ; then
|
|
yell "Using existing SDK import image '${import_image}'"
|
|
else
|
|
yell "Building plain SDK import image"
|
|
if [ -n "$cleanup" ] ; then
|
|
echo "$docker image rm -f '${import_image}'" >> "$cleanup"
|
|
fi
|
|
$docker build -t "$import_image" \
|
|
--build-arg VERSION="${docker_vernum}" \
|
|
-f sdk_lib/Dockerfile.sdk-import \
|
|
.
|
|
fi
|
|
|
|
# --
|
|
|
|
# build full SDK container w/ board support.
|
|
# This uses the SDK import container to first build toolchain binpkgs.
|
|
# Then, the import container and toolchain packages are used
|
|
# to build a full SDK container w/ amd64 and arm64 board support.
|
|
#
|
|
sdk_build_image="flatcar-sdk-build:${docker_vernum}"
|
|
image_present="$($docker image ls "${sdk_build_image}" --format '{{.Repository}}:{{.Tag}}')"
|
|
if [ "$image_present" = "${sdk_build_image}" ] ; then
|
|
yell "Using existing SDK build image '${sdk_build_image}'"
|
|
else
|
|
# --- Toolchains build ---
|
|
yell "Building toolchains in a temporary container."
|
|
# We need to use run_sdk_container instead of building from a Dockerfile
|
|
# since toolchains build uses catalyst which requires privileged access.
|
|
tarball_copied=""
|
|
if [ "$(basename "${tarball}")" != "${tarball}" ] ; then
|
|
cp --reflink=auto "${tarball}" ./
|
|
tarball="$(basename "${tarball}")"
|
|
tarball_copied="${tarball}"
|
|
fi
|
|
|
|
toolchains_container="flatcar-sdk-toolchains-build-${docker_vernum}"
|
|
if [ -n "$cleanup" ] ; then
|
|
echo "$docker container rm -f '${toolchains_container}'" >> "$cleanup"
|
|
fi
|
|
./run_sdk_container -C "${import_image}" -n "${toolchains_container}" \
|
|
sudo ./build_toolchains --seed_tarball="./${tarball}"
|
|
|
|
# remove sdk tarball from scripts root so it's not part of the SDK container build context
|
|
if [ -f "${tarball_copied}" ] ; then
|
|
rm "${tarball_copied}"
|
|
fi
|
|
|
|
$docker container rm -f "${toolchains_container}"
|
|
|
|
docker_interface="docker0"
|
|
if "${is_podman}"; then
|
|
# Make a dummy run without "--net host" here for the interface to be created
|
|
$docker run --rm alpine
|
|
docker_interface="cni-podman0"
|
|
fi
|
|
host_ip="$(ip addr show "${docker_interface}" | grep -Po 'inet \K[\d.]+')"
|
|
binhost_port="$((1000 + (RANDOM % 55000) ))"
|
|
binhost="${host_ip}:${binhost_port}"
|
|
binhost_container="${toolchains_container}-binhost-${binhost_port}"
|
|
yell "Building SDK container + board support, toolchain packages served at http://${binhost} by ${binhost_container}"
|
|
|
|
# Spin up temporary toolchains package binhost
|
|
if [ -n "$cleanup" ] ; then
|
|
echo "$docker container rm -f '${binhost_container}'" >> "$cleanup"
|
|
fi
|
|
$docker run --rm -d -p "${binhost}":80 \
|
|
--name ${binhost_container} \
|
|
-v "$(pwd)/__build__/images/catalyst/packages/coreos-toolchains/target":/usr/share/caddy \
|
|
docker.io/library/caddy caddy file-server \
|
|
--root /usr/share/caddy --browse
|
|
|
|
# --- Full SDK container build ---
|
|
|
|
yell "Initialising the SDK container and building board packages"
|
|
if [ -n "$cleanup" ] ; then
|
|
echo "$docker image rm -f '${sdk_build_image}'" >> "$cleanup"
|
|
fi
|
|
$docker build -t "${sdk_build_image}" \
|
|
--build-arg VERSION="${docker_vernum}" \
|
|
--build-arg BINHOST="http://${binhost}" \
|
|
--build-arg OFFICIAL="${official}" \
|
|
-f sdk_lib/Dockerfile.sdk-build \
|
|
.
|
|
|
|
$docker stop "${binhost_container}"
|
|
fi
|
|
|
|
# --
|
|
|
|
# Derive "lean" SDK containers from full build. Main purpose
|
|
# of this step is to remove "white-outs", i.e. files which have been
|
|
# deleted in the full image but are still present in an intermediate layer.
|
|
#
|
|
for a in all arm64 amd64; do
|
|
yell "Creating '$a' arch SDK image"
|
|
rmarch=""; rmcross=""
|
|
case $a in
|
|
arm64) rmarch="amd64-usr"; rmcross="x86_64-cros-linux-gnu";;
|
|
amd64) rmarch="arm64-usr"; rmcross="aarch64-cros-linux-gnu";;
|
|
esac
|
|
$docker build -t "$sdk_container_common_registry/flatcar-sdk-${a}:${docker_vernum}" \
|
|
--build-arg VERSION="${docker_vernum}" \
|
|
--build-arg RMARCH="${rmarch}" \
|
|
--build-arg RMCROSS="${rmcross}" \
|
|
-f sdk_lib/Dockerfile.lean-arch \
|
|
.
|
|
done
|
|
|
|
# --
|
|
|
|
# Cleanup
|
|
#
|
|
if ! $keep; then
|
|
yell "Cleaning up intermediate containers"
|
|
$docker rmi flatcar-sdk-build:"${docker_vernum}"
|
|
$docker rmi flatcar-sdk-import:"${docker_vernum}"
|
|
$docker rmi flatcar-sdk-tarball:"${docker_vernum}"
|
|
fi
|