From 00b4b250ac03449ecfd198a49b64a9d719ceb62b Mon Sep 17 00:00:00 2001 From: Gabriela Cervantes Date: Thu, 1 Feb 2018 05:17:59 -0600 Subject: [PATCH] ci: Add installation scripts This will install runtime, shim, agent, proxy, qemu, and all dependencies to run kata-containers. Fixes #70 Signed-off-by: Gabriela Cervantes --- .ci/install_agent.sh | 14 ++ .ci/install_kata_image.sh | 40 +++ .ci/install_kata_kernel.sh | 92 +++++++ .ci/install_proxy.sh | 14 ++ .ci/install_qemu_lite.sh | 38 +++ .ci/install_runtime.sh | 53 ++++ .ci/install_shim.sh | 14 ++ .ci/lib.sh | 61 +++++ .ci/setup.sh | 33 +++ .ci/setup_env_ubuntu.sh | 70 ++++++ cmd/container-manager/manage_ctr_mgr.sh | 321 ++++++++++++++++++++++++ 11 files changed, 750 insertions(+) create mode 100755 .ci/install_agent.sh create mode 100755 .ci/install_kata_image.sh create mode 100755 .ci/install_kata_kernel.sh create mode 100755 .ci/install_proxy.sh create mode 100755 .ci/install_qemu_lite.sh create mode 100755 .ci/install_runtime.sh create mode 100755 .ci/install_shim.sh create mode 100755 .ci/lib.sh create mode 100755 .ci/setup.sh create mode 100755 .ci/setup_env_ubuntu.sh create mode 100755 cmd/container-manager/manage_ctr_mgr.sh diff --git a/.ci/install_agent.sh b/.ci/install_agent.sh new file mode 100755 index 000000000..450234e73 --- /dev/null +++ b/.ci/install_agent.sh @@ -0,0 +1,14 @@ +#!/bin/bash +# +# Copyright (c) 2017-2018 Intel Corporation +# +# SPDX-License-Identifier: Apache-2.0 +# + +set -e + +cidir=$(dirname "$0") + +source "${cidir}/lib.sh" + +clone_build_and_install "github.com/kata-containers/agent" diff --git a/.ci/install_kata_image.sh b/.ci/install_kata_image.sh new file mode 100755 index 000000000..0f4a82132 --- /dev/null +++ b/.ci/install_kata_image.sh @@ -0,0 +1,40 @@ +#!/bin/bash +# +# Copyright (c) 2017-2018 Intel Corporation +# +# SPDX-License-Identifier: Apache-2.0 +# + +set -e + +cidir=$(dirname "$0") + +OSBUILDER_DISTRO=${OSBUILDER_DISTRO:-clearlinux} +image_name="kata-containers.img" + +# Build Kata agent +bash -f ${cidir}/install_agent.sh + +osbuilder_repo="github.com/kata-containers/osbuilder" + +# Clone os-builder repository +go get -d ${osbuilder_repo} || true + +pushd "${GOPATH}/src/${osbuilder_repo}/rootfs-builder" +sudo -E GOPATH=$GOPATH USE_DOCKER=true ./rootfs.sh ${OSBUILDER_DISTRO} +popd + +# Build the image +pushd "${GOPATH}/src/${osbuilder_repo}/image-builder" +sudo -E USE_DOCKER=true ./image_builder.sh ../rootfs-builder/rootfs + +# Install the image +agent_commit=$("$GOPATH/src/github.com/kata-containers/agent/kata-agent" --version | awk '{print $NF}') +commit=$(git log --format=%h -1 HEAD) +date=$(date +%Y-%m-%d-%T.%N%z) +image="kata-containers-${date}-osbuilder-${commit}-agent-${agent_commit}" + +sudo install -o root -g root -m 0640 -D ${image_name} "/usr/share/kata-containers/${image}" +(cd /usr/share/kata-containers && sudo rm -f ${image_name} && sudo ln -s "$image" ${image_name}) + +popd diff --git a/.ci/install_kata_kernel.sh b/.ci/install_kata_kernel.sh new file mode 100755 index 000000000..d32b639ad --- /dev/null +++ b/.ci/install_kata_kernel.sh @@ -0,0 +1,92 @@ +#!/bin/bash +# +# Copyright (c) 2017-2018 Intel Corporation +# +# SPDX-License-Identifier: Apache-2.0 +# + +# Currently we will use this repository until this issue is solved +# See https://github.com/kata-containers/packaging/issues/1 + +set -e + +cidir=$(dirname "$0") +source "${cidir}/lib.sh" + +repo_owner="clearcontainers" +repo_name="linux" + +linux_releases_url="https://github.com/${repo_owner}/${repo_name}/releases" +#fake repository dir to query kernel version from remote +fake_repo_dir=$(mktemp -t -d kata-kernel.XXXX) + +function cleanup { + rm -rf "${fake_repo_dir}" +} + +trap cleanup EXIT + +function usage() { + cat << EOT +Usage: $0 +Install the containers clear kernel image from "${repo_owner}/${repo_name}". + +version: Use 'latest' to pull latest kernel or a version from "${cc_linux_releases_url}" +EOT + + exit 1 +} + +#Get latest version by checking remote tags +#We dont ask to github api directly because force a user to provide a GITHUB token +function get_latest_version { + pushd "${fake_repo_dir}" >> /dev/null + git init -q + git remote add origin https://github.com/"${repo_owner}/${repo_name}".git + + cc_release=$(git ls-remote --tags 2>/dev/null \ + | grep -oP '\-\d+\.container' \ + | grep -oP '\d+' \ + | sort -n | \ + tail -1 ) + + tag=$(git ls-remote --tags 2>/dev/null \ + | grep -oP "v\d+\.\d+\.\d+\-${cc_release}.container" \ + | tail -1) + + popd >> /dev/null + echo "${tag}" +} + +function download_kernel() { + local version="$1" + arch=$(arch) + [ -n "${version}" ] || die "version not provided" + [ "${version}" == "latest" ] && version=$(get_latest_version) + echo "version to install ${version}" + local binaries_dir="${version}-binaries" + local binaries_tarball="${binaries_dir}.tar.gz" + local shasum_file="SHA512SUMS" + if [ "$arch" = x86_64 ]; then + curl -OL "${linux_releases_url}/download/${version}/${binaries_tarball}" + curl -OL "${linux_releases_url}/download/${version}/${shasum_file}" + sha512sum -c "${shasum_file}" + tar xf "${binaries_tarball}" + else + die "Unsupported architecture: $arch" + fi + + pushd "${binaries_dir}" + sudo make install + popd +} + +cc_kernel_version="$1" + +[ -z "${cc_kernel_version}" ] && usage +download_kernel "${cc_kernel_version}" + +# Make symbolic link to kata-containers +# FIXME: see https://github.com/kata-containers/packaging/issues/1 +sudo ln -s /usr/share/clear-containers/vmlinux.container /usr/share/kata-containers/ +sudo ln -s /usr/share/clear-containers/vmlinuz.container /usr/share/kata-containers/ diff --git a/.ci/install_proxy.sh b/.ci/install_proxy.sh new file mode 100755 index 000000000..657b01645 --- /dev/null +++ b/.ci/install_proxy.sh @@ -0,0 +1,14 @@ +#!/bin/bash +# +# Copyright (c) 2017-2018 Intel Corporation +# +# SPDX-License-Identifier: Apache-2.0 +# + +set -e + +cidir=$(dirname "$0") + +source "${cidir}/lib.sh" + +clone_build_and_install "github.com/kata-containers/proxy" diff --git a/.ci/install_qemu_lite.sh b/.ci/install_qemu_lite.sh new file mode 100755 index 000000000..05bde4bde --- /dev/null +++ b/.ci/install_qemu_lite.sh @@ -0,0 +1,38 @@ +#!/bin/bash +# +# Copyright (c) 2017-2018 Intel Corporation +# +# SPDX-License-Identifier: Apache-2.0 +# + +set -e + +arch=$(arch) + +if [ "$#" -ne 3 ]; then + echo "Usage: $0 " + echo " Install the QEMU_LITE_VERSION from clear CLEAR_RELEASE." + exit 1 +fi + +clear_release="$1" +qemu_lite_version="$2" +distro="$3" +qemu_lite_bin="qemu-lite-bin-${qemu_lite_version}.${arch}.rpm" +qemu_lite_data="qemu-lite-data-${qemu_lite_version}.${arch}.rpm" + +echo -e "Install qemu-lite ${qemu_lite_version}" + +# download packages +curl -LO "https://download.clearlinux.org/releases/${clear_release}/clear/${arch}/os/Packages/${qemu_lite_bin}" +curl -LO "https://download.clearlinux.org/releases/${clear_release}/clear/${arch}/os/Packages/${qemu_lite_data}" + +# install packages +if [ "$distro" == "ubuntu" ]; then + sudo alien -i "./${qemu_lite_bin}" + sudo alien -i "./${qemu_lite_data}" +fi + +# cleanup +rm -f "./${qemu_lite_bin}" +rm -f "./${qemu_lite_data}" diff --git a/.ci/install_runtime.sh b/.ci/install_runtime.sh new file mode 100755 index 000000000..dfa61d7a7 --- /dev/null +++ b/.ci/install_runtime.sh @@ -0,0 +1,53 @@ +#!/bin/bash +# +# Copyright (c) 2017-2018 Intel Corporation +# +# SPDX-License-Identifier: Apache-2.0 +# + +set -e + +cidir=$(dirname "$0") + +source "${cidir}/lib.sh" + +# Modify the runtimes build-time defaults + +# enable verbose build +export V=1 + +# tell the runtime build to use sane defaults +export SYSTEM_BUILD_TYPE=kata + +# The runtimes config file should live here +export SYSCONFDIR=/etc + +# Artifacts (kernel + image) live below here +export SHAREDIR=/usr/share + +runtime_config_path="${SYSCONFDIR}/kata-containers/configuration.toml" + +PKGDEFAULTSDIR="${SHAREDIR}/defaults/kata-containers" +NEW_RUNTIME_CONFIG="${PKGDEFAULTSDIR}/configuration.toml" +# Note: This will also install the config file. +clone_build_and_install "github.com/kata-containers/runtime" + +# Check system supports running Kata Containers +kata-runtime kata-check + +if [ -e "${NEW_RUNTIME_CONFIG}" ]; then + # Remove the legacy config file + sudo rm -f "${runtime_config_path}" + + # Use the new path + runtime_config_path="${NEW_RUNTIME_CONFIG}" +fi + +echo "Enabling all debug options in file ${runtime_config_path}" +sudo sed -i -e 's/^#\(enable_debug\).*=.*$/\1 = true/g' "${runtime_config_path}" + +echo "Add runtime as a new/default Docker runtime. Docker version \"$(docker --version)\" could change according to updates." +docker_options="-D --add-runtime kata-runtime=/usr/local/bin/kata-runtime" + +echo "Add kata-runtime as a new/default Docker runtime." +"${cidir}/../cmd/container-manager/manage_ctr_mgr.sh" docker configure -r kata-runtime -f diff --git a/.ci/install_shim.sh b/.ci/install_shim.sh new file mode 100755 index 000000000..20196f841 --- /dev/null +++ b/.ci/install_shim.sh @@ -0,0 +1,14 @@ +#!/bin/bash +# +# Copyright (c) 2017-2018 Intel Corporation +# +# SPDX-License-Identifier: Apache-2.0 +# + +set -e + +cidir=$(dirname "$0") + +source "${cidir}/lib.sh" + +clone_build_and_install "github.com/kata-containers/shim" diff --git a/.ci/lib.sh b/.ci/lib.sh new file mode 100755 index 000000000..afbbe28a9 --- /dev/null +++ b/.ci/lib.sh @@ -0,0 +1,61 @@ +#!/bin/bash +# +# Copyright (c) 2017-2018 Intel Corporation +# +# SPDX-License-Identifier: Apache-2.0 +# + +set -e + +_runtime_repo="github.com/kata-containers/runtime" +# FIXME: Issue https://github.com/kata-containers/packaging/issues/1 +_versions_file="$GOPATH/src/github.com/clearcontainers/runtime/versions.txt" + +export KATA_RUNTIME=${KATA_RUNTIME:-cc} + +# If we fail for any reason a message will be displayed +die(){ + msg="$*" + echo "ERROR: $msg" >&2 + exit 1 +} + +function clone_and_build() { + github_project="$1" + make_target="$2" + project_dir="${GOPATH}/src/${github_project}" + + echo "Retrieve repository ${github_project}" + go get -d ${github_project} || true + + # fixme: once tool to parse and get branches from github is + # completed, add it here to fetch branches under testing + + pushd ${project_dir} + + echo "Build ${github_project}" + if [ ! -f Makefile ]; then + echo "Run autogen.sh to generate Makefile" + bash -f autogen.sh + fi + + make + + popd +} + +function clone_build_and_install() { + clone_and_build $1 $2 + pushd "${GOPATH}/src/${1}" + echo "Install repository ${1}" + sudo -E PATH=$PATH KATA_RUNTIME=${KATA_RUNTIME} make install + popd +} + +function get_cc_versions(){ + # This is needed in order to retrieve the version for qemu-lite + cc_runtime_repo="github.com/clearcontainers/runtime" + go get -d -u -v "$cc_runtime_repo" || true + [ ! -f "$_versions_file" ] && { echo >&2 "ERROR: cannot find $_versions_file"; exit 1; } + source "$_versions_file" +} diff --git a/.ci/setup.sh b/.ci/setup.sh new file mode 100755 index 000000000..3335c0f08 --- /dev/null +++ b/.ci/setup.sh @@ -0,0 +1,33 @@ +#!/bin/bash +# +# Copyright (c) 2017-2018 Intel Corporation +# +# SPDX-License-Identifier: Apache-2.0 +# + +set -e + +cidir=$(dirname "$0") +source /etc/os-release +source "${cidir}/lib.sh" + +echo "Set up environment" +if [ "$ID" == ubuntu ];then + bash -f "${cidir}/setup_env_ubuntu.sh" +else + die "ERROR: Unrecognised distribution." + exit 1 +fi + +echo "Install shim" +bash -f ${cidir}/install_shim.sh + +echo "Install proxy" +bash -f ${cidir}/install_proxy.sh + +echo "Install runtime" +bash -f ${cidir}/install_runtime.sh + +echo "Drop caches" +sync +sudo -E PATH=$PATH bash -c "echo 3 > /proc/sys/vm/drop_caches" diff --git a/.ci/setup_env_ubuntu.sh b/.ci/setup_env_ubuntu.sh new file mode 100755 index 000000000..3190b3a72 --- /dev/null +++ b/.ci/setup_env_ubuntu.sh @@ -0,0 +1,70 @@ +#!/bin/bash +# +# Copyright (c) 2017-2018 Intel Corporation +# +# SPDX-License-Identifier: Apache-2.0 +# + +set -e + +cidir=$(dirname "$0") +source "/etc/os-release" +source "${cidir}/lib.sh" +get_cc_versions + +arch=$(arch) + +if [ "$arch" = x86_64 ]; then + if grep -q "N" /sys/module/kvm_intel/parameters/nested; then + echo "enable Nested Virtualization" + sudo modprobe -r kvm_intel + sudo modprobe kvm_intel nested=1 + fi +else + die "Unsupported architecture: $arch" +fi + +echo "Update apt repositories" +sudo -E apt update + +echo "Install chronic" +sudo -E apt install -y moreutils + +echo "Install kata containers dependencies" +chronic sudo -E apt install -y libtool automake autotools-dev autoconf bc alien libpixman-1-dev coreutils + +if ! command -v docker > /dev/null; then + "${cidir}/../cmd/container-manager/manage_ctr_mgr.sh" docker install +fi + +echo "Install qemu-lite binary" +"${cidir}/install_qemu_lite.sh" "${qemu_lite_clear_release}" "${qemu_lite_sha}" "$ID" + +echo "Install kata-containers image" +"${cidir}/install_kata_image.sh" + +echo "Install CRI-O dependencies for all Ubuntu versions" +chronic sudo -E apt install -y libglib2.0-dev libseccomp-dev libapparmor-dev libgpgme11-dev + +echo "Install bison binary" +chronic sudo -E apt install -y bison + +echo "Install libudev-dev" +chronic sudo -E apt-get install -y libudev-dev + +echo "Install Build Tools" +sudo -E apt install -y build-essential python pkg-config zlib1g-dev + +echo "Install Kata Containers Kernel" +"${cidir}/install_kata_kernel.sh" "latest" + +echo -e "Install CRI-O dependencies available for Ubuntu $VERSION_ID" +sudo -E apt install -y libdevmapper-dev btrfs-tools util-linux + +if [ "$VERSION_ID" == "16.04" ]; then + echo "Install os-tree" + sudo -E add-apt-repository ppa:alexlarsson/flatpak -y + sudo -E apt update +fi + +sudo -E apt install -y libostree-dev diff --git a/cmd/container-manager/manage_ctr_mgr.sh b/cmd/container-manager/manage_ctr_mgr.sh new file mode 100755 index 000000000..7190cfc9c --- /dev/null +++ b/cmd/container-manager/manage_ctr_mgr.sh @@ -0,0 +1,321 @@ +#!/bin/bash -e +# +# Copyright (c) 2017-2018 Intel Corporation +# +# SPDX-License-Identifier: Apache-2.0 +# + +DOCKER_BIN=docker +SCRIPT_PATH=$(dirname "$(readlink -f "$0")") +SCRIPT_NAME=${0##*/} +source "${SCRIPT_PATH}/../../.ci/lib.sh" +source /etc/os-release + +force=false +ctr_manager="" +subcommand="" +runtime="" +tag="" + +get_cc_versions > /dev/null 2>&1 + +usage(){ + cat << EOF +This script helps you install the correct version of docker +to use with Clear Containers. +WARNING: Using this tool with -f flag, will overwrite any docker configuration that you may +have modified. +Usage: $SCRIPT_NAME [docker] [configure|info|install|remove] +Options: + -f : Force action. It will replace any installation + or configuration that you may have. + -h : Help, show this information. + -r : Supported runtimes: runc and cc-runtime. + -t : Tags supported: swarm, latest. If you do not specify + a tag, the script will use latest as default. + With this tag you can install the correct version + of docker that has CC compatibility with swarm. +Example: + ./$SCRIPT_NAME docker install -t swarm -f +EOF +} + +die(){ + msg="$*" + echo "$SCRIPT_NAME - ERROR: $msg" >&2 + exit 1 +} + +warning(){ + msg="$*" + echo "$SCRIPT_NAME - WARNING: $msg" >&2 +} + +message(){ + msg="$*" + echo "$SCRIPT_NAME - INFO: $msg" >&2 +} + +log_message(){ + message="$1" + logger -s -t "$(basename $0)" "$message" +} + +parse_subcommand_options(){ + while getopts ":fr:t:" opt; do + case $opt in + f) + force=true + ;; + r) + runtime="${OPTARG}" + ;; + t) + tag="${OPTARG}" + ;; + \?) + echo "Invalid option: -${OPTARG}" >&2 + usage + exit 1 + esac + done +} + +# This function handles the installation of the required docker version. +install_docker(){ + # Check if docker is present in the system + if [ "$(info_docker)" ] && [ ${force} == false ]; then + die "Docker is already installed. Please use -f flag to force new installation" + elif [ "$(info_docker)" ] && [ ${force} == true ]; then + remove_docker + fi + + if [ -z "$tag" ] || [ "$tag" == "latest" ] ; then + # If no tag is recevied, install latest compatible version + log_message "Installing docker $docker_version" + docker_version=${docker_version/v} + docker_version=${docker_version/-*} + pkg_name="docker-ce" + if [ "$ID" == "ubuntu" ]; then + sudo -E apt-get -y install apt-transport-https ca-certificates software-properties-common + repo_url="https://download.docker.com/linux/ubuntu" + curl -fsSL "${repo_url}/gpg" | sudo apt-key add - + sudo -E add-apt-repository "deb [arch=amd64] ${repo_url} $(lsb_release -cs) stable" + sudo -E apt-get update + docker_version_full=$(apt-cache show $pkg_name | grep "^Version: $docker_version" | awk '{print $2}' | head -1) + sudo -E apt-get -y install "${pkg_name}=${docker_version_full}" + elif [ "$ID" == "fedora" ]; then + repo_url="https://download.docker.com/linux/fedora/docker-ce.repo" + sudo -E dnf -y install dnf-plugins-core + sudo -E dnf config-manager --add-repo "$repo_url" + sudo -E dnf makecache + docker_version_full=$(dnf --showduplicate list "$pkg_name" | grep "$docker_version" | awk '{print $2}' | tail -1) + sudo -E dnf -y install "${pkg_name}-${docker_version_full}" + fi + elif [ "$tag" == "swarm" ]; then + # If tag is swarm, install docker 1.12.1 + log_message "Installing docker $docker_swarm_version" + pkg_name="docker-engine" + if [ "$ID" == "ubuntu" ]; then + # We stick to the xenial repo, since it is the only one that + # provides docker 1.12.1 + repo_url="https://apt.dockerproject.org" + sudo -E apt-get -y install apt-transport-https ca-certificates + curl -fsSL "${repo_url}/gpg" | sudo apt-key add - + sudo -E add-apt-repository "deb ${repo_url}/repo ubuntu-xenial main" + sudo -E apt-get update + docker_version_full=$(apt-cache show docker-engine | grep "^Version: $docker_swarm_version" | awk '{print $2}' | head -1) + sudo -E apt-get -y install --allow-downgrades "${pkg_name}=${docker_version_full}" + elif [ "$ID" == "fedora" ]; then + # We stick to the Fedora 24 repo, since it is the only one that + # provides docker 1.12.1 + repo_url="https://yum.dockerproject.org" + fedora24_repo="${repo_url}/repo/main/fedora/24" + gpg_key="gpg" + sudo -E dnf -y install dnf-plugins-core + sudo -E dnf config-manager --add-repo "${fedora24_repo}" + curl -O "${repo_url}/${gpg_key}" + sudo rpm --import "./${gpg_key}" + rm "./${gpg_key}" + sudo -E dnf makecache + docker_version_full=$(dnf --showduplicate list "$pkg_name" | grep "$docker_swarm_version" | awk '{print $2}' | tail -1) + sudo -E dnf -y install "${pkg_name}-${docker_version_full}" + fi + else + # If tag received is invalid, then return an error message + die "Unrecognized tag. Tag supported is: swarm" + fi + sudo systemctl restart docker + sudo gpasswd -a ${USER} docker + sudo chmod g+rw /var/run/docker.sock +} + +# This function removes the installed docker package. +remove_docker(){ + pkg_name=$(get_docker_package_name) + if [ -z "$pkg_name" ]; then + die "Docker not found in this system" + else + version=$(get_docker_version) + log_message "Removing package: $pkg_name version: $version" + if [ "$ID" == "ubuntu" ]; then + sudo apt -y purge "$pkg_name" + elif [ "$ID" == "fedora" ]; then + sudo dnf -y remove "$pkg_name" + else + die "This script doesn't support your Linux distribution" + fi + fi +} + +get_docker_default_runtime(){ + sudo docker info 2> /dev/null | awk '/Default Runtime/ {print $3}' +} + +get_docker_version(){ + sudo docker version | awk '/Server/{getline; print $2 }' +} + +get_docker_package_name(){ + if [ "$ID" == "ubuntu" ]; then + dpkg --get-selections | awk '/docker/ {print $1}' + elif [ "$ID" == "fedora" ]; then + rpm -qa | grep docker | grep -v selinux + else + die "This script doesn't support your Linux distribution" + fi +} + +# This function gives information about: +# - Installed docker package and version +# - docker default runtime +info_docker(){ + if command -v "$DOCKER_BIN"; then + message "docker_info: version: $(get_docker_version)" + message "docker_info: default runtime: $(get_docker_default_runtime)" + message "docker_info: package name: $(get_docker_package_name)" + else + warning "docker is not installed on this system" + return 1 + fi +} + +# Modify docker service using of $docker_options +modify_docker_service(){ + docker_options=$1 + docker_service_dir="/etc/systemd/system/docker.service.d/" + if [ "$(ls -A $docker_service_dir)" ] && [ ${force} == false ]; then + die "Found a service configuration file. Please use -f flag to overwrite the service configuration" + elif [ "$(ls -A $docker_service_dir)" ] && [ ${force} == true ]; then + rm -rf "${docker_service_dir}/*" + fi + sudo mkdir -p "$docker_service_dir" + cat <&2 + usage + exit 1 + ;; + esac + done + shift $((OPTIND -1)) + + ctr_manager=$1; shift + case "$ctr_manager" in + # Parse options + docker) + subcommand=$1; shift + parse_subcommand_options "$@" + ;; + *) + warning "container manager \"$ctr_manager\" is not supported." + usage + exit 1 + esac + + shift "$((OPTIND - 1))" + + case "$subcommand" in + configure ) + configure_docker + ;; + + info ) + info_docker + ;; + + install ) + install_docker + ;; + + remove ) + remove_docker + ;; + + *) + echo "Invalid subcommand: \"$subcommand\"" + usage + exit 1 + + esac + echo "Script finished" +} + +main "$@"