xref: /cloud-hypervisor/scripts/dev_cli.sh (revision 3f8cd52ffd74627242cb7e8ea1c2bdedadf6741a)
1#!/usr/bin/env bash
2
3# Copyright 2018 Amazon.com, Inc. or its affiliates. All Rights Reserved.
4# Copyright © 2020 Intel Corporation
5# SPDX-License-Identifier: Apache-2.0
6
7CLI_NAME="Cloud Hypervisor"
8
9CTR_IMAGE_TAG="ghcr.io/cloud-hypervisor/cloud-hypervisor"
10
11# Needs to match explicit version in docker-image.yaml workflow
12CTR_IMAGE_VERSION="20240507-0"
13: "${CTR_IMAGE:=${CTR_IMAGE_TAG}:${CTR_IMAGE_VERSION}}"
14
15DOCKER_RUNTIME="docker"
16
17# Host paths
18CLH_SCRIPTS_DIR=$(cd "$(dirname "$0")" && pwd)
19CLH_ROOT_DIR=$(cd "${CLH_SCRIPTS_DIR}/.." && pwd)
20CLH_BUILD_DIR="${CLH_ROOT_DIR}/build"
21CLH_CARGO_TARGET="${CLH_BUILD_DIR}/cargo_target"
22CLH_DOCKERFILE="${CLH_SCRIPTS_DIR}/../resources/Dockerfile"
23CLH_CTR_BUILD_DIR="/tmp/cloud-hypervisor/ctr-build"
24CLH_INTEGRATION_WORKLOADS="${HOME}/workloads"
25
26# Container paths
27CTR_CLH_ROOT_DIR="/cloud-hypervisor"
28CTR_CLH_CARGO_BUILT_DIR="${CTR_CLH_ROOT_DIR}/build"
29CTR_CLH_CARGO_TARGET="${CTR_CLH_CARGO_BUILT_DIR}/cargo_target"
30CTR_CLH_INTEGRATION_WORKLOADS="/root/workloads"
31
32# Container networking option
33CTR_CLH_NET="bridge"
34
35# Cargo paths
36# Full path to the cargo registry dir on the host. This appears on the host
37# because we want to persist the cargo registry across container invocations.
38# Otherwise, any rust crates from crates.io would be downloaded again each time
39# we build or test.
40CARGO_REGISTRY_DIR="${CLH_BUILD_DIR}/cargo_registry"
41
42# Full path to the cargo git registry on the host. This serves the same purpose
43# as CARGO_REGISTRY_DIR, for crates downloaded from GitHub repos instead of
44# crates.io.
45CARGO_GIT_REGISTRY_DIR="${CLH_BUILD_DIR}/cargo_git_registry"
46
47# Full path to the cargo target dir on the host.
48CARGO_TARGET_DIR="${CLH_BUILD_DIR}/cargo_target"
49
50# Send a decorated message to stdout, followed by a new line
51#
52say() {
53    [ -t 1 ] && [ -n "$TERM" ] &&
54        echo "$(tput setaf 2)[$CLI_NAME]$(tput sgr0) $*" ||
55        echo "[$CLI_NAME] $*"
56}
57
58# Send a decorated message to stdout, without a trailing new line
59#
60say_noln() {
61    [ -t 1 ] && [ -n "$TERM" ] &&
62        echo -n "$(tput setaf 2)[$CLI_NAME]$(tput sgr0) $*" ||
63        echo "[$CLI_NAME] $*"
64}
65
66# Send a text message to stderr
67#
68say_err() {
69    [ -t 2 ] && [ -n "$TERM" ] &&
70        echo "$(tput setaf 1)[$CLI_NAME] $*$(tput sgr0)" 1>&2 ||
71        echo "[$CLI_NAME] $*" 1>&2
72}
73
74# Send a warning-highlighted text to stdout
75say_warn() {
76    [ -t 1 ] && [ -n "$TERM" ] &&
77        echo "$(tput setaf 3)[$CLI_NAME] $*$(tput sgr0)" ||
78        echo "[$CLI_NAME] $*"
79}
80
81# Exit with an error message and (optional) code
82# Usage: die [-c <error code>] <error message>
83#
84die() {
85    code=1
86    [[ "$1" = "-c" ]] && {
87        code="$2"
88        shift 2
89    }
90    say_err "$@"
91    exit "$code"
92}
93
94# Exit with an error message if the last exit code is not 0
95#
96ok_or_die() {
97    code=$?
98    [[ $code -eq 0 ]] || die -c $code "$@"
99}
100
101# Make sure the build/ dirs are available. Exit if we can't create them.
102# Upon returning from this call, the caller can be certain the build/ dirs exist.
103#
104ensure_build_dir() {
105    for dir in "$CLH_BUILD_DIR" \
106        "$CLH_INTEGRATION_WORKLOADS" \
107        "$CLH_CTR_BUILD_DIR" \
108        "$CARGO_TARGET_DIR" \
109        "$CARGO_REGISTRY_DIR" \
110        "$CARGO_GIT_REGISTRY_DIR"; do
111        mkdir -p "$dir" || die "Error: cannot create dir $dir"
112        [ -x "$dir" ] && [ -w "$dir" ] ||
113            {
114                say "Wrong permissions for $dir. Attempting to fix them ..."
115                chmod +x+w "$dir"
116            } ||
117            die "Error: wrong permissions for $dir. Should be +x+w"
118    done
119}
120
121# Make sure we're using the latest dev container, by just pulling it.
122ensure_latest_ctr() {
123    if [ "$CTR_IMAGE_VERSION" = "local" ]; then
124        build_container
125    else
126        if ! $DOCKER_RUNTIME pull "$CTR_IMAGE"; then
127            build_container
128        fi
129
130        ok_or_die "Error pulling/building container image. Aborting."
131    fi
132}
133
134# Fix main directory permissions after a container ran as root.
135# Since the container ran as root, any files it creates will be owned by root.
136# This fixes that by recursively changing the ownership of /cloud-hypervisor to the
137# current user.
138#
139fix_dir_perms() {
140    # Yes, running Docker to get elevated privileges, just to chown some files
141    # is a dirty hack.
142    $DOCKER_RUNTIME run \
143        --workdir "$CTR_CLH_ROOT_DIR" \
144        --rm \
145        --volume /dev:/dev \
146        --volume "$CLH_ROOT_DIR:$CTR_CLH_ROOT_DIR" \
147        ${exported_volumes:+"$exported_volumes"} \
148        "$CTR_IMAGE" \
149        chown -R "$(id -u):$(id -g)" "$CTR_CLH_ROOT_DIR"
150
151    return "$1"
152}
153# Process exported volumes argument, separate the volumes and make docker compatible
154# Sample input: --volumes /a:/a#/b:/b
155# Sample output: --volume /a:/a --volume /b:/b
156#
157process_volumes_args() {
158    if [ -z "$arg_vols" ]; then
159        return
160    fi
161    exported_volumes=""
162    arr_vols=("${arg_vols//#/ }")
163    for var in "${arr_vols[@]}"; do
164        parts=("${var//:/ }")
165        if [[ ! -e "${parts[0]}" ]]; then
166            echo "The volume ${parts[0]} does not exist."
167            exit 1
168        fi
169        exported_volumes="$exported_volumes --volume $var"
170    done
171}
172
173cmd_help() {
174    echo ""
175    echo "Cloud Hypervisor $(basename "$0")"
176    echo "Usage: $(basename "$0") [flags] <command> [<command args>]"
177    echo ""
178    echo "Available flags":
179    echo ""
180    echo "    --local        Set the container image version being used to \"local\"."
181    echo ""
182    echo "Available commands:"
183    echo ""
184    echo "    build [--debug|--release] [--libc musl|gnu] [-- [<cargo args>]]"
185    echo "        Build the Cloud Hypervisor binaries."
186    echo "        --debug               Build the debug binaries. This is the default."
187    echo "        --release             Build the release binaries."
188    echo "        --libc                Select the C library Cloud Hypervisor will be built against. Default is gnu"
189    echo "        --volumes             Hash separated volumes to be exported. Example --volumes /mnt:/mnt#/myvol:/myvol"
190    echo "        --hypervisor          Underlying hypervisor. Options kvm, mshv"
191    echo ""
192    echo "    tests [<test type (see below)>] [--libc musl|gnu] [-- [<test scripts args>] [-- [<test binary args>]]] "
193    echo "        Run the Cloud Hypervisor tests."
194    echo "        --unit                       Run the unit tests."
195    echo "        --integration                Run the integration tests."
196    echo "        --integration-sgx            Run the SGX integration tests."
197    echo "        --integration-vfio           Run the VFIO integration tests."
198    echo "        --integration-windows        Run the Windows guest integration tests."
199    echo "        --integration-live-migration Run the live-migration integration tests."
200    echo "        --integration-rate-limiter   Run the rate-limiter integration tests."
201    echo "        --libc                       Select the C library Cloud Hypervisor will be built against. Default is gnu"
202    echo "        --metrics                    Generate performance metrics"
203    echo "        --volumes                    Hash separated volumes to be exported. Example --volumes /mnt:/mnt#/myvol:/myvol"
204    echo "        --hypervisor                 Underlying hypervisor. Options kvm, mshv"
205    echo "        --all                        Run all tests."
206    echo ""
207    echo "    build-container [--type]"
208    echo "        Build the Cloud Hypervisor container."
209    echo ""
210    echo "    clean [<cargo args>]]"
211    echo "        Remove the Cloud Hypervisor artifacts."
212    echo ""
213    echo "    shell"
214    echo "        Run the development container into an interactive, privileged BASH shell."
215    echo "        --volumes             Hash separated volumes to be exported. Example --volumes /mnt:/mnt#/myvol:/myvol"
216    echo ""
217    echo "    help"
218    echo "        Display this help message."
219    echo ""
220}
221
222cmd_build() {
223    build="debug"
224    libc="gnu"
225    hypervisor="kvm"
226    features_build=()
227    exported_device="/dev/kvm"
228    while [ $# -gt 0 ]; do
229        case "$1" in
230        "-h" | "--help") {
231            cmd_help
232            exit 1
233        } ;;
234        "--debug") { build="debug"; } ;;
235        "--release") { build="release"; } ;;
236        "--runtime")
237            shift
238            DOCKER_RUNTIME="$1"
239            export DOCKER_RUNTIME
240            ;;
241        "--libc")
242            shift
243            [[ "$1" =~ ^(musl|gnu)$ ]] ||
244                die "Invalid libc: $1. Valid options are \"musl\" and \"gnu\"."
245            libc="$1"
246            ;;
247        "--volumes")
248            shift
249            arg_vols="$1"
250            ;;
251        "--hypervisor")
252            shift
253            hypervisor="$1"
254            ;;
255        "--features")
256            shift
257            features_build=(--features "$1")
258            ;;
259        "--") {
260            shift
261            break
262        } ;;
263        *)
264            die "Unknown build argument: $1. Please use --help for help."
265            ;;
266        esac
267        shift
268    done
269
270    ensure_build_dir
271    ensure_latest_ctr
272
273    process_volumes_args
274    if [[ ! ("$hypervisor" = "kvm" || "$hypervisor" = "mshv") ]]; then
275        die "Hypervisor value must be kvm or mshv"
276    fi
277    if [[ "$hypervisor" = "mshv" ]]; then
278        exported_device="/dev/mshv"
279    fi
280    target="$(uname -m)-unknown-linux-${libc}"
281
282    cargo_args=("$@")
283    [ $build = "release" ] && cargo_args+=("--release")
284    cargo_args+=(--target "$target")
285
286    # shellcheck disable=SC2153
287    rustflags="$RUSTFLAGS"
288    target_cc=""
289    if [ "$(uname -m)" = "aarch64" ] && [ "$libc" = "musl" ]; then
290        rustflags="$rustflags -C link-args=-Wl,-Bstatic -C link-args=-lc"
291    fi
292
293    $DOCKER_RUNTIME run \
294        --user "$(id -u):$(id -g)" \
295        --workdir "$CTR_CLH_ROOT_DIR" \
296        --rm \
297        --volume $exported_device \
298        --volume "$CLH_ROOT_DIR:$CTR_CLH_ROOT_DIR" \
299        ${exported_volumes:+"$exported_volumes"} \
300        --env RUSTFLAGS="$rustflags" \
301        --env TARGET_CC="$target_cc" \
302        "$CTR_IMAGE" \
303        cargo build --all "${features_build[@]}" \
304        --target-dir "$CTR_CLH_CARGO_TARGET" \
305        "${cargo_args[@]}" && say "Binaries placed under $CLH_CARGO_TARGET/$target/$build"
306}
307
308cmd_clean() {
309    cargo_args=("$@")
310
311    ensure_build_dir
312    ensure_latest_ctr
313
314    $DOCKER_RUNTIME run \
315        --user "$(id -u):$(id -g)" \
316        --workdir "$CTR_CLH_ROOT_DIR" \
317        --rm \
318        --volume "$CLH_ROOT_DIR:$CTR_CLH_ROOT_DIR" \
319        ${exported_volumes:+"$exported_volumes"} \
320        "$CTR_IMAGE" \
321        cargo clean \
322        --target-dir "$CTR_CLH_CARGO_TARGET" \
323        "${cargo_args[@]}"
324}
325
326cmd_tests() {
327    unit=false
328    integration=false
329    integration_sgx=false
330    integration_vfio=false
331    integration_windows=false
332    integration_live_migration=false
333    integration_rate_limiter=false
334    metrics=false
335    libc="gnu"
336    arg_vols=""
337    hypervisor="kvm"
338    exported_device="/dev/kvm"
339    while [ $# -gt 0 ]; do
340        case "$1" in
341        "-h" | "--help") {
342            cmd_help
343            exit 1
344        } ;;
345        "--unit") { unit=true; } ;;
346        "--integration") { integration=true; } ;;
347        "--integration-sgx") { integration_sgx=true; } ;;
348        "--integration-vfio") { integration_vfio=true; } ;;
349        "--integration-windows") { integration_windows=true; } ;;
350        "--integration-live-migration") { integration_live_migration=true; } ;;
351        "--integration-rate-limiter") { integration_rate_limiter=true; } ;;
352        "--metrics") { metrics=true; } ;;
353        "--libc")
354            shift
355            [[ "$1" =~ ^(musl|gnu)$ ]] ||
356                die "Invalid libc: $1. Valid options are \"musl\" and \"gnu\"."
357            libc="$1"
358            ;;
359        "--volumes")
360            shift
361            arg_vols="$1"
362            ;;
363        "--hypervisor")
364            shift
365            hypervisor="$1"
366            ;;
367        "--all") {
368            unit=true
369            integration=true
370        } ;;
371        "--") {
372            shift
373            break
374        } ;;
375        *)
376            die "Unknown tests argument: $1. Please use --help for help."
377            ;;
378        esac
379        shift
380    done
381    if [[ ! ("$hypervisor" = "kvm" || "$hypervisor" = "mshv") ]]; then
382        die "Hypervisor value must be kvm or mshv"
383    fi
384
385    if [[ "$hypervisor" = "mshv" ]]; then
386        exported_device="/dev/mshv"
387    fi
388
389    if [ ! -e "${exported_device}" ]; then
390        die "${exported_device} does not exist on the system"
391    fi
392
393    set -- '--hypervisor' "$hypervisor" "$@"
394
395    ensure_build_dir
396    ensure_latest_ctr
397
398    process_volumes_args
399    target="$(uname -m)-unknown-linux-${libc}"
400
401    rustflags="$RUSTFLAGS"
402    target_cc=""
403    if [ "$(uname -m)" = "aarch64" ] && [ "$libc" = "musl" ]; then
404        rustflags="$rustflags -C link-args=-Wl,-Bstatic -C link-args=-lc"
405    fi
406
407    if [[ "$unit" = true ]]; then
408        say "Running unit tests for $target..."
409        $DOCKER_RUNTIME run \
410            --workdir "$CTR_CLH_ROOT_DIR" \
411            --rm \
412            --device $exported_device \
413            --device /dev/net/tun \
414            --cap-add net_admin \
415            --volume "$CLH_ROOT_DIR:$CTR_CLH_ROOT_DIR" \
416            ${exported_volumes:+"$exported_volumes"} \
417            --env BUILD_TARGET="$target" \
418            --env RUSTFLAGS="$rustflags" \
419            --env TARGET_CC="$target_cc" \
420            "$CTR_IMAGE" \
421            ./scripts/run_unit_tests.sh "$@" || fix_dir_perms $? || exit $?
422    fi
423
424    if [ "$integration" = true ]; then
425        say "Running integration tests for $target..."
426        $DOCKER_RUNTIME run \
427            --workdir "$CTR_CLH_ROOT_DIR" \
428            --rm \
429            --privileged \
430            --security-opt seccomp=unconfined \
431            --ipc=host \
432            --net="$CTR_CLH_NET" \
433            --mount type=tmpfs,destination=/tmp \
434            --volume /dev:/dev \
435            --volume "$CLH_ROOT_DIR:$CTR_CLH_ROOT_DIR" \
436            ${exported_volumes:+"$exported_volumes"} \
437            --volume "$CLH_INTEGRATION_WORKLOADS:$CTR_CLH_INTEGRATION_WORKLOADS" \
438            --env USER="root" \
439            --env BUILD_TARGET="$target" \
440            --env RUSTFLAGS="$rustflags" \
441            --env TARGET_CC="$target_cc" \
442            --env AUTH_DOWNLOAD_TOKEN="$AUTH_DOWNLOAD_TOKEN" \
443            "$CTR_IMAGE" \
444            dbus-run-session ./scripts/run_integration_tests_"$(uname -m)".sh "$@" || fix_dir_perms $? || exit $?
445    fi
446
447    if [ "$integration_sgx" = true ]; then
448        say "Running SGX integration tests for $target..."
449        $DOCKER_RUNTIME run \
450            --workdir "$CTR_CLH_ROOT_DIR" \
451            --rm \
452            --privileged \
453            --security-opt seccomp=unconfined \
454            --ipc=host \
455            --net="$CTR_CLH_NET" \
456            --mount type=tmpfs,destination=/tmp \
457            --volume /dev:/dev \
458            --volume "$CLH_ROOT_DIR:$CTR_CLH_ROOT_DIR" \
459            ${exported_volumes:+"$exported_volumes"} \
460            --volume "$CLH_INTEGRATION_WORKLOADS:$CTR_CLH_INTEGRATION_WORKLOADS" \
461            --env USER="root" \
462            --env BUILD_TARGET="$target" \
463            --env RUSTFLAGS="$rustflags" \
464            --env TARGET_CC="$target_cc" \
465            --env AUTH_DOWNLOAD_TOKEN="$AUTH_DOWNLOAD_TOKEN" \
466            "$CTR_IMAGE" \
467            ./scripts/run_integration_tests_sgx.sh "$@" || fix_dir_perms $? || exit $?
468    fi
469
470    if [ "$integration_vfio" = true ]; then
471        say "Running VFIO integration tests for $target..."
472        $DOCKER_RUNTIME run \
473            --workdir "$CTR_CLH_ROOT_DIR" \
474            --rm \
475            --privileged \
476            --security-opt seccomp=unconfined \
477            --ipc=host \
478            --net="$CTR_CLH_NET" \
479            --mount type=tmpfs,destination=/tmp \
480            --volume /dev:/dev \
481            --volume "$CLH_ROOT_DIR:$CTR_CLH_ROOT_DIR" \
482            ${exported_volumes:+"$exported_volumes"} \
483            --volume "$CLH_INTEGRATION_WORKLOADS:$CTR_CLH_INTEGRATION_WORKLOADS" \
484            --env USER="root" \
485            --env BUILD_TARGET="$target" \
486            --env RUSTFLAGS="$rustflags" \
487            --env TARGET_CC="$target_cc" \
488            --env AUTH_DOWNLOAD_TOKEN="$AUTH_DOWNLOAD_TOKEN" \
489            "$CTR_IMAGE" \
490            ./scripts/run_integration_tests_vfio.sh "$@" || fix_dir_perms $? || exit $?
491    fi
492
493    if [ "$integration_windows" = true ]; then
494        say "Running Windows integration tests for $target..."
495        $DOCKER_RUNTIME run \
496            --workdir "$CTR_CLH_ROOT_DIR" \
497            --rm \
498            --privileged \
499            --security-opt seccomp=unconfined \
500            --ipc=host \
501            --net="$CTR_CLH_NET" \
502            --mount type=tmpfs,destination=/tmp \
503            --volume /dev:/dev \
504            --volume "$CLH_ROOT_DIR:$CTR_CLH_ROOT_DIR" \
505            ${exported_volumes:+"$exported_volumes"} \
506            --volume "$CLH_INTEGRATION_WORKLOADS:$CTR_CLH_INTEGRATION_WORKLOADS" \
507            --env USER="root" \
508            --env BUILD_TARGET="$target" \
509            --env RUSTFLAGS="$rustflags" \
510            --env TARGET_CC="$target_cc" \
511            --env AUTH_DOWNLOAD_TOKEN="$AUTH_DOWNLOAD_TOKEN" \
512            "$CTR_IMAGE" \
513            ./scripts/run_integration_tests_windows_"$(uname -m)".sh "$@" || fix_dir_perms $? || exit $?
514    fi
515
516    if [ "$integration_live_migration" = true ]; then
517        say "Running 'live migration' integration tests for $target..."
518        $DOCKER_RUNTIME run \
519            --workdir "$CTR_CLH_ROOT_DIR" \
520            --rm \
521            --privileged \
522            --security-opt seccomp=unconfined \
523            --ipc=host \
524            --net="$CTR_CLH_NET" \
525            --mount type=tmpfs,destination=/tmp \
526            --volume /dev:/dev \
527            --volume "$CLH_ROOT_DIR:$CTR_CLH_ROOT_DIR" \
528            ${exported_volumes:+"$exported_volumes"} \
529            --volume "$CLH_INTEGRATION_WORKLOADS:$CTR_CLH_INTEGRATION_WORKLOADS" \
530            --env USER="root" \
531            --env BUILD_TARGET="$target" \
532            --env RUSTFLAGS="$rustflags" \
533            --env TARGET_CC="$target_cc" \
534            --env AUTH_DOWNLOAD_TOKEN="$AUTH_DOWNLOAD_TOKEN" \
535            "$CTR_IMAGE" \
536            ./scripts/run_integration_tests_live_migration.sh "$@" || fix_dir_perms $? || exit $?
537    fi
538
539    if [ "$integration_rate_limiter" = true ]; then
540        say "Running 'rate limiter' integration tests for $target..."
541        $DOCKER_RUNTIME run \
542            --workdir "$CTR_CLH_ROOT_DIR" \
543            --rm \
544            --privileged \
545            --security-opt seccomp=unconfined \
546            --ipc=host \
547            --net="$CTR_CLH_NET" \
548            --mount type=tmpfs,destination=/tmp \
549            --volume /dev:/dev \
550            --volume "$CLH_ROOT_DIR:$CTR_CLH_ROOT_DIR" \
551            ${exported_volumes:+"$exported_volumes"} \
552            --volume "$CLH_INTEGRATION_WORKLOADS:$CTR_CLH_INTEGRATION_WORKLOADS" \
553            --env USER="root" \
554            --env BUILD_TARGET="$target" \
555            --env RUSTFLAGS="$rustflags" \
556            --env TARGET_CC="$target_cc" \
557            --env AUTH_DOWNLOAD_TOKEN="$AUTH_DOWNLOAD_TOKEN" \
558            "$CTR_IMAGE" \
559            ./scripts/run_integration_tests_rate_limiter.sh "$@" || fix_dir_perms $? || exit $?
560    fi
561
562    if [ "$metrics" = true ]; then
563        say "Generating performance metrics for $target..."
564        $DOCKER_RUNTIME run \
565            --workdir "$CTR_CLH_ROOT_DIR" \
566            --rm \
567            --privileged \
568            --security-opt seccomp=unconfined \
569            --ipc=host \
570            --net="$CTR_CLH_NET" \
571            --mount type=tmpfs,destination=/tmp \
572            --volume /dev:/dev \
573            --volume "$CLH_ROOT_DIR:$CTR_CLH_ROOT_DIR" \
574            ${exported_volumes:+"$exported_volumes"} \
575            --volume "$CLH_INTEGRATION_WORKLOADS:$CTR_CLH_INTEGRATION_WORKLOADS" \
576            --env USER="root" \
577            --env BUILD_TARGET="$target" \
578            --env RUSTFLAGS="$rustflags" \
579            --env TARGET_CC="$target_cc" \
580            --env RUST_BACKTRACE="${RUST_BACKTRACE}" \
581            --env AUTH_DOWNLOAD_TOKEN="$AUTH_DOWNLOAD_TOKEN" \
582            "$CTR_IMAGE" \
583            ./scripts/run_metrics.sh "$@" || fix_dir_perms $? || exit $?
584    fi
585
586    fix_dir_perms $?
587}
588
589build_container() {
590    ensure_build_dir
591
592    BUILD_DIR=/tmp/cloud-hypervisor/container/
593
594    mkdir -p $BUILD_DIR
595    cp "$CLH_DOCKERFILE" $BUILD_DIR
596
597    [ "$(uname -m)" = "aarch64" ] && TARGETARCH="arm64"
598    [ "$(uname -m)" = "x86_64" ] && TARGETARCH="amd64"
599
600    $DOCKER_RUNTIME build \
601        --target dev \
602        -t "$CTR_IMAGE" \
603        -f $BUILD_DIR/Dockerfile \
604        --build-arg TARGETARCH="$TARGETARCH" \
605        $BUILD_DIR
606}
607
608cmd_build-container() {
609    while [ $# -gt 0 ]; do
610        case "$1" in
611        "-h" | "--help") {
612            cmd_help
613            exit 1
614        } ;;
615        "--") {
616            shift
617            break
618        } ;;
619        *)
620            die "Unknown build-container argument: $1. Please use --help for help."
621            ;;
622        esac
623        shift
624    done
625
626    build_container
627}
628
629cmd_shell() {
630    while [ $# -gt 0 ]; do
631        case "$1" in
632        "-h" | "--help") {
633            cmd_help
634            exit 1
635        } ;;
636        "--volumes")
637            shift
638            arg_vols="$1"
639            ;;
640        "--") {
641            shift
642            break
643        } ;;
644        *) ;;
645
646        esac
647        shift
648    done
649    ensure_build_dir
650    ensure_latest_ctr
651    process_volumes_args
652    say_warn "Starting a privileged shell prompt as root ..."
653    say_warn "WARNING: Your $CLH_ROOT_DIR folder will be bind-mounted in the container under $CTR_CLH_ROOT_DIR"
654    $DOCKER_RUNTIME run \
655        -ti \
656        --workdir "$CTR_CLH_ROOT_DIR" \
657        --rm \
658        --privileged \
659        --security-opt seccomp=unconfined \
660        --ipc=host \
661        --net="$CTR_CLH_NET" \
662        --tmpfs /tmp:exec \
663        --volume /dev:/dev \
664        --volume "$CLH_ROOT_DIR:$CTR_CLH_ROOT_DIR" \
665        ${exported_volumes:+"$exported_volumes"} \
666        --volume "$CLH_INTEGRATION_WORKLOADS:$CTR_CLH_INTEGRATION_WORKLOADS" \
667        --env USER="root" \
668        --entrypoint bash \
669        "$CTR_IMAGE"
670
671    fix_dir_perms $?
672}
673
674if [ $# = 0 ]; then
675    cmd_help
676    say_err "Please specify command to run!"
677    exit 1
678fi
679
680# Parse main command line args.
681#
682while [ $# -gt 0 ]; do
683    case "$1" in
684    -h | --help) {
685        cmd_help
686        exit 1
687    } ;;
688    --local) {
689        CTR_IMAGE_VERSION="local"
690        CTR_IMAGE="${CTR_IMAGE_TAG}:${CTR_IMAGE_VERSION}"
691    } ;;
692    -*)
693        die "Unknown arg: $1. Please use \`$0 help\` for help."
694        ;;
695    *)
696        break
697        ;;
698    esac
699    shift
700done
701
702# $1 is now a command name. Check if it is a valid command and, if so,
703# run it.
704#
705declare -f "cmd_$1" >/dev/null
706ok_or_die "Unknown command: $1. Please use \`$0 help\` for help."
707
708cmd=cmd_$1
709shift
710
711$cmd "$@"
712