diff --git a/.gitignore b/.gitignore index d3d965ec950..f6771897f6b 100644 --- a/.gitignore +++ b/.gitignore @@ -67,14 +67,13 @@ dist-newstyle test_report.xml # IC-OS disk images -*-os.iso -*-img.tar.gz +ic-os.img.tar +ic-os.img # Various build artifacts /artifacts/ **/build **/build-tmp -**/build-out **/boot/version.txt **/bin/canister_sandbox **/bin/ic-btc-adapter @@ -86,7 +85,7 @@ test_report.xml **/bin/replica **/bin/state-tool **/bin/vsock_agent -**/bin/sandbox_launcher +**/bin/canister_sandbox **/bin/boundary-node-prober # Boundary node control plane binary diff --git a/Capsule.toml b/Capsule.toml index ba29b3dff94..24f52955d31 100644 --- a/Capsule.toml +++ b/Capsule.toml @@ -63,7 +63,6 @@ input = [ "artifacts/canisters/xnet-test-canister.wasm.gz", # IC-OS Build scripts "ic-os/guestos/scripts/*", - "ic-os/scripts/*", "gitlab-ci/src/job_scripts/*", "ic-os/guestos/bootloader/*", "ic-os/guestos/rootfs/**/*", diff --git a/gitlab-ci/config/00--child-pipeline-root.yml b/gitlab-ci/config/00--child-pipeline-root.yml index 05ba62a5427..82f727e8247 100644 --- a/gitlab-ci/config/00--child-pipeline-root.yml +++ b/gitlab-ci/config/00--child-pipeline-root.yml @@ -18,10 +18,6 @@ include: - local: /gitlab-ci/config/47--guest-os-test--guest-os-e2e-test.yml - local: /gitlab-ci/config/47--guest-os-test--e2e-scalability.yml - local: /gitlab-ci/config/48--determinism-test.yml -- local: /gitlab-ci/config/52--host-os-build--build-host-img.yml -- local: /gitlab-ci/config/52--host-os-build--build-update-img.yml -- local: /gitlab-ci/config/53--host-os-build--build-iso-img.yml -- local: /gitlab-ci/config/54--host-os-test--host-os-upgrade-test.yml .cargo-build-docker-protected: needs: [] # don't wait on other jobs by default diff --git a/gitlab-ci/config/00--common.yml b/gitlab-ci/config/00--common.yml index ac6eb10b8fb..a9bb13b208a 100644 --- a/gitlab-ci/config/00--common.yml +++ b/gitlab-ci/config/00--common.yml @@ -12,8 +12,6 @@ stages: # Files from the given stage should be prefixed with: - guest-os-test # 47-- - build-determinism-test # 48-- - e2e-tests # 50-- - - host-os-build # 52-- - - host-os-test # 54-- - prod-tests # 60-- # Shard prod tests into 5 groups, because there are 5 'cdnightly' testnet environments. # The stages are purely for visual convenience when rendering the pipeline in the GitLab UI. @@ -223,7 +221,7 @@ after_script: # - Build results are stored in non-persisted /cargo_target # - The container is destroyed and all non-persisted data is dropped, including /cargo_target image: - name: "registry.gitlab.com/dfinity-lab/core/docker/ic-build-nix:2022-03-29-0bd5868e7-680ce9a5065742d97e268e3889118eaf21a26a4a" + name: "registry.gitlab.com/dfinity-lab/core/docker/ic-build-nix:2022-03-29-09b55cf44-d94121860c64b161888521097e591ee2e25c0637" tags: # Build on runners that have following tags - dfinity diff --git a/gitlab-ci/config/30--cargo-build--child-pipeline.yml b/gitlab-ci/config/30--cargo-build--child-pipeline.yml index 3a5812dd97c..3bf0f2e60cc 100644 --- a/gitlab-ci/config/30--cargo-build--child-pipeline.yml +++ b/gitlab-ci/config/30--cargo-build--child-pipeline.yml @@ -45,7 +45,7 @@ cargo-build-release-linux-native: - .rules-parent-pipeline-autorun-on-trigger image: # Use the docker image without nix-shell - name: "registry.gitlab.com/dfinity-lab/core/docker/ic-build:2022-03-29-0bd5868e7-29457eb1fba2642d9df5cdc0022655acfea974cc" + name: "registry.gitlab.com/dfinity-lab/core/docker/ic-build:2022-03-29-09b55cf44-be6eecb8e51ffc7fc98bb891a45bc77bde931b58" variables: ARTIFACT_EXT: "" artifacts: @@ -67,7 +67,7 @@ cargo-build-canisters: ARTIFACT_EXT: "" image: # Use the docker image without nix-shell - name: "registry.gitlab.com/dfinity-lab/core/docker/ic-build:2022-03-29-0bd5868e7-29457eb1fba2642d9df5cdc0022655acfea974cc" + name: "registry.gitlab.com/dfinity-lab/core/docker/ic-build:2022-03-29-09b55cf44-be6eecb8e51ffc7fc98bb891a45bc77bde931b58" artifacts: paths: - "artifacts/canisters${ARTIFACT_EXT}/*" @@ -92,7 +92,7 @@ dfx-build-release-linux: - artifacts/sdk-release/* image: # Use the docker image without nix-shell - name: "registry.gitlab.com/dfinity-lab/core/docker/ic-build:2022-03-29-0bd5868e7-29457eb1fba2642d9df5cdc0022655acfea974cc" + name: "registry.gitlab.com/dfinity-lab/core/docker/ic-build:2022-03-29-09b55cf44-be6eecb8e51ffc7fc98bb891a45bc77bde931b58" variables: BUILD_COMMAND: "" CARGO_BUILD_TARGET: x86_64-unknown-linux-gnu diff --git a/gitlab-ci/config/52--host-os-build--build-base-img.yml b/gitlab-ci/config/52--host-os-build--build-base-img.yml deleted file mode 100644 index 520495af898..00000000000 --- a/gitlab-ci/config/52--host-os-build--build-base-img.yml +++ /dev/null @@ -1,33 +0,0 @@ -deploy-host-os-baseimg: - extends: - - .ubuntu-nix-docker-protected - - .rules-protected-branch-manual - stage: host-os-build - needs: [] - script: - - | - set -euo pipefail - - TAG=$(date '+%Y-%m-%d-%H%M') - - docker login -u "$DOCKER_HUB_USER" -p "$DOCKER_HUB_PASSWORD" - cd "${CI_PROJECT_DIR}/ic-os/hostos/rootfs" - docker build -q -t dfinity/hostos-base:"$TAG" -t dfinity/hostos-base:latest -f Dockerfile.base . - docker push dfinity/hostos-base:"$TAG" - - echo "Use the image with it's SHA256 DIGEST below for IC-OS Dockerfile" - docker inspect --format='{{index .RepoDigests 0}}' dfinity/hostos-base:"$TAG" - -build-host-os-baseimg: - extends: - - .cargo-build-docker - - .rules-dockerfile-base-changes - stage: host-os-build - needs: [] - script: - - | - set -euo pipefail - - TAG=$(date '+%Y-%m-%d-%H%M') - cd "${CI_PROJECT_DIR}/ic-os/hostos/rootfs" - docker build -t dfinity/hostos-base:"$TAG" -t dfinity/hostos-base:latest -f Dockerfile.base . diff --git a/gitlab-ci/config/52--host-os-build--build-host-img.yml b/gitlab-ci/config/52--host-os-build--build-host-img.yml deleted file mode 100644 index 95594102b22..00000000000 --- a/gitlab-ci/config/52--host-os-build--build-host-img.yml +++ /dev/null @@ -1,41 +0,0 @@ -host-os-diskimg: - needs: - - artifacts-upload-to-s3 - extends: - - .ubuntu-nix-docker-protected - - .rules-parent-pipeline-autorun-on-trigger - stage: host-os-build - retry: 2 - artifacts: - paths: - - ic-os/hostos/build-out/disk-img${BUILD_EXTRA_SUFFIX}/* - expire_in: 2 days - variables: - BUILD_EXTRA_ARGS: "" - BUILD_EXTRA_SUFFIX: "" - script: - - | - set -xeuo pipefail - - BUILD_OUT="build-out/disk-img${BUILD_EXTRA_SUFFIX}" - BUILD_TMP="build-tmp${BUILD_EXTRA_SUFFIX}" - UPLOAD_TARGET="host-os/disk-img${BUILD_EXTRA_SUFFIX}" - VERSION=$(cat VERSION) - export VERSION - echo "Build ID: ${VERSION}" - - cd "${CI_PROJECT_DIR}"/ic-os/hostos - # shellcheck disable=SC2086 # Expanding BUILD_EXTRA_ARGS into multiple parameters - buildevents cmd "${ROOT_PIPELINE_ID}" "${CI_JOB_ID}" build-host-img -- \ - capsule --passive -v -t "$(openssl sha256 <<<${BUILD_EXTRA_ARGS}${BUILD_EXTRA_SUFFIX})" -t "${VERSION}" -o "${BUILD_OUT}/**/*" -- \ - "${CI_PROJECT_DIR}"/gitlab-ci/src/job_scripts/lib/host-os-diskimg.sh \ - "$BUILD_OUT" "$BUILD_TMP" "$UPLOAD_TARGET" "$VERSION" - - buildevents cmd "$ROOT_PIPELINE_ID" "$CI_JOB_ID" rclone -- \ - "${CI_PROJECT_DIR}"/gitlab-ci/src/artifacts/rclone_upload.py --version="${VERSION}" "$BUILD_OUT" "$UPLOAD_TARGET" - - # XXX FIXME: host-os build is not currently reproducible - # extra placebo that logs as its inputs the outputs of the previous step - # the intention is to cach non-determinism on host's disk-img.tar.gz - # placebo -v -c "${CI_JOB_NAME}--check" -i "disk-img.tar.gz" -- \ - # /bin/echo "Logged hashes of outputs to honeycomb via placebo." diff --git a/gitlab-ci/config/52--host-os-build--build-update-img.yml b/gitlab-ci/config/52--host-os-build--build-update-img.yml deleted file mode 100644 index b04cbd8579e..00000000000 --- a/gitlab-ci/config/52--host-os-build--build-update-img.yml +++ /dev/null @@ -1,50 +0,0 @@ -host-os-updateimg: - needs: - - artifacts-upload-to-s3 - extends: - - .ubuntu-nix-docker-protected - - .rules-parent-pipeline-autorun-on-trigger - stage: host-os-build - artifacts: - paths: - - ic-os/hostos/build-out/update-img${BUILD_EXTRA_SUFFIX}/* - expire_in: 2 days - variables: - BUILD_EXTRA_ARGS: "" - BUILD_EXTRA_SUFFIX: "" - VERSION_SUFFIX: "" - script: - - | - set -xeuo pipefail - - BUILD_OUT="build-out/update-img${BUILD_EXTRA_SUFFIX}" - BUILD_TMP="build-tmp${BUILD_EXTRA_SUFFIX}" - UPLOAD_TARGET="host-os/update-img${BUILD_EXTRA_SUFFIX}" - VERSION=$(cat VERSION)${VERSION_SUFFIX} - echo "Build ID: ${VERSION}" - - cd "${CI_PROJECT_DIR}"/ic-os/hostos - # shellcheck disable=SC2086 # Expanding BUILD_EXTRA_ARGS into multiple parameters - buildevents cmd "${ROOT_PIPELINE_ID}" "${CI_JOB_ID}" build-host-update -- \ - capsule --passive -v -t "$(openssl sha256 <<<${BUILD_EXTRA_ARGS}${BUILD_EXTRA_SUFFIX})" -t "${VERSION}" -o "${BUILD_OUT}/**/*" -- \ - "${CI_PROJECT_DIR}"/gitlab-ci/src/job_scripts/lib/host-os-updateimg.sh \ - "$BUILD_OUT" "$BUILD_TMP" "$UPLOAD_TARGET" "$VERSION" - - "$CI_PROJECT_DIR"/gitlab-ci/src/artifacts/openssl-sign.sh "$BUILD_OUT" - - buildevents cmd "$ROOT_PIPELINE_ID" "$CI_JOB_ID" rclone -- \ - "${CI_PROJECT_DIR}"/gitlab-ci/src/artifacts/rclone_upload.py --version="${VERSION}" "$BUILD_OUT" "$UPLOAD_TARGET" - - # XXX FIXME: host-os build is not currently reproducible - # extra placebo that logs as its inputs the outputs of the previous step - # the intention is to cach non-determinism on host disk-img.tar.gz - # placebo -v -c "${CI_JOB_NAME}--check" -i "disk-img.tar.gz" -- \ - # /bin/echo "Logged hashes of outputs to honeycomb via placebo." - -host-os-updateimg-new: - extends: - - host-os-updateimg - variables: - BUILD_EXTRA_ARGS: "" - BUILD_EXTRA_SUFFIX: "" - VERSION_SUFFIX: "-new" diff --git a/gitlab-ci/config/53--host-os-build--build-iso-img.yml b/gitlab-ci/config/53--host-os-build--build-iso-img.yml deleted file mode 100644 index c58f5d68d9a..00000000000 --- a/gitlab-ci/config/53--host-os-build--build-iso-img.yml +++ /dev/null @@ -1,33 +0,0 @@ -host-os-iso: - needs: - - artifacts-upload-to-s3 - - guest-os-diskimg - - host-os-diskimg - dependencies: - - artifacts-upload-to-s3 - - guest-os-diskimg - - host-os-diskimg - extends: - - .ubuntu-nix-docker-protected - - .rules-parent-pipeline-autorun-on-trigger - stage: host-os-build - script: - - | - set -xeuo pipefail - VERSION=$(cat VERSION) - echo "Build ID: ${VERSION}" - - "$CI_PROJECT_DIR"/gitlab-ci/src/artifacts/rclone_download.py --remote-path=guest-os --blessed-only --out=guestos --git-rev 9817eb2304d45c2c6ec5e0050b8cc4e72919c314 - - BUILD_OUT="ic-os/setupos/build-out" - UPLOAD_TARGET="setup-os" - - ic-os/setupos/scripts/build-iso.sh \ - --guest-os=./guestos/disk-img/disk-img.tar.gz \ - --host-os=./ic-os/hostos/build-out/disk-img/host-disk-img.tar.gz \ - --output="$BUILD_OUT" - - "$CI_PROJECT_DIR"/gitlab-ci/src/artifacts/openssl-sign.sh "$BUILD_OUT" - - buildevents cmd "$ROOT_PIPELINE_ID" "$CI_JOB_ID" rclone -- \ - "${CI_PROJECT_DIR}"/gitlab-ci/src/artifacts/rclone_upload.py --version="${VERSION}" "$BUILD_OUT" "$UPLOAD_TARGET" diff --git a/gitlab-ci/config/54--host-os-test--host-os-upgrade-test.yml b/gitlab-ci/config/54--host-os-test--host-os-upgrade-test.yml deleted file mode 100644 index da4e52ad899..00000000000 --- a/gitlab-ci/config/54--host-os-test--host-os-upgrade-test.yml +++ /dev/null @@ -1,35 +0,0 @@ -.e2e-test-base: - extends: - # Use untrusted builders for e2e tests. - # The trusted builders don't work with IPv6 right now. - - .ubuntu-nix-docker - - .rules-parent-pipeline - stage: host-os-test - retry: 2 - # The e2e tests are flaky and impacting developer merges - # https://dfinity.slack.com/archives/C012RDFNK7U/p1618233620112900 - variables: - HOST_OS_TEST_TIMEOUT: 2400 - # This var is needed as some shell scripts depend on it. - E2E_TEST_TIMEOUT: 480 - -host-os-upgrade-test: - extends: - - .e2e-test-base - needs: - - host-os-diskimg - - host-os-updateimg-new - artifacts: - paths: - - ic-os/hostos/test-out - script: - - | - sudo apt -y install android-sdk-ext4-utils --no-install-recommends - - # shellcheck disable=SC2154 - $SHELL_WRAPPER timeout -k 10 "${HOST_OS_TEST_TIMEOUT}" \ - capsule -v \ - -i "ic-os/hostos/tests/*" \ - -i "ic-os/scripts/*" \ - -i "ic-os/hostos/build-out/disk-img/SHA256SUMS" -- \ - "$CI_PROJECT_DIR"/ic-os/hostos/tests/hostos-upgrade.sh "$CI_PROJECT_DIR" diff --git a/gitlab-ci/docker/Dockerfile b/gitlab-ci/docker/Dockerfile index aabc2a49a13..66e88a297e8 100644 --- a/gitlab-ci/docker/Dockerfile +++ b/gitlab-ci/docker/Dockerfile @@ -25,8 +25,7 @@ RUN ln -snf /usr/share/zoneinfo/$TZ /etc/localtime && echo $TZ > /etc/timezone & zip unzip rclone rsync bc csmith gcc lld lld-10 libc++-10-dev libcsmith-dev sqlite3 libsqlite3-dev libselinux-dev libunwind-dev \ qemu-system-x86 ovmf iproute2 dosfstools mtools fakeroot faketime android-sdk-ext4-utils \ policycoreutils python3 python3-requests python3-pip python3-gflags python3-cbor pipenv shellcheck bazel-5.0.0 \ - sudo docker-ce-cli ripgrep patchelf asciidoctor plantuml graphviz cpio nodejs npm gosu pigz \ - ca-certificates curl git isolinux p7zip-full syslinux xorriso && \ + sudo docker-ce-cli ripgrep patchelf asciidoctor plantuml graphviz cpio nodejs npm gosu pigz && \ gem install asciidoctor-diagram rouge && \ ln -s $(which bazel-5.0.0) /usr/bin/bazel diff --git a/gitlab-ci/docker/TAG b/gitlab-ci/docker/TAG index 05416fbfcd1..9be78112679 100644 --- a/gitlab-ci/docker/TAG +++ b/gitlab-ci/docker/TAG @@ -1 +1 @@ -2022-03-29-0bd5868e7 +2022-03-29-09b55cf44 diff --git a/gitlab-ci/src/job_scripts/lib/host-os-diskimg.sh b/gitlab-ci/src/job_scripts/lib/host-os-diskimg.sh deleted file mode 100755 index e4a2d08f604..00000000000 --- a/gitlab-ci/src/job_scripts/lib/host-os-diskimg.sh +++ /dev/null @@ -1,44 +0,0 @@ -#!/usr/bin/env bash -# -# Script for host-os-diskimg CI job -# - -set -euo pipefail - -BUILD_OUT=${1:-"build-out/disk-img"} -BUILD_TMP=${2:-"build-tmp"} -UPLOAD_TARGET=${3:-"host-os/disk-img"} -VERSION=${4:-$(git rev-parse --verify HEAD)} - -ROOT_DIR=$(git rev-parse --show-toplevel) -ls -lah /var/run/docker.sock -groups - -cd "$ROOT_DIR"/ic-os/hostos || exit 1 - -mkdir -p "$BUILD_OUT" "$BUILD_TMP" -echo "$VERSION" >"${BUILD_TMP}/version.txt" - -if [ -z "$CI_JOB_ID" ]; then - ./build.sh -v "$VERSION" "$BUILD_EXTRA_ARGS" - tar xzf disk-img.tar.gz -C "$BUILD_TMP" - tar --sort=name --owner=root:0 --group=root:0 --mtime='UTC 2020-01-01' --sparse \ - -cvzf "${BUILD_OUT}/host-disk-img.tar.gz" -C "$BUILD_TMP" disk.img version.txt - ls -lah "$BUILD_TMP" -else - buildevents cmd "${ROOT_PIPELINE_ID}" "${CI_JOB_ID}" build-disk-img -- \ - ./build.sh -v "$VERSION" "$BUILD_EXTRA_ARGS" - buildevents cmd "$ROOT_PIPELINE_ID" "$CI_JOB_ID" move-build -- \ - tar xzf disk-img.tar.gz -C "$BUILD_TMP" - buildevents cmd "$ROOT_PIPELINE_ID" "$CI_JOB_ID" tar-build-out -- \ - tar --sort=name --owner=root:0 --group=root:0 --mtime='UTC 2020-01-01' --sparse \ - -cvzf "${BUILD_OUT}/host-disk-img.tar.gz" -C "$BUILD_TMP" disk.img version.txt - ls -lah "$BUILD_TMP" - - "$ROOT_DIR"/gitlab-ci/src/artifacts/openssl-sign.sh "$BUILD_OUT" - - if [ "$CI_JOB_NAME" != "docker-build-all" ]; then - buildevents cmd "$ROOT_PIPELINE_ID" "$CI_JOB_ID" rclone -- \ - "$ROOT_DIR"/gitlab-ci/src/artifacts/rclone_upload.py "$BUILD_OUT" "$UPLOAD_TARGET" - fi -fi diff --git a/gitlab-ci/src/job_scripts/lib/host-os-updateimg.sh b/gitlab-ci/src/job_scripts/lib/host-os-updateimg.sh deleted file mode 100755 index 3a4a6dce7a5..00000000000 --- a/gitlab-ci/src/job_scripts/lib/host-os-updateimg.sh +++ /dev/null @@ -1,28 +0,0 @@ -#!/usr/bin/env bash - -set -euo pipefail - -BUILD_OUT=${1:-"build-out/disk-img"} -BUILD_TMP=${2:-"build-tmp"} -UPLOAD_TARGET=${3:-"host-os/disk-img"} -VERSION=${4:-$(git rev-parse --verify HEAD)} -ROOT_PASSWORD=${5:-""} - -ROOT_DIR=$(git rev-parse --show-toplevel) -ls -lah /var/run/docker.sock -groups - -cd "$ROOT_DIR" || exit 1 - -cd "$ROOT_DIR"/ic-os/hostos || exit 1 -mkdir -p "$BUILD_OUT" "$BUILD_TMP" -echo "$VERSION" >"${BUILD_TMP}/version.txt" -echo "${VERSION}" >"rootfs/opt/ic/share/version.txt" -echo "${VERSION}" >"rootfs/boot/version.txt" - -../scripts/build-docker-save.sh \ - --build-arg ROOT_PASSWORD="${ROOT_PASSWORD}" \ - ./rootfs >$BUILD_TMP/rootfs.tar - -../scripts/build-update-image.sh -o "${BUILD_OUT}/host-update-img.tar.gz" -i $BUILD_TMP/rootfs.tar "$BUILD_EXTRA_ARGS" -ls -lah "$BUILD_OUT" diff --git a/gitlab-ci/tools/build-ic b/gitlab-ci/tools/build-ic index e2587c1ba6e..217040c000e 100755 --- a/gitlab-ci/tools/build-ic +++ b/gitlab-ci/tools/build-ic @@ -154,8 +154,6 @@ if [ "$BUILD_IMAGES" == "true" ]; then fi echo -e "\n${HEADER_ICOS}\n" gitlab-ci/src/job_scripts/lib/guest-os-updateimg.sh "${DISK_DIR}" - # XXX FIXME: Avoid building host-os update image until artifact limit has been increased. - # gitlab-ci/src/job_scripts/lib/host-os-updateimg.sh "${DISK_DIR}" fi echo @@ -178,8 +176,6 @@ if [ "$BUILD_IMAGES" == "true" ] && [ "$BUILD_BINARIES" == "true" ] && [ "$BUILD echo IC-OS Image cd "$DISK_DIR" ls -1 update-img.tar.gz | xargs -n1 sha256sum | tee /tmp/update-img.txt - # XXX FIXME: Avoid building host-os update image until artifact limit has been increased. - # ls -1 host-update-img.tar.gz | xargs -n1 sha256sum | tee /tmp/host-update-img.txt echo fi @@ -193,7 +189,5 @@ if [ "$BUILD_CANISTERS" == "true" ]; then fi if [ "$BUILD_IMAGES" == "true" ] && [ "$BUILD_BINARIES" == "true" ] && [ "$BUILD_CANISTERS" == "true" ]; then sha256sum update-img.txt - # XXX FIXME: Avoid building host-os update image until artifact limit has been increased. - # sha256sum host-update-img.txt fi echo diff --git a/ic-os/README.adoc b/ic-os/README.adoc deleted file mode 100644 index c5c7e0561ec..00000000000 --- a/ic-os/README.adoc +++ /dev/null @@ -1,226 +0,0 @@ -= Ubuntu base OS XXX TODO - -This contains the build scripts for using full system images of Ubuntu -including the IC software stack as units of deployment and upgrade. - -== Quick build and test instructions - -To build a full system image, step into either `guestos` or `hostos` and run: - -[source,shell] ---- -./build.sh ---- - -When building your replica, nodemanger and other IC binaries, be sure *not* to use Nix to build those. -Instead do a docker based build as described here: https://github.com/dfinity/ic#building-the-code - -[source,shell] ---- - cd rs - ../gitlab-ci/tools/docker-run cargo build --bin ic-workload-generator --bin vsock_agent --bin state-tool --bin ic-consensus-pool-util --bin ic-crypto-csp --bin ic-regedit --bin ic-btc-adapter --bin ic-canister-http-adapter --release - ../gitlab-ci/tools/docker-run cargo build -p orchestrator -p ic-replica --release - # To build the NNS canisters needed for installing the NNS - cd ../ic-os/guestos - ../../gitlab-ci/tools/docker-run gitlab-ci/tools/cargo-build-canisters ---- - -If you want to include binaries that you have been locally building, append `-x`. -You might also want to set a password to be used `-p`. - -[source,shell] ---- -./build.sh -x ~/.cache/dfinity/cargo_target/debug/ ---- - -(Expected build time: ~90 seconds, including docker downloads and container -builds; ~20 seconds if docker cached). - -This can then be booted in qemu, e.g.: - -[source,shell] ---- -qemu-system-x86_64 \ - -display none -serial mon:stdio \ - -machine type=q35,accel=kvm -enable-kvm \ - -m 2G \ - -bios /usr/share/OVMF/OVMF_CODE.fd \ - -device virtio-blk-pci,drive=drive0,addr=2.0 -drive file=/tmp/disk.img,format=raw,id=drive0,if=none \ - -device pcie-root-port,id=pcie.1,chassis=1 \ - -netdev user,id=enp1s0,hostfwd=tcp::8080-:8080,hostfwd=tcp::22222-:22 \ - -device virtio-net-pci,netdev=enp1s0,bus=pcie.1,addr=0.0 ---- - -You can interact with the VM via the console now (note: issue "ctrl-a", "c" -to enter qemu console from here; issue "quit" to terminate the VM). - -You can also SSH into your qemu instance on [::1]:22222. - -The system is laid out such that there are two alternate system partitions -(called "A" and "B"): One is active at any point in time, the other is available -for writing updates into it. You can test this by first building a -partition image that can be put there as upgrade: - -[source,shell] ---- -scripts/build-ubuntu.sh -o /tmp/upgrade-image.tar ---- - -(Note that this is basically also built as part of the above full -disk image build). Transfer this in whatever way to the target system -and install it using the tool included, by running on the *target* *system*: - -[source,shell] ---- -cat /tmp/upgrade-image.tar | /opt/ic/bin/install-upgrade.sh -reboot ---- - -After that, the newly installed system will be booted. On next boot, it will -revert to the original system unless you previously confirm that the new -system is actually fully operational: - -[source,shell] ---- -/opt/ic/bin/manageboot.sh confirm ---- - -== Developing the Ubuntu system - -The entirety of the actual Ubuntu operating system is contained in the -rootfs/ subdirectory. See instructions there on how to -make changes to the OS. - -== Directory organization - -The directory rootfs/ contains everything related to building a bootable -Ubuntu system. It uses various template directories (e.g. /opt) that -are simply copied verbatim to the target system -- you can just drop -files there to include in the image. - -The directory bootloader/ contains everything related to building EFI -firmware and the grub bootloader image. It is configured to support -A/B partition split: - -All build scripts are contained in the scripts/ subdirectory. - -== CI build XXX TODO - -For CI purposes, the build is split such that the network-dependent -part (docker) is separated from the other parts of the build pipeline. - -To run these two steps separately, execute: - -[source,shell] ---- -scripts/build-docker.sh /tmp/dockertmp -scripts/build-disk-image.sh -o /tmp/disk.img -t /tmp/dockertmp/bootloader.tar -u /tmp/dockertmp/rootfs.tar ---- - -The "update artifact" image can be built using: - -[source,shell] ---- -scripts/build-docker.sh /tmp/dockertmp -scripts/build-ubuntu.sh -o /tmp/update-image.tar -i /tmp/dockertmp/rootfs.tar ---- - -== Docker container use - -The system can also be turned into a docker image that allows to boot an -entire testnet as a set of docker containers. See link:containerfs/README.adoc#[containerfs/] -for some initial build documentation. - -== Prerequisites - -docker, usual set of fs tools (sfdisk, ext4fs tools, vfat, ...) - -== Under the hood - -The ubuntu system is built by converting the official Ubuntu docker image -into a bootable "bare-metal" image (or "virtual-metal" VM image). This -results in a very minimal system with basically no services running at all. -All pre-configuration of the system is performed using docker utilities, -and the system is actually also fully operational as a docker container. -This means that development and testing can be done on the docker image -itself - actual VM image is only required for full end to end testing. - -== Prod deployment - -The prod deployment is facilitated using the following command: - -[source,shell] ---- -virt-install \ - --disk disk.img --import \ - --memory 4096 \ - --os-variant ubuntu20.04 \ - --network bridge=X \ - --network bridge=Y \ - --graphics none \ - --console pty,target.type=virtio --serial pty \ - --boot uefi \ - --noautoconsole ---- - -This sets up the following critical system pieces for operation: - -* a virtual harddisk driven by virtio-blk -* first virtual network device driven by virtio-net, using PCI bus 1 slot 0 -* second virtual network device driven by virtio-net, using PCI bus 2 slot 0 - -== Run a single machine NNS using qemu (e.g. on developer laptop) - -Generate key material and configuration files for the guest and the disk image with it: - -[source,shell] ---- -./boot-single-machine-nns.sh -cd guestos -./build.sh ---- - -Then start qemu as described above. - -Then, install the NNS: - -[source,shell] ---- -./scripts/install-nns.sh /tmp/tmp.3HNnhenaD8 ---- - -The directory given as argument is printed at the end of the `boot-single-machine-nns.sh` script. - -== Test base OS upgrades - -Boot a single machine NNS instance and run in qemu as described above. - -Build a base OS upgrade image and serve it via http. - -[source,shell] ---- -mkdir /tmp/upgrade -scripts/build-update-image.sh -o /tmp/upgrade/upgrade-image.tar -v 42 -(cd /tmp/upgrade; python -m http.server 8000 --bind ::) ---- - -Upgrade the NNS subnetwork. First, check the currently running version. - -[source,shell] ---- -/tmp/tmp.3HNnhenaD8/ic-admin --nns-url http://[::1]:8080 get-replica-version 0.1.0 ---- - -This should return a replica version record. Note that the record does not specify a base OS image yet. -Then, trigger the upgrade (currently, with a very recent ic-admin, which is not yet on master) - -[source,shell] ---- - export IP=192.168.178.139 - ic-admin --nns-url http://[::1]:8080 propose-to-bless-replica-version-flexible 42 \ - http://$IP:8000/upgrade-image.tar e592d1a0aa055da6e9436f95c2a7e7e96ed0417eebb55d6a5af0fa15a4cd0ce4 - ic-admin --nns-url=http://[::1]:8080 forward-test-neuron-vote ${PROPOSAL_ID} && ic-admin --nns-url=http://[::1]:8080 execute-eligible-proposals - ic-admin --nns-url=http://[::1]:8080 get-replica-version 42 - ic-admin --nns-url=http://[::1]:8080 get-subnet 0 | grep replica_version - ic-admin --nns-url=http://[::1]:8080 update-subnet-replica-version 0 42 ---- diff --git a/ic-os/guestos/rootfs/opt/ic/bin/generate-journalbeat-config.sh b/ic-os/guestos/rootfs/opt/ic/bin/generate-journalbeat-config.sh index a364d8899c0..8a0b0b85d91 100755 --- a/ic-os/guestos/rootfs/opt/ic/bin/generate-journalbeat-config.sh +++ b/ic-os/guestos/rootfs/opt/ic/bin/generate-journalbeat-config.sh @@ -66,11 +66,7 @@ JOURNALBEAT_TAGS="${journalbeat_tags}" if [ "${JOURNALBEAT_HOSTS}" != "" ]; then # Covert string into comma separated array - if [ "$(echo ${JOURNALBEAT_HOSTS} | grep ':')" ]; then - journalbeat_hosts_array=$(for host in ${JOURNALBEAT_HOSTS}; do echo -n "\"${host}\", "; done | sed -E "s@, \$@@g") - else - journalbeat_hosts_array=$(for host in ${JOURNALBEAT_HOSTS}; do echo -n "\"${host}:443\", "; done | sed -E "s@, \$@@g") - fi + journalbeat_hosts_array=$(for host in ${JOURNALBEAT_HOSTS}; do echo -n "\"${host}\", "; done | sed -E "s@, \$@@g") sed -e "s@{{ journalbeat_hosts }}@${journalbeat_hosts_array}@" "${IN_FILE}" >"${OUT_FILE}" fi diff --git a/ic-os/guestos/scripts/build-bootstrap-config-image.sh b/ic-os/guestos/scripts/build-bootstrap-config-image.sh index cd16691a5f8..d40933fc1c2 100755 --- a/ic-os/guestos/scripts/build-bootstrap-config-image.sh +++ b/ic-os/guestos/scripts/build-bootstrap-config-image.sh @@ -47,7 +47,7 @@ options may be specified: --journalbeat_hosts hosts Logging hosts to use. Can be multiple hosts separated by space (make sure to quote the argument string so it appears as a single argument to the - script, e.g. --journalbeat_hosts "h1.domain.tld h2.domain.tld"). + script, e.g. --journalbeat_hosts "h1.domain.tld:9220 h2.domain.tld:9230"). --journalbeat_tags tags Tags to be used by Journalbeat. Can be multiple tags separated by space diff --git a/ic-os/hostos/bootloader/Dockerfile b/ic-os/hostos/bootloader/Dockerfile deleted file mode 100644 index ada6ca5e639..00000000000 --- a/ic-os/hostos/bootloader/Dockerfile +++ /dev/null @@ -1,17 +0,0 @@ -FROM ubuntu:20.04 - -RUN apt-get -y update && apt-get -y upgrade && apt-get -y --no-install-recommends install \ - grub-efi-amd64-bin faketime - -# Copy all grub modules into their requisite place -RUN mkdir -p /boot/grub ; cp -r /usr/lib/grub/x86_64-efi /boot/grub - -# Build grub image itself into EFI directory tree -RUN mkdir -p /boot/efi/EFI/Boot -RUN faketime "2021-5-7 0" grub-mkimage -p "(,gpt2)/" -O x86_64-efi -o /boot/efi/EFI/Boot/bootx64.efi \ - boot linux search normal configfile \ - part_gpt btrfs ext2 fat iso9660 loopback \ - test keystatus gfxmenu regexp probe \ - efi_gop efi_uga all_video gfxterm font \ - echo read ls cat png jpeg halt reboot loadenv \ - lvm diff --git a/ic-os/hostos/bootloader/grub.cfg b/ic-os/hostos/bootloader/grub.cfg deleted file mode 100644 index b303d99255c..00000000000 --- a/ic-os/hostos/bootloader/grub.cfg +++ /dev/null @@ -1,89 +0,0 @@ -regexp -s boot_disk '^\(([a-z0-9]*),[a-z0-9]*\)/EFI/BOOT' $cmdpath - -set prefix=($boot_disk,gpt2) - -if [ -s $prefix/grubenv ]; then - load_env -fi - -# boot_alternative should be "A" or "B" to indicate whether we will use -# the A or B variant of the system (see below for mapping to -# partitions). -# If unset (very first boot), defaults to "A". -if [ "${boot_alternative}" = "" ]; then - set boot_alternative=A -fi - -# boot_cycle should be one of: -# -# - "install": this state exists only once, after initial install of the -# system -# -# - "stable": this indicates that we consider the system given in -# boot_alternative as "good": we will always try booting it -# -# - "first_boot": this indicates that we are booting for the very first -# time after an upgrade into the system given by "boot_alternative" -# we will boot this system and then go into "failsafe_check" state -# -# - "failsafe_check": we have tried booting the currently active system, -# but the target system did not 'acknowledge' that it got into a -# working state (by changing state to "stable" after it booted -# successfully) -# we will fall back to the alternative system and declare it stable -# -# If unset (very first boot), default to "stable" -if [ "${boot_cycle}" = "" ]; then - set boot_cycle=stable - save_env boot_alternative boot_cycle -fi - -if [ "${boot_cycle}" = "install" ]; then - set boot_cycle=stable - save_env boot_alternative boot_cycle - BOOT_STATE=install -elif [ "${boot_cycle}" = "first_boot" ]; then - set boot_cycle="failsafe_check" - save_env boot_alternative boot_cycle - BOOT_STATE=upgrade -elif [ "${boot_cycle}" = "failsafe_check" ]; then - if [ "${boot_alternative}" = "A"]; then - set boot_alternative=B - else - set boot_alternative=A - fi - set boot_cycle="stable" - save_env boot_alternative boot_cycle - BOOT_STATE=failsafe -else - BOOT_STATE=stable -fi - -if [ "${boot_alternative}" = "A" ]; then - set root=(lvm/hostlvm-A_boot) - set linux_root=/dev/hostlvm/A_root -else - set root=(lvm/hostlvm-B_boot) - set linux_root=/dev/hostlvm/B_root -fi - -echo Booting linux from system "${boot_alternative}" (state: "${boot_cycle}")... - -if [ -f ${boot}/extra_boot_args ]; then - echo Loading extra boot args ${boot}/extra_boot_args - # This is not really great -- we are directly sourcing the target - # file while we would only want a single variable out of it. - # I don't think there is another way. - source ${boot}/extra_boot_args - echo Extra boot arguments $EXTRA_BOOT_ARGS -fi - -linux /vmlinuz root=$linux_root console=ttyS0 dfinity.system=$boot_alternative dfinity.boot_state=$BOOT_STATE $EXTRA_BOOT_ARGS - -if [ -f ${boot}/initrd.img ]; then - echo Loading initial ram disk ${boot}/initrd.img - initrd ${boot}/initrd.img -fi - - -boot diff --git a/ic-os/hostos/bootloader/grubenv b/ic-os/hostos/bootloader/grubenv deleted file mode 100644 index f93ccbfff52..00000000000 --- a/ic-os/hostos/bootloader/grubenv +++ /dev/null @@ -1,2 +0,0 @@ -# GRUB Environment Block -####################################################################################################################################################################################################################################################################################################################################################################################################################################################################################################################################################################################################################################################################################################################################################################################################################################################################################################################################################################################################################################### \ No newline at end of file diff --git a/ic-os/hostos/build.sh b/ic-os/hostos/build.sh deleted file mode 100755 index 3c53d6f5e12..00000000000 --- a/ic-os/hostos/build.sh +++ /dev/null @@ -1,60 +0,0 @@ -#!/usr/bin/env bash -# Builds the IC hostOS image - -set -eo pipefail - -function usage() { - cat <"${BASE_DIR}/rootfs/opt/ic/share/version.txt" -echo "${VERSION}" >"${BASE_DIR}/rootfs/boot/version.txt" - -$SCRIPTS_DIR/build-docker-save.sh $BASE_DIR/bootloader >$BASE_DIR/bootloader.tar -$SCRIPTS_DIR/build-docker-save.sh \ - --build-arg ROOT_PASSWORD="${ROOT_PASSWORD}" \ - $BASE_DIR/rootfs >$BASE_DIR/rootfs.tar - -IMAGE_ID=$( - docker build -q -f $BASE_DIR/build/Dockerfile $BASE_DIR/.. 2>&1 \ - | tee /dev/fd/2 \ - | sed -e 's/sha256:\([0-9a-f]\{64\}\)/\1/' -e t -e d -) -docker run -h builder --cidfile cid --privileged $IMAGE_ID -CONTAINER_ID=$(cat cid) -docker cp $CONTAINER_ID:/ic-os/disk-img.tar.gz disk-img.tar.gz -docker cp $CONTAINER_ID:/ic-os/update-img.tar.gz update-img.tar.gz -docker rm $CONTAINER_ID diff --git a/ic-os/hostos/build/Dockerfile b/ic-os/hostos/build/Dockerfile deleted file mode 100644 index 2661b568f04..00000000000 --- a/ic-os/hostos/build/Dockerfile +++ /dev/null @@ -1,21 +0,0 @@ -# 20.04 -FROM ubuntu:focal-20211006 - -RUN apt-get -y update && \ - apt-get -y upgrade && \ - apt-get -y --no-install-recommends install \ - faketime \ - android-sdk-ext4-utils \ - lvm2 \ - dosfstools \ - fakeroot \ - mtools \ - policycoreutils \ - python3 - -WORKDIR ic-os - -COPY hostos . -COPY scripts scripts - -ENTRYPOINT ["/bin/bash", "build/build-disk-image.sh"] diff --git a/ic-os/hostos/build/build-disk-image.sh b/ic-os/hostos/build/build-disk-image.sh deleted file mode 100644 index b2686c8c159..00000000000 --- a/ic-os/hostos/build/build-disk-image.sh +++ /dev/null @@ -1,119 +0,0 @@ -#!/usr/bin/env bash - -# Build bootable full disk image containing the initial system image. - -set -eo pipefail - -# ----------------------------------------------------------------------- - -# Take a filesystem tree and turn it into a vfat filesystem image. -# -# Arguments: -# - $1: name of file to build filesystem image in; this must be a file truncated -# to the desired size of the filesystem to be built -# - $2: base directory of file system tree -function fstree_to_vfat() { - FS_IMAGE="$1" - FS_DIR="$2" - - mkfs.vfat -i 0 "${FS_IMAGE}" - - # Create all directories in sorted order - for d in $(cd "${FS_DIR}" && find . -mindepth 1 -type d | sed -e 's/^\.\///' | sort); do - faketime "1970-1-1 0" mmd -i "${FS_IMAGE}" "::/$d" - done - - # Copy all files in sorted order - for f in $(cd "${FS_DIR}" && find . -mindepth 1 -type f | sed -e 's/^\.\///' | sort); do - faketime "1970-1-1 0" mcopy -o -i "${FS_IMAGE}" "${FS_DIR}/$f" "::/$f" - done -} - -# Build bootloader -- this consists of the EFI System Partition (ESP) + -# a dedicated partition to hold grub modules and configuration. -# -# Arguments: -# - $1: name of the ESP image file; this must be a file truncated -# to the desired size of the filesystem to be built -# - $2: name of the grub partition image file; this must be a file truncated -# to the desired size of the filesystem to be built -# -# The function expects the "bootloader docker tarball" output on stdin. -function build_bootloader_from_tar() { - ESP_IMAGE="$1" - GRUB_IMAGE="$2" - - local FAKEROOT_STATE_FILE=$(mktemp -t fakerootstate-XXXXXXXXXXXX) - local DOCKER_EXTRACT_TMPDIR=$(mktemp -d -t bootloader-XXXXXXXXXXXX) - fakeroot -s "${FAKEROOT_STATE_FILE}" "${BASE_DIR}"/scripts/docker_extract.py "${DOCKER_EXTRACT_TMPDIR}" - - local EFI_FSDIR="${DOCKER_EXTRACT_TMPDIR}"/boot/efi - local GRUB_FSDIR="${DOCKER_EXTRACT_TMPDIR}"/boot/grub - cp bootloader/grub.cfg bootloader/grubenv "${GRUB_FSDIR}"/ - fstree_to_vfat "${ESP_IMAGE}" "${EFI_FSDIR}" - fstree_to_vfat "${GRUB_IMAGE}" "${GRUB_FSDIR}" - - rm -rf "${DOCKER_EXTRACT_TMPDIR}" -} - -# ----------------------------------------------------------------------- - -BASE_DIR=$(dirname "${BASH_SOURCE[0]}")/.. -source "${BASE_DIR}"/scripts/partitions.sh - -TMPDIR=$(mktemp -d -t build-image-XXXXXXXXXXXX) -UPDATE_DIR=$(mktemp -d -t build-image-XXXXXXXXXXXX) -trap "rm -rf $TMPDIR $UPDATE_DIR" exit - -DISK_IMG="disk.img" - -# Build bootloader partitions. -BOOTLOADER_TAR="bootloader.tar" -ESP_IMG="${TMPDIR}/esp.img" -GRUB_IMG="${TMPDIR}/grub.img" -truncate --size 100M "$ESP_IMG" -truncate --size 100M "$GRUB_IMG" -build_bootloader_from_tar "$ESP_IMG" "$GRUB_IMG" <"${BOOTLOADER_TAR}" - -# Prepare empty config partition. -CONFIG_IMG="${TMPDIR}/config.img" -truncate --size 100M "$CONFIG_IMG" -make_ext4fs -T 0 -l 100M "$CONFIG_IMG" - -# Prepare partitions for system image A. -UBUNTU_TAR="rootfs.tar" -BOOT_IMG="${TMPDIR}/boot.img" -ROOT_IMG="${TMPDIR}/root.img" -"${BASE_DIR}"/scripts/build-ubuntu.sh -i "${UBUNTU_TAR}" -r "${ROOT_IMG}" -b "${BOOT_IMG}" - -# Update Image -# HACK: allow running without explicitly given version, extract version -# from rootfs. This is NOT good, but workable for the moment. -VERSION=$(debugfs "${ROOT_IMG}" -R "cat /opt/ic/share/version.txt") - -echo "${VERSION}" >"${UPDATE_DIR}/VERSION.TXT" -cp "${TMPDIR}/boot.img" "${UPDATE_DIR}/boot.img" -cp "${TMPDIR}/root.img" "${UPDATE_DIR}/root.img" -# Sort by name in tar file -- makes ordering deterministic and ensures -# that VERSION.TXT is first entry, making it quick & easy to extract. -# Override owner, group and mtime to make build independent of the user -# building it. -tar czf "update-img.tar.gz" --sort=name --owner=root:0 --group=root:0 --mtime='UTC 2020-01-01' --sparse -C "${UPDATE_DIR}" . - -# Format LVM structure and write images into place -VOLUME_GROUP="hostlvm" -LVM_IMG="${TMPDIR}/lvm.img" -prepare_lvm_image "$LVM_IMG" 107374182400 "$VOLUME_GROUP" "4c7GVZ-Df82-QEcJ-xXtV-JgRL-IjLE-hK0FgA" "eu0VQE-HlTi-EyRc-GceP-xZtn-3j6t-iqEwyv" # 100G - -# Assemble all partitions -prepare_disk_image "$DISK_IMG" 108447924224 # 101G -write_single_partition "$DISK_IMG" esp "$ESP_IMG" -write_single_partition "$DISK_IMG" grub "$GRUB_IMG" -write_single_partition "$DISK_IMG" hostlvm "$LVM_IMG" -write_single_lvm_volume "$DISK_IMG" "$VOLUME_GROUP" A_boot "$BOOT_IMG" -write_single_lvm_volume "$DISK_IMG" "$VOLUME_GROUP" A_root "$ROOT_IMG" -write_single_lvm_volume "$DISK_IMG" "$VOLUME_GROUP" config "$CONFIG_IMG" - -# Package image in tar -tar --sparse -czaf disk-img.tar.gz "$DISK_IMG" -rm "$DISK_IMG" diff --git a/ic-os/hostos/build/partitions.csv b/ic-os/hostos/build/partitions.csv deleted file mode 100644 index 518386d477b..00000000000 --- a/ic-os/hostos/build/partitions.csv +++ /dev/null @@ -1,17 +0,0 @@ -# Partitions specification -# -# Each row takes the form: -# name,start,size,type,uuid,comment -# where -# name: identifier used for the partition (see design doc) -# start: start of partition in extents (512 bytes) -# size: size of partition in extents (512 bytes) -# type: a typecode recognized by sfdisk -# uuid: uuid for partition (to ensure that the build is deterministic) -# comment: free-form field explaining the partition -# -# Note that "start" and "size" need to match up correctly, otherwise -# partition table building will fail. -esp , 2048, 204800,U,f46600e3-d0e6-4258-9607-e64b13cf7595,EFI system partition -grub , 206848, 204800,L,1a7c28b7-efe0-4f17-9230-678cf2df8db2,Grub bootloader modules and config -hostlvm, 411648, 209715200,L,735a766a-2047-45c2-ab48-d5ec948de550,Partition for LVM PV diff --git a/ic-os/hostos/build/volumes.csv b/ic-os/hostos/build/volumes.csv deleted file mode 100644 index 7a0db298ef4..00000000000 --- a/ic-os/hostos/build/volumes.csv +++ /dev/null @@ -1,21 +0,0 @@ -# LVM volumes specification -# -# Each row takes the form: -# name,start,size,uuid,comment -# where -# name: identifier used for the partition (see design doc) -# start: start of partition in extents (4 MB) -# size: size of partition in extents (4 MB) -# uuid: uuid for partition (to ensure that the build is deterministic) -# comment: free-form field explaining the partition -# -# Note that "start" and "size" need to match up correctly, otherwise -# LVM volume building will fail. -config , 0, 25,SIs20R-l6gh-2Rli-KAP0-ZO88-3Y4q-G9JPAm,Config partition for HostOS -A_boot , 25, 256,0BQNUA-dzGu-wvW5-mMRh-Ptr6-J6DT-Ff2a9x,Boot partition for system A -A_root , 281, 2560,RM99J5-B2t1-JU3l-HNco-J2f2-1808-eJGo3s,Root partition for system A -A_var , 2841, 2560,AkcyNt-TkgJ-JL7M-UNoP-jWWC-Fhvh-86QyHG,Mutable data partition for system A -B_boot , 5401, 256,6gl2Fd-qm1V-9E3W-Arjv-J5mW-RqFO-EgYiNC,Boot partition for system B -B_root , 5657, 2560,UVBREu-GuBh-VHHb-RUAp-jjhQ-blIy-ez3Tjr,Root partition for system B -B_var , 8217, 2560,VNZoZ9-013f-hbEJ-Xd9C-AH6E-vAhI-KkzZ4p,Mutable data partition for system B -guestos,10777,13056,woW7RT-t6jS-cRo2-uENw-iQXu-ni2u-AZdHpq,GuestOS LVM partition diff --git a/ic-os/hostos/rootfs/Dockerfile b/ic-os/hostos/rootfs/Dockerfile deleted file mode 100644 index 0d7a98b887b..00000000000 --- a/ic-os/hostos/rootfs/Dockerfile +++ /dev/null @@ -1,259 +0,0 @@ -# HostOS - Main Docker Image -# -# Build steps: -# - `docker build --pull -t dfinity/hostos-main -f Dockerfile .` -# -# First build stage: -# - Download 3rd party tools -FROM ubuntu:20.04 AS download - -ENV TZ=UTC -RUN ln -snf /usr/share/zoneinfo/$TZ /etc/localtime && echo $TZ > /etc/timezone -RUN apt-get -y update && apt-get -y upgrade && apt-get -y --no-install-recommends install \ - ca-certificates \ - curl \ - perl - -# Download and verify journalbeat -RUN cd /tmp/ && \ - curl -L -O https://artifacts.elastic.co/downloads/beats/journalbeat/journalbeat-oss-7.14.0-linux-x86_64.tar.gz && \ - echo "3c97e8706bd0d2e30678beee7537b6fe6807cf858a0dd2e7cfce5beccb621eb0fefe6871027bc7b55e2ea98d7fe2ca03d4d92a7b264abbb0d6d54ecfa6f6a305 journalbeat-oss-7.14.0-linux-x86_64.tar.gz" > journalbeat.sha512 && \ - shasum -c journalbeat.sha512 - -# Download and verify node_exporter -RUN cd /tmp/ && \ - curl -L -O https://github.com/prometheus/node_exporter/releases/download/v1.3.1/node_exporter-1.3.1.linux-amd64.tar.gz && \ - echo "68f3802c2dd3980667e4ba65ea2e1fb03f4a4ba026cca375f15a0390ff850949 node_exporter-1.3.1.linux-amd64.tar.gz" > node_exporter.sha256 && \ - shasum -c node_exporter.sha256 - -# Download and verify QEMU -RUN cd /tmp/ && \ - curl -L -O https://download.qemu.org/qemu-6.2.0.tar.xz && \ - echo "68e15d8e45ac56326e0b9a4afa8b49a3dfe8aba3488221d098c84698bca65b45 qemu-6.2.0.tar.xz" > qemu.sha256 && \ - shasum -c qemu.sha256 - -# Second build stage: -# - Compile downloaded archives from first build stage -FROM ubuntu:20.04 AS build - -ENV TZ=UTC -RUN ln -snf /usr/share/zoneinfo/$TZ /etc/localtime && echo $TZ > /etc/timezone -RUN apt-get -y update && apt-get -y upgrade && apt-get -y --no-install-recommends install \ - ca-certificates \ - build-essential \ - libglib2.0-dev \ - libpixman-1-dev \ - libusb-1.0-0-dev \ - ninja-build \ - pkg-config \ - python3 - -# Configure and compile QEMU -COPY --from=download /tmp/qemu-6.2.0.tar.xz /tmp/qemu-6.2.0.tar.xz -RUN cd /tmp/ && \ - tar xJf qemu-6.2.0.tar.xz && \ - cd /tmp/qemu-6.2.0 && \ - ./configure --target-list=x86_64-softmmu --enable-kvm --enable-libusb && \ - echo "Compiling qemu..." && \ - make -j 2 >/dev/null 2>&1 && \ - DESTDIR="/out" ninja -C build install - -# Third build stage: -# - Construct the actual target image (IC-OS root filesystem) -# - Copy downloaded archives from first build stage into the target image -# - Copy compilation from second build stage into the target image -# -# Update below image when new dfinity/hostos-base image gets produced (see deploy-host-os-baseimg CI job on master/rc). -FROM dfinity/hostos-base@sha256:20ddb4e85ca1c5c3a0c60244432e99a66055c456ba438ae731db4d80cd7598da - -RUN mkdir -p /boot/config \ - /boot/efi \ - /boot/grub -COPY etc /etc - -# Update POSIX permissions in /etc/ -RUN find /etc -type d -exec chmod 0755 {} \+ && \ - find /etc -type f -not -path "/etc/hostname" -not -path "/etc/hosts" -not -path "/etc/resolv.conf" -exec chmod 0644 {} \+ && \ - chmod 0755 /etc/systemd/system-generators/mount-generator && \ - chmod 0440 /etc/sudoers && \ - chmod 755 /etc/initramfs-tools/scripts/init-bottom/set-machine-id - -# Deactivate motd, it tries creating $HOME/.cache/motd.legal-displayed, -# but we want to prohibit it from writing to user home dirs -RUN sed -e '/.*pam_motd.so.*/d' -i /etc/pam.d/login && \ - sed -e '/.*pam_motd.so.*/d' -i /etc/pam.d/sshd - -# Deactivate lvm backup/archive: It writes backup information to /etc/lvm, but a) this is -# per system (so backups are not persisted across upgrades) and thus not very -# useful, and b) we want to turn /etc read-only eventually. So simply suppress -# generating backups. -RUN sed -e 's/\(backup *= *\)1/\10/' -e 's/\(archive *= *\)1/\10/' -i /etc/lvm/lvm.conf - -# Deactivate systemd userdb. We don't use it. -RUN sed -e 's/ *systemd//' -i /etc/nsswitch.conf - -# Regenerate initramfs (config changed after copying in /etc) -RUN RESUME=none update-initramfs -c -k all - -ARG ROOT_PASSWORD= -RUN \ - if [ "${ROOT_PASSWORD}" != "" ]; then \ - echo "root:$(openssl passwd -6 -salt jE8zzDEHeRg/DuGq ${ROOT_PASSWORD})" | chpasswd -e ; \ - fi - -# Prepare for bind mount of authorized_keys -RUN mkdir -p /root/.ssh && chmod 0700 /root/.ssh - -# Delete generated ssh keys, otherwise every host will have the same key pair. -# They will be generated on first boot. -RUN rm /etc/ssh/ssh*key* -# Allow root login only via keys. In prod deployments there are never any -# keys set up for root, but in dev deployments there may be. -# Actually, prohibit-password is the default config, so would not be -# strictly necessary to be explicit here. -RUN sed -e "s/.*PermitRootLogin.*/PermitRootLogin prohibit-password/" -i /etc/ssh/sshd_config - -# All of the above sets up the base operating system. Everything below relates -# to node operation. - -RUN \ - for SERVICE in /etc/systemd/system/*; do \ - if [ -f "$SERVICE" -a ! -L "$SERVICE" ]; then systemctl enable "${SERVICE#/etc/systemd/system/}" ; fi ; \ - done - -RUN systemctl enable \ - chrony \ - libvirtd \ - nftables \ - systemd-journal-gatewayd \ - systemd-networkd \ - systemd-networkd-wait-online \ - systemd-resolved - -# Add user/group entries specified here: /usr/lib/sysusers.d/systemd.conf E.g., systemd-timesync/coredump -RUN faketime "1970-1-1 0" systemd-sysusers - -# Set /bin/sh to point to /bin/bash instead of the default /bin/dash -RUN echo "set dash/sh false" | debconf-communicate && dpkg-reconfigure -fnoninteractive dash - -# Group accounts to which parts of the runtime state are assigned such that -# user accounts can be granted individual access rights. -# Note that a group "backup" already exists and is used for the purpose of -# allowing backup read access. -RUN addgroup --system nonconfidential && \ - addgroup --system confidential && \ - addgroup --system vsock - -# User which will run the replica service. -RUN adduser --system --disabled-password --home /var/lib/ic --group --no-create-home ic-replica && \ - adduser ic-replica backup && \ - adduser ic-replica nonconfidential && \ - adduser ic-replica confidential && \ - adduser ic-replica vsock && \ - adduser ic-replica sudo - -# Accounts to allow remote access to state bits - -# The "backup" user account. We simply use the existing "backup" account and -# reconfigure it for our purposes. -RUN chsh -s /bin/bash backup && \ - mkdir /var/lib/backup && \ - chown backup:backup /var/lib/backup && \ - usermod -d /var/lib/backup backup && \ - adduser backup systemd-journal - -# The "read-only" user account. -RUN adduser --system --disabled-password --home /var/lib/readonly --shell /bin/bash readonly && \ - adduser readonly backup && \ - adduser readonly nonconfidential && \ - adduser readonly systemd-journal - -# The omnipotent "admin" account. May read everything and crucially can also -# arbitrarily change system state via sudo. -RUN adduser --system --disabled-password --home /var/lib/admin --shell /bin/bash admin && \ - chown admin:staff /var/lib/admin && \ - adduser admin backup && \ - adduser admin nonconfidential && \ - adduser admin systemd-journal && \ - adduser admin vsock && \ - adduser admin sudo - -# The "journalbeat" account. Used to run journalbeat binary to send logs of the -# GuestOS. -RUN addgroup journalbeat && \ - adduser --system --disabled-password --shell /usr/sbin/nologin -c "Journalbeat" journalbeat && \ - adduser journalbeat journalbeat && \ - adduser journalbeat systemd-journal - -# The "node_exporter" account. Used to run node_exporter binary to export -# telemetry metrics of the GuestOS. -RUN addgroup node_exporter && \ - adduser --system --disabled-password --shell /usr/sbin/nologin -c "Node Exporter" node_exporter && \ - adduser node_exporter node_exporter - -# Install journalbeat -COPY --from=download /tmp/journalbeat-oss-7.14.0-linux-x86_64.tar.gz /tmp/journalbeat-oss-7.14.0-linux-x86_64.tar.gz -RUN cd /tmp/ && \ - mkdir -p /etc/journalbeat \ - /var/lib/journalbeat \ - /var/log/journalbeat && \ - tar --strip-components=1 -C /etc/journalbeat/ -zvxf journalbeat-oss-7.14.0-linux-x86_64.tar.gz journalbeat-7.14.0-linux-x86_64/fields.yml && \ - tar --strip-components=1 -C /etc/journalbeat/ -zvxf journalbeat-oss-7.14.0-linux-x86_64.tar.gz journalbeat-7.14.0-linux-x86_64/journalbeat.reference.yml && \ - tar --strip-components=1 -C /usr/local/bin/ -zvxf journalbeat-oss-7.14.0-linux-x86_64.tar.gz journalbeat-7.14.0-linux-x86_64/journalbeat && \ - chown root:root /etc/journalbeat/*.yml \ - /usr/local/bin/journalbeat && \ - chown journalbeat:journalbeat /var/lib/journalbeat \ - /var/log/journalbeat && \ - chmod 0755 /etc/journalbeat && \ - chmod 0750 /var/lib/journalbeat \ - /var/log/journalbeat && \ - chmod 0644 /etc/journalbeat/*.yml && \ - rm /tmp/journalbeat-oss-7.14.0-linux-x86_64.tar.gz - -# Install node_exporter -COPY --from=download /tmp/node_exporter-1.3.1.linux-amd64.tar.gz /tmp/node_exporter-1.3.1.linux-amd64.tar.gz -RUN cd /tmp/ && \ - mkdir -p /etc/node_exporter && \ - tar --strip-components=1 -C /usr/local/bin/ -zvxf node_exporter-1.3.1.linux-amd64.tar.gz node_exporter-1.3.1.linux-amd64/node_exporter && \ - chown root:root /etc/node_exporter \ - /usr/local/bin/node_exporter && \ - chmod 0755 /etc/node_exporter \ - /usr/local/bin/node_exporter && \ - chmod 0644 /etc/default/node_exporter \ - /etc/node_exporter/web.yml && \ - rm /tmp/node_exporter-1.3.1.linux-amd64.tar.gz - -# Install QEMU -COPY --from=build /out/usr/local/bin/qemu-system-x86_64 /usr/local/bin/ -COPY --from=build /out/usr/local/share/qemu /usr/local/share/qemu - -# Compile locale specification -RUN localedef -i en_US -c -f UTF-8 -A /usr/share/locale/locale.alias en_US.UTF-8 - -# Clear all files that may lead to indeterministic build. -RUN apt-get clean && \ - rm -rf \ - /var/cache/fontconfig/* /var/cache/ldconfig/aux-cache \ - /var/log/alternatives.log /var/log/apt/history.log /var/log/apt/term.log /var/log/dpkg.log \ - /var/lib/apt/lists/* /var/lib/dbus/machine-id \ - /var/lib/initramfs-tools/5.8.0-50-generic && \ - find /usr/local/share/fonts -name .uuid | xargs rm && \ - find /usr/share/fonts -name .uuid | xargs rm && \ - find /usr/lib/python3.8 -name "*.pyc" | xargs rm && \ - find /usr/lib/python3 -name "*.pyc" | xargs rm && \ - find /usr/share/python3 -name "*.pyc" | xargs rm && \ - truncate --size 0 /etc/machine-id - -# Install IC binaries and other data late -- this means everything above -# will be cached when only the binaries change. -COPY opt /opt - -# Update POSIX permissions in /opt/ic/ -RUN find /opt -type d -exec chmod 0755 {} \+ && \ - find /opt -type f -exec chmod 0644 {} \+ && \ - chmod 0755 /opt/ic/bin/* && \ - chmod 0644 /opt/ic/share/* - -COPY boot /boot -# Update POSIX permissions in /boot/ -RUN chmod 0644 /boot/extra_boot_args /boot/version.txt diff --git a/ic-os/hostos/rootfs/Dockerfile.base b/ic-os/hostos/rootfs/Dockerfile.base deleted file mode 100644 index 901fe6c1301..00000000000 --- a/ic-os/hostos/rootfs/Dockerfile.base +++ /dev/null @@ -1,38 +0,0 @@ -# HostOS - Base Image -# -# Build steps: -# - `docker build -t dfinity/hostos-base: -f Dockerfile.base .` -# - `docker push/pull dfinity/hostos-base:` -# - `docker build -t dfinity/hostos-base-dev: --build-arg PACKAGE_FILES="packages.common packages.dev" -f Dockerfile.base .` -# - `docker push/pull dfinity/hostos-base-dev:` -# -# First build stage: -# - Download and cache minimal Ubuntu Server 20.04 LTS Docker image -# - Install and cache upstream packages from built-in Ubuntu repositories -# -# NOTE: -# If you edit this file, you will need to perform the following operations -# to get your changes deployed. -# -# 1. Get your MR approved and merged into master -# 2. On the next hourly master pipeline, click the "deploy-host-os-baseimg" job -# 3. Note down the sha256 and update the sha256 reference in the neighboring -# Dockerfiles -FROM ubuntu:20.04 - -ENV SOURCE_DATE_EPOCH=0 -ENV TZ=UTC -ENV DEBIAN_FRONTEND=noninteractive - - -# For the prod image, just use packages.common to define the packages installed -# on target. -# For the dev image, use both "packages.common" and "packages.dev" -- this can -# be set via docker build args (see above). -ARG PACKAGE_FILES=packages.common -RUN ln -snf /usr/share/zoneinfo/$TZ /etc/localtime && echo $TZ > /etc/timezone -COPY packages.* /tmp/ -RUN apt-get -y update && \ - apt-get -y upgrade && \ - apt-get -y --no-install-recommends install $(for P in ${PACKAGE_FILES}; do cat /tmp/$P | sed -e "s/#.*//" ; done) && \ - rm /tmp/packages.* diff --git a/ic-os/hostos/rootfs/README.adoc b/ic-os/hostos/rootfs/README.adoc deleted file mode 100644 index 0d1f30b0dec..00000000000 --- a/ic-os/hostos/rootfs/README.adoc +++ /dev/null @@ -1,133 +0,0 @@ -= Ubuntu base OS development - -The Ubuntu-based IC OS is built by: - -* creating a root filesystem image using docker -- this is based on the - official Ubuntu docker image and simply adds the OS kernel plus our - required services to it - -* converting this root filesystem into filesystem images for +/+ and +/boot+ - via +mke2fs+ - -The build instructions in the Dockerfile itself should be straight-forward -to read, required additional steps can simply be amended. - -The following template directories are simply copied verbatim onto the target -system: - -* +etc+ -* +opt+ -* +boot+ - -If you simply need to add files to the system, simply drop them into the -appropriate target directory. At present, all dfinity-specific binaries -and scripts simply go to +/opt/ic/bin+. - -If you install new systemd services, drop an appropriate unit file into -/etc/systemd/system and add an activation to the Dockerfile (maybe the -last step could be automated based on the contents of the directory). - -Various more detailed implementation aspects of the system are documented -below. - -== Dynamic file system mounts - -The exact partitions used for the +/boot+ and +/var+ filesystems depends on -what root partition the system is running from: - -* A: +/dev/vda4+ -> +/boot+, +/dev/vda5+ -> +/+, +/dev/vda6+ -> +/var+ -* B: +/dev/vda7+ -> +/boot+, +/dev/vda8+ -> +/+, +/dev/vda9+ -> +/var+ - -The system will be informed via bootloader command line whether it is -running as A or B. Since the root filesystem is conceptually supposed to -be immutable, the dynamic mappings cannot be stored in +/etc/fstab+. - -This is addressed using a generator in +/etc/systemd/system-generator/mount-generator+: -Systemd runs these during early boot, and it will dynamically generate an -appropriate +boot.mount+ unit based on the boot command-line. - -== First boot actions - -Several preparatory operations are performed when the system boots for the -first time. This documents what actions are performed presently and might -serve as a guide on how to add further actions. - -=== ssh key generation - -The +setup-ssh-keys+ (and corresponding shell script) service performs one of -two things: If this is the first boot ever (on a newly installed system), it -generates ssh keys and stashes them away in a location that is preserved across -upgrades. On first boot after an upgrade, it integrates the keys from their -storage location into the running system. The corr - -=== /var filesystem setup - -Partition numbers 6 or 9 (for system A and system B, respectively) are used -for the /var filesystem hierarchy. It is set up as an encrypted filesystem -as well, but its lifetime is limited to the system that it is associated with: -If system A is upgraded to system B, then the /var partition associated of -system B is set up from scratch on first boot of system B. The (now unused) -/var partition of system A will be scrapped and overwritten on next upgrade -written into system A again. - -When an upgrade is installed into either system slot A or B, it is ensured -that the corresponding /var partition is wiped such that the newly booted -system will set up its own /var filesystem correctly again. - -=== IC bootstrap - -The +bootstrap-ic-node+ service (and its corresponding) shell script performs -customization of the installation using node-specific information. This includes: - -* network environment - -* keys or registration parameters for the IC node software - -For all of the above, the system expects a file +ic-bootstrap.tar+ - either -already present at +/mnt+ or supplied on a removable storage medium (e.g. -a USB stick or an optical medium). - -==== Network configuration - -The network configuration is performed using a file +network.conf+ in the -bootstrap tarball. It must contain lines of "key=value" statements, -with the following keys supported: - -* ipv6_address: address used for the IC replica service -* ipv6_gateway: gateway used for the primary interface -* name_servers: space-separated list of DNS servers - -This configuration file is simply copied to the +config+ partition and evaluated -on each boot to set up network. - -==== Journalbeat configuration - -The Journalbeat configuration is performed using a file +journalbeat.conf+ in -the bootstrap tarball. It must contain lines of "key=value= statements, -with the following keys supported: - -* journalbeat_hosts: space-separated list of logging hosts -* journalbeat_tags: space-separated list of tags - -== SELinux - -The system will (eventually) run SELinux in enforcing mode for security. This -requires that all system objects including all files on filesystems are -labelled appropriately. The "usual" way of setting up such a system is -to run it in "permissive" mode first on top of an (SELinux-less) base -install, however this would not work for our cases as we never want the -system to be in anything else than "enforcing" mode (similarly as for -embedded systems in general). - -Instead, SELinux is installed using docker into the target system, but -without applying any file labels (which would not be possible in docker -anyways). The labelling is then applied when extracting the docker image -into a regular filesystem image, with labels applied as per -+/etc/selinux/default/contexts/files/file_contexts+ in the file system -tree. - -Since the system has never run, some files that would have "usually" been -created do not exist yet and are not labelled -- to account for this, -a small number of additional permissions not foreseen in the reference -policy are required -- this is contained in module +fixes.te+ and set -up as part of the +prep.sh+ script called in docker. diff --git a/ic-os/hostos/rootfs/boot/extra_boot_args b/ic-os/hostos/rootfs/boot/extra_boot_args deleted file mode 100644 index 31071fb3809..00000000000 --- a/ic-os/hostos/rootfs/boot/extra_boot_args +++ /dev/null @@ -1,14 +0,0 @@ -# Uncomment this to run system with SELinux in PERMISSIVE mode: -# the system will use SELinux and keep track of operations that would -# be prohibited, but will only log but not actually deny them. This is -# useful for debug and policy development. The system behaves essentially the -# same as if SELinux was not activated. -# -EXTRA_BOOT_ARGS="security=selinux selinux=1 enforcing=0" - -# Uncomment this to run system with SELinux in ENFORCING mode: All rules -# of the policy are enforced, and forbidden actions are not just logged but -# stopped. This causes the system to behave differently than in either -# "no SELinux" or "permissive" mode. -# -# EXTRA_BOOT_ARGS="security=selinux selinux=1 enforcing=1" diff --git a/ic-os/hostos/rootfs/etc/chrony/chrony.conf b/ic-os/hostos/rootfs/etc/chrony/chrony.conf deleted file mode 100644 index 7ccf7f4367e..00000000000 --- a/ic-os/hostos/rootfs/etc/chrony/chrony.conf +++ /dev/null @@ -1,34 +0,0 @@ -# Welcome to the chrony configuration file. See chrony.conf(5) for more -# information about usable directives. - -# Use servers from the NTP Pool Project. -pool 0.pool.ntp.org iburst -pool 1.pool.ntp.org iburst -pool 2.pool.ntp.org iburst -pool 3.pool.ntp.org iburst - -# This directive specify the location of the file containing ID/key pairs for -# NTP authentication. -keyfile /etc/chrony/chrony.keys - -# This directive specify the file into which chronyd will store the rate -# information. -driftfile /var/lib/chrony/chrony.drift - -# Uncomment the following line to turn logging on. -#log tracking measurements statistics - -# Log files location. -logdir /var/log/chrony - -# Stop bad estimates upsetting machine clock. -maxupdateskew 100.0 - -# This directive enables kernel synchronisation (every 11 minutes) of the -# real-time clock. Note that it can’t be used along with the 'rtcfile' directive. -rtcsync - -# Step the system clock instead of slewing it if the adjustment is larger than -# one second, but only in the first three clock updates. -makestep 1 3 -logchange 0.5 diff --git a/ic-os/hostos/rootfs/etc/default/locale b/ic-os/hostos/rootfs/etc/default/locale deleted file mode 100644 index 01ec548f822..00000000000 --- a/ic-os/hostos/rootfs/etc/default/locale +++ /dev/null @@ -1 +0,0 @@ -LANG=en_US.UTF-8 diff --git a/ic-os/hostos/rootfs/etc/default/node_exporter b/ic-os/hostos/rootfs/etc/default/node_exporter deleted file mode 100644 index cd91972bd1d..00000000000 --- a/ic-os/hostos/rootfs/etc/default/node_exporter +++ /dev/null @@ -1 +0,0 @@ -OPTIONS="--web.config='/etc/node_exporter/web.yml' --collector.textfile.directory='/run/node_exporter/collector_textfile'" diff --git a/ic-os/hostos/rootfs/etc/fstab b/ic-os/hostos/rootfs/etc/fstab deleted file mode 100644 index 11022b6be37..00000000000 --- a/ic-os/hostos/rootfs/etc/fstab +++ /dev/null @@ -1,5 +0,0 @@ -/dev/rootfs / ext4 ro,errors=remount-ro 0 1 -tmpfs /tmp tmpfs defaults 0 2 -PARTUUID=f46600e3-d0e6-4258-9607-e64b13cf7595 /boot/efi vfat defaults 0 2 -PARTUUID=1a7c28b7-efe0-4f17-9230-678cf2df8db2 /boot/grub vfat defaults 0 2 -/dev/hostlvm/config /boot/config ext4 defaults,sync 0 2 diff --git a/ic-os/hostos/rootfs/etc/hostname b/ic-os/hostos/rootfs/etc/hostname deleted file mode 100644 index e69de29bb2d..00000000000 diff --git a/ic-os/hostos/rootfs/etc/hosts b/ic-os/hostos/rootfs/etc/hosts deleted file mode 100644 index 62c5dcc4fdd..00000000000 --- a/ic-os/hostos/rootfs/etc/hosts +++ /dev/null @@ -1,8 +0,0 @@ -127.0.0.1 localhost localhost.localdomain - -# The following lines are desirable for IPv6 capable hosts -::1 ip6-localhost ip6-loopback -fe00::0 ip6-localnet -ff00::0 ip6-mcastprefix -ff02::1 ip6-allnodes -ff02::2 ip6-allrouters diff --git a/ic-os/hostos/rootfs/etc/initramfs-tools/initramfs.conf b/ic-os/hostos/rootfs/etc/initramfs-tools/initramfs.conf deleted file mode 100644 index 2202d038676..00000000000 --- a/ic-os/hostos/rootfs/etc/initramfs-tools/initramfs.conf +++ /dev/null @@ -1,5 +0,0 @@ -MODULES=list -BUSYBOX=auto -COMPRESS=lz4 -RUNSIZE=10% -UMASK=0077 diff --git a/ic-os/hostos/rootfs/etc/initramfs-tools/modules b/ic-os/hostos/rootfs/etc/initramfs-tools/modules deleted file mode 100644 index 56a282a1a4c..00000000000 --- a/ic-os/hostos/rootfs/etc/initramfs-tools/modules +++ /dev/null @@ -1,2 +0,0 @@ -virtio_blk -nvme diff --git a/ic-os/hostos/rootfs/etc/initramfs-tools/scripts/init-bottom/set-machine-id/set-machine-id b/ic-os/hostos/rootfs/etc/initramfs-tools/scripts/init-bottom/set-machine-id/set-machine-id deleted file mode 100755 index 53388390943..00000000000 --- a/ic-os/hostos/rootfs/etc/initramfs-tools/scripts/init-bottom/set-machine-id/set-machine-id +++ /dev/null @@ -1,36 +0,0 @@ -#!/bin/sh - -# Set up a machine-id during early boot to ensure that it is stable across -# reboots. - -set -e - -prereqs() { - echo "" -} - -case $1 in - prereqs) - prereqs - exit 0 - ;; -esac - -. /scripts/functions - -# Mount the config partition -mkdir -p /mnt -mount -t ext4 /dev/vda3 /mnt - -# If it contains a saved machine-id, then use it. Bind-mount it over the rootfs -# that we are about to boot, systemd will take it as the given machine-id. -if [ -f "/mnt/machine-id" ]; then - # Note that at this stage, /run has not been move-mounted to be - # below /root -- that will happen right afterwards before booting - # init. - cp /mnt/machine-id /run/machine-id - mount --bind /run/machine-id /root/etc/machine-id -fi -umount /mnt - -exit 0 diff --git a/ic-os/hostos/rootfs/etc/journalbeat/journalbeat.yml.template b/ic-os/hostos/rootfs/etc/journalbeat/journalbeat.yml.template deleted file mode 100644 index bec48096114..00000000000 --- a/ic-os/hostos/rootfs/etc/journalbeat/journalbeat.yml.template +++ /dev/null @@ -1,225 +0,0 @@ -###################### Journalbeat Configuration Example ######################### - -# This file is an example configuration file highlighting only the most common -# options. The journalbeat.reference.yml file from the same directory contains all the -# supported options with more comments. You can use it as a reference. -# -# You can find the full configuration reference here: -# https://www.elastic.co/guide/en/beats/journalbeat/index.html - -# For more available modules and options, please see the journalbeat.reference.yml sample -# configuration file. - -# ============================= Journalbeat inputs ============================= - -journalbeat.inputs: - # Paths that should be crawled and fetched. Possible values files and directories. - # When setting a directory, all journals under it are merged. - # When empty starts to read from local journal. -- paths: [] - - # An optional unique identifier for the input. By providing a unique `id` you - # can operate multiple inputs on the same journal. This allows each input's - # cursor to be persisted independently in the registry file. - #id: "" - - # The number of seconds to wait before trying to read again from journals. - #backoff: 1s - # The maximum number of seconds to wait before attempting to read again from journals. - #max_backoff: 20s - - # Position to start reading from journal. Valid values: head, tail, cursor - seek: cursor - # Fallback position if no cursor data is available. - #cursor_seek_fallback: head - - # Exact matching for field values of events. - # Matching for nginx entries: "systemd.unit=nginx" - #include_matches: [] - - # Optional fields that you can specify to add additional information to the - # output. Fields can be scalar values, arrays, dictionaries, or any nested - # combination of these. - #fields: - # env: staging - - -# ========================= Journalbeat global options ========================= -#journalbeat: - # Name of the registry file. If a relative path is used, it is considered relative to the - # data path. - #registry_file: registry - -# ======================= Elasticsearch template setting ======================= -setup.ilm.enabled: false - -setup.template.name: "journalbeat-guestos-journal" -setup.template.pattern: "journalbeat-guestos-journal-%{[agent.version]}-%{+yyyy.MM.dd}" -setup.template.settings: - index.number_of_shards: 6 - index.number_of_replicas: 2 - #index.codec: best_compression - #_source.enabled: false - -# ================================== General =================================== - -# The name of the shipper that publishes the network data. It can be used to group -# all the transactions sent by a single shipper in the web interface. -#name: - -# The tags of the shipper are included in their own field with each -# transaction published. -#tags: ["service-X", "web-tier"] - -# Optional fields that you can specify to add additional information to the -# output. -#fields: -# env: staging - -# ================================= Dashboards ================================= -# These settings control loading the sample dashboards to the Kibana index. Loading -# the dashboards is disabled by default and can be enabled either by setting the -# options here or by using the `setup` command. -#setup.dashboards.enabled: false - -# The URL from where to download the dashboards archive. By default this URL -# has a value which is computed based on the Beat name and version. For released -# versions, this URL points to the dashboard archive on the artifacts.elastic.co -# website. -#setup.dashboards.url: - -# =================================== Kibana =================================== - -# Starting with Beats version 6.0.0, the dashboards are loaded via the Kibana API. -# This requires a Kibana endpoint configuration. -setup.kibana: - - # Kibana Host - # Scheme and port can be left out and will be set to the default (http and 5601) - # In case you specify and additional path, the scheme is required: http://localhost:5601/path - # IPv6 addresses should always be defined as: https://[2001:db8::1]:5601 - #host: "localhost:5601" - - # Kibana Space ID - # ID of the Kibana Space into which the dashboards should be loaded. By default, - # the Default Space will be used. - #space.id: - -# =============================== Elastic Cloud ================================ - -# These settings simplify using Journalbeat with the Elastic Cloud (https://cloud.elastic.co/). - -# The cloud.id setting overwrites the `output.elasticsearch.hosts` and -# `setup.kibana.host` options. -# You can find the `cloud.id` in the Elastic Cloud web UI. -#cloud.id: - -# The cloud.auth setting overwrites the `output.elasticsearch.username` and -# `output.elasticsearch.password` settings. The format is `:`. -#cloud.auth: - -# ================================== Outputs =================================== - -# Configure what output to use when sending the data collected by the beat. - -# ---------------------------- Elasticsearch Output ---------------------------- -output.elasticsearch: - # Array of hosts to connect to. - hosts: [{{ journalbeat_hosts }}] - index: "journalbeat-hostos-%{[agent.version]}-%{+yyyy.MM.dd}" - - # Protocol - either `http` (default) or `https`. - protocol: "https" - - # Authentication credentials - either API key or username/password. - #api_key: "id:api_key" - #username: "elastic" - #password: "changeme" - -# ------------------------------ Logstash Output ------------------------------- -#output.logstash: - # The Logstash hosts - #hosts: ["localhost:5044"] - - # Optional SSL. By default is off. - # List of root certificates for HTTPS server verifications - #ssl.certificate_authorities: ["/etc/pki/root/ca.pem"] - - # Certificate for SSL client authentication - #ssl.certificate: "/etc/pki/client/cert.pem" - - # Client Certificate Key - #ssl.key: "/etc/pki/client/cert.key" - -# ================================= Processors ================================= - -# Configure processors to enhance or manipulate events generated by the beat. - -processors: - - add_host_metadata: ~ - - -# ================================== Logging =================================== - -# Sets log level. The default log level is info. -# Available log levels are: error, warning, info, debug -logging.level: warning -processors: - - drop_event: - when: - equals: - systemd.unit: "journalbeat.service" - -# At debug level, you can selectively enable logging only for some components. -# To enable all selectors use ["*"]. Examples of other selectors are "beat", -# "publisher", "service". -#logging.selectors: ["*"] - -# ============================= X-Pack Monitoring ============================== -# Journalbeat can export internal metrics to a central Elasticsearch monitoring -# cluster. This requires xpack monitoring to be enabled in Elasticsearch. The -# reporting is disabled by default. - -# Set to true to enable the monitoring reporter. -#monitoring.enabled: false - -# Sets the UUID of the Elasticsearch cluster under which monitoring data for this -# Journalbeat instance will appear in the Stack Monitoring UI. If output.elasticsearch -# is enabled, the UUID is derived from the Elasticsearch cluster referenced by output.elasticsearch. -#monitoring.cluster_uuid: - -# Uncomment to send the metrics to Elasticsearch. Most settings from the -# Elasticsearch output are accepted here as well. -# Note that the settings should point to your Elasticsearch *monitoring* cluster. -# Any setting that is not set is automatically inherited from the Elasticsearch -# output configuration, so if you have the Elasticsearch output configured such -# that it is pointing to your Elasticsearch monitoring cluster, you can simply -# uncomment the following line. -#monitoring.elasticsearch: - -# ============================== Instrumentation =============================== - -# Instrumentation support for the journalbeat. -#instrumentation: - # Set to true to enable instrumentation of journalbeat. - #enabled: false - - # Environment in which journalbeat is running on (eg: staging, production, etc.) - #environment: "" - - # APM Server hosts to report instrumentation results to. - #hosts: - # - http://localhost:8200 - - # API Key for the APM Server(s). - # If api_key is set then secret_token will be ignored. - #api_key: - - # Secret token for the APM Server(s). - #secret_token: - - -# ================================= Migration ================================== - -# This allows to enable 6.7 migration aliases -#migration.6_to_7.enabled: true diff --git a/ic-os/hostos/rootfs/etc/nftables.conf b/ic-os/hostos/rootfs/etc/nftables.conf deleted file mode 100644 index b5e3dc9e1dc..00000000000 --- a/ic-os/hostos/rootfs/etc/nftables.conf +++ /dev/null @@ -1,79 +0,0 @@ -table ip filter { - chain INPUT { - type filter hook input priority filter; policy drop; - iif "lo" accept - ct state { invalid } drop - ct state { established, related } accept - icmp type destination-unreachable accept - icmp type source-quench accept - icmp type time-exceeded accept - icmp type parameter-problem accept - icmp type echo-request accept - icmp type echo-reply accept - ip saddr { 10.0.0.0/8, 172.16.0.0/12, 192.168.0.0/16 } ct state { new } tcp dport { 22 } accept - ip saddr { 10.0.0.0/8, 172.16.0.0/12, 192.168.0.0/16 } ct state { new } udp dport { 67 } accept - } - - chain FORWARD { - type filter hook forward priority filter; policy drop; - } - - chain OUTPUT { - type filter hook output priority filter; policy drop; - oif "lo" accept - ct state { invalid } drop - ct state { established, related } accept - icmp type destination-unreachable accept - icmp type source-quench accept - icmp type time-exceeded accept - icmp type parameter-problem accept - icmp type echo-request accept - icmp type echo-reply accept - ip daddr { 0.0.0.0/0 } ct state { new } tcp dport { 53 } accept - ip daddr { 0.0.0.0/0 } ct state { new } udp dport { 53 } accept - ip daddr { 0.0.0.0/0 } ct state { new } udp dport { 123 } accept - ip daddr { 0.0.0.0/0 } ct state { new } tcp dport { 80, 443 } accept - } -} -table ip6 filter { - chain INPUT { - type filter hook input priority filter; policy drop; - iif "lo" accept - ct state { invalid } drop - ct state { established, related } accept - icmpv6 type destination-unreachable accept - icmpv6 type packet-too-big accept - icmpv6 type time-exceeded accept - icmpv6 type parameter-problem accept - icmpv6 type echo-request accept - icmpv6 type echo-reply accept - icmpv6 type nd-router-advert accept - icmpv6 type nd-neighbor-solicit accept - icmpv6 type nd-neighbor-advert accept - ip6 saddr { 2001:438:fffd:11c::/64, 2001:470:1:c76::/64, 2001:920:401a:1706::/64, 2001:920:401a:1708::/64, 2001:920:401a:1710::/64, 2001:4d78:400:10a::/64, 2001:4d78:40d::/48, 2401:3f00:1000:22::-2401:3f00:1000:24:ffff:ffff:ffff:ffff, 2600:c02:b002:15::/64, 2600:c0d:3002:4::/64, 2600:2c01:21::/64, 2600:3000:1300:1300::/64, 2600:3000:6100:200::/64, 2600:3004:1200:1200::/56, 2600:3006:1400:1500::/64, 2604:1380:4091:3000::/64, 2604:1380:40e1:4700::/64, 2604:1380:40f1:1700::/64, 2604:1380:45d1:bf00::/64, 2604:1380:45e1:a600::/64, 2604:1380:45f1:9400::/64, 2604:1380:4601:6200::/64, 2604:1380:4641:6100::/64, 2604:3fc0:2001::/48, 2604:3fc0:3002::/48, 2604:6800:258:1::/64, 2604:7e00:30:3::/64, 2604:7e00:50::/64, 2604:b900:4001:76::/64, 2607:f1d0:10:1::/64, 2607:f6f0:3004::/48, 2607:f758:1220::/64, 2607:f758:c300::/64, 2607:fb58:9005::/48, 2607:ff70:3:2::/64, 2610:190:6000:1::/64, 2610:190:df01:5::/64, 2a00:fa0:3::/48, 2a00:fc0:5000:300::/64, 2a00:fb01:400::/55, 2a01:138:900a::/48, 2a01:2a8:a13c:1::/64, 2a01:2a8:a13d:1::/64, 2a01:2a8:a13e:1::/64, 2a02:418:3002::/64, 2a02:41b:300e::/48, 2a02:800:2:2003::/64, 2a04:9dc0:0:108::/64, 2a05:d01c:e2c:a700::/56, 2a0b:21c0:b002:2::/64, 2a0f:cd00:2::/56, fd00:2:1:1::/64 } ct state { new } tcp dport { 22, 9100, 19531 } accept - } - - chain FORWARD { - type filter hook forward priority filter; policy drop; - } - - chain OUTPUT { - type filter hook output priority filter; policy drop; - oif "lo" accept - ct state { invalid } drop - ct state { established, related } accept - icmpv6 type destination-unreachable accept - icmpv6 type packet-too-big accept - icmpv6 type time-exceeded accept - icmpv6 type parameter-problem accept - icmpv6 type echo-request accept - icmpv6 type echo-reply accept - icmpv6 type nd-router-solicit accept - icmpv6 type nd-neighbor-solicit accept - icmpv6 type nd-neighbor-advert accept - ip6 daddr { ::/0 } ct state { new } tcp dport { 53 } accept - ip6 daddr { ::/0 } ct state { new } udp dport { 53 } accept - ip6 daddr { ::/0 } ct state { new } udp dport { 123 } accept - ip6 daddr { ::/0 } ct state { new } tcp dport { 80, 443 } accept - } -} diff --git a/ic-os/hostos/rootfs/etc/node_exporter/node_exporter.crt b/ic-os/hostos/rootfs/etc/node_exporter/node_exporter.crt deleted file mode 100644 index e69de29bb2d..00000000000 diff --git a/ic-os/hostos/rootfs/etc/node_exporter/node_exporter.key b/ic-os/hostos/rootfs/etc/node_exporter/node_exporter.key deleted file mode 100644 index e69de29bb2d..00000000000 diff --git a/ic-os/hostos/rootfs/etc/node_exporter/web.yml b/ic-os/hostos/rootfs/etc/node_exporter/web.yml deleted file mode 100644 index 39adc79faa3..00000000000 --- a/ic-os/hostos/rootfs/etc/node_exporter/web.yml +++ /dev/null @@ -1,5 +0,0 @@ ---- - -tls_server_config: - cert_file: "/etc/node_exporter/node_exporter.crt" - key_file: "/etc/node_exporter/node_exporter.key" diff --git a/ic-os/hostos/rootfs/etc/resolv.conf b/ic-os/hostos/rootfs/etc/resolv.conf deleted file mode 100644 index 1db3c036677..00000000000 --- a/ic-os/hostos/rootfs/etc/resolv.conf +++ /dev/null @@ -1,18 +0,0 @@ -# This file is managed by man:systemd-resolved(8). Do not edit. -# -# This is a dynamic resolv.conf file for connecting local clients to the -# internal DNS stub resolver of systemd-resolved. This file lists all -# configured search domains. -# -# Run "resolvectl status" to see details about the uplink DNS servers -# currently in use. -# -# Third party programs must not access this file directly, but only through the -# symlink at /etc/resolv.conf. To manage man:resolv.conf(5) in a different way, -# replace this symlink by a static file or a different symlink. -# -# See man:systemd-resolved.service(8) for details about the supported modes of -# operation for /etc/resolv.conf. - -nameserver 127.0.0.53 -options edns0 trust-ad diff --git a/ic-os/hostos/rootfs/etc/sudoers b/ic-os/hostos/rootfs/etc/sudoers deleted file mode 100644 index eb59f2cad72..00000000000 --- a/ic-os/hostos/rootfs/etc/sudoers +++ /dev/null @@ -1,32 +0,0 @@ -# -# This file MUST be edited with the 'visudo' command as root. -# -# Please consider adding local content in /etc/sudoers.d/ instead of -# directly modifying this file. -# -# See the man page for details on how to write a sudoers file. -# -Defaults env_reset -Defaults mail_badpass -Defaults secure_path="/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin:/snap/bin" - - -# Uncomment to disable the insults for incorrect passwords -Defaults !insults - -# Uncomment to disable the lecture the first time you run sudo -Defaults !lecture - -# Host alias specification - -# User alias specification - -# Cmnd alias specification - -# User privilege specification -root ALL=(ALL:ALL) NOPASSWD:ALL - -# Allow members of group sudo to execute any command -%sudo ALL=(ALL:ALL) NOPASSWD:ALL - -# See sudoers(5) for more information on "#include" directives: diff --git a/ic-os/hostos/rootfs/etc/sysctl.d/network-tweaks.conf b/ic-os/hostos/rootfs/etc/sysctl.d/network-tweaks.conf deleted file mode 100644 index 8b011e6b523..00000000000 --- a/ic-os/hostos/rootfs/etc/sysctl.d/network-tweaks.conf +++ /dev/null @@ -1,15 +0,0 @@ -# Networking tweaks copied from ic-os/hostos/ansible/roles/sysctl/defaults/main.yml -# - -# BBR should provide better throughput for single tcp streams on lossy -# long-distance links. That may be crucial to get sufficient cross-DC -# throughput. -net.ipv4.tcp_congestion_control = bbr - -# There is no documented rationale for the individual settings below. -net.core.rmem_max = 134217728 -net.core.wmem_max = 134217728 -net.ipv4.tcp_notsent_lowat = 16384 -net.ipv4.tcp_rmem = 4096 131072 134217728 -net.ipv4.tcp_wmem = 4096 131072 134217728 -net.core.default_qdisc = fq diff --git a/ic-os/hostos/rootfs/etc/systemd/resolved.conf.d/fallback.conf b/ic-os/hostos/rootfs/etc/systemd/resolved.conf.d/fallback.conf deleted file mode 100644 index 0e4239e9869..00000000000 --- a/ic-os/hostos/rootfs/etc/systemd/resolved.conf.d/fallback.conf +++ /dev/null @@ -1,2 +0,0 @@ -[Resolve] -FallbackDNS=2606:4700:4700::1111 2606:4700:4700::1001 2001:4860:4860::8888 2001:4860:4860::8844 diff --git a/ic-os/hostos/rootfs/etc/systemd/system-generators/mount-generator b/ic-os/hostos/rootfs/etc/systemd/system-generators/mount-generator deleted file mode 100755 index ddf78003565..00000000000 --- a/ic-os/hostos/rootfs/etc/systemd/system-generators/mount-generator +++ /dev/null @@ -1,101 +0,0 @@ -#!/bin/bash - -# This script dynamically creates the correct mounts based on whether -# we are running system A or B -- we will not "know" at build time -# what we are going to be booted from because the same image could -# be placed into either system A or system B root partition during -# upgrades. -# -# The dynamically changing mounts are: -# - /boot is /dev/hostlvm/A_boot (system A) or /dev/hostlvm/B_boot (system B) -# - /var is /dev/hostlvm/A_var (system A) or /dev/hostlvm/B_var (system B) -# -# This is generated dynamically to avoid changing /etc/fstab (root -# filesystem might be read-only). -# -# systemd doc advises to "not use shell scripts" as generators -- -# while I agree with that and the rationale behind it, this script -# is written carefully and works correctly, and is quicker to write -# than setting up a compiled binary (for now). - -UNIT_DIR="$1" - -function get_boot_arg_value() { - local ARGNAME="$1" - for ARG in $(cat /proc/cmdline); do - echo "$ARG" | while IFS='=' read KEY VALUE; do - if [ "$ARGNAME" == "$KEY" ]; then echo "$VALUE"; fi - done - done -} - -function make_requires() { - mkdir -p "${UNIT_DIR}"/$1.requires - ln -s ../$2 "${UNIT_DIR}"/$1.requires/$2 -} - -function make_boot_mount() { - if [ "$1" == A ]; then - local DEVICE=/dev/hostlvm/A_boot - else - local DEVICE=/dev/hostlvm/B_boot - fi - echo "# Automatically generated by /etc/systemd/system-generators/mount-generator" - echo "[Unit]" - echo "SourcePath=/etc/systemd/system-generators/mount-generator" - echo "Before=local-fs.target" - echo - echo "[Mount]" - echo "What=$DEVICE" - echo "Where=/boot" - echo "Type=ext4" - echo "Options=defaults" -} - -function make_var_setup() { - if [ "$1" == A ]; then - local DEVICE=A_var - else - local DEVICE=B_var - fi - echo "# Automatically generated by /etc/systemd/system-generators/mount-generator" - echo "[Unit]" - echo "SourcePath=/etc/systemd/system-generators/mount-generator" - echo "Description=Setup for var" - echo "DefaultDependencies=no" - echo "Before=var.mount" - echo "" - echo "[Service]" - echo "Type=oneshot" - echo "RemainAfterExit=yes" - echo "ExecStart=/opt/ic/bin/setup-var.sh /dev/hostlvm/${DEVICE}" -} - -function make_var_mount() { - if [ "$1" == A ]; then - local DEVICE=/dev/hostlvm/A_var - else - local DEVICE=/dev/hostlvm/B_var - fi - echo "# Automatically generated by /etc/systemd/system-generators/mount-generator" - echo "[Unit]" - echo "SourcePath=/etc/systemd/system-generators/mount-generator" - echo "Before=local-fs.target" - echo "Requires=var-setup.service" - echo - echo "[Mount]" - echo "What=$DEVICE" - echo "Where=/var" - echo "Type=ext4" - echo "Options=defaults" -} - -CURRENT_SYSTEM=$(get_boot_arg_value dfinity.system) - -make_boot_mount "$CURRENT_SYSTEM" >"$UNIT_DIR"/boot.mount -make_requires localfs.target boot.mount -make_requires boot-efi.mount boot.mount -make_requires boot-grub.mount boot.mount - -make_var_setup "$CURRENT_SYSTEM" >"$UNIT_DIR"/var-setup.service -make_var_mount "$CURRENT_SYSTEM" >"$UNIT_DIR"/var.mount diff --git a/ic-os/hostos/rootfs/etc/systemd/system-generators/systemd-gpt-auto-generator b/ic-os/hostos/rootfs/etc/systemd/system-generators/systemd-gpt-auto-generator deleted file mode 100755 index f9c586b7b89..00000000000 --- a/ic-os/hostos/rootfs/etc/systemd/system-generators/systemd-gpt-auto-generator +++ /dev/null @@ -1,6 +0,0 @@ -#!/bin/bash - -# This generator normally scans gpt partition table in order to auto-mount -# filesystems based on partition labels. It does not perform anything useful -# in our case, so simply disable it. (Otherwise, needs security policy to -# allow it to do a number of things to avoid failure messages). diff --git a/ic-os/hostos/rootfs/etc/systemd/system/deploy-updated-ssh-account-keys.service b/ic-os/hostos/rootfs/etc/systemd/system/deploy-updated-ssh-account-keys.service deleted file mode 100644 index cc1b47ef93e..00000000000 --- a/ic-os/hostos/rootfs/etc/systemd/system/deploy-updated-ssh-account-keys.service +++ /dev/null @@ -1,12 +0,0 @@ -[Unit] -Description=Update ssh account keys -Before=setup-ssh-account-keys.service - -[Service] -Type=oneshot -RemainAfterExit=true -ExecStart=/opt/ic/bin/deploy-updated-ssh-account-keys.sh - -[Install] -RequiredBy=setup-ssh-account-keys.service -WantedBy=multi-user.target diff --git a/ic-os/hostos/rootfs/etc/systemd/system/generate-guestos-config.service b/ic-os/hostos/rootfs/etc/systemd/system/generate-guestos-config.service deleted file mode 100644 index 5b0b37fc85e..00000000000 --- a/ic-os/hostos/rootfs/etc/systemd/system/generate-guestos-config.service +++ /dev/null @@ -1,12 +0,0 @@ -[Unit] -Description=Generate GuestOS configuration -Before=systemd-networkd.service -After=store-hsm.service - -[Service] -Type=oneshot -RemainAfterExit=true -ExecStart=/opt/ic/bin/generate-guestos-config.sh - -[Install] -WantedBy=multi-user.target diff --git a/ic-os/hostos/rootfs/etc/systemd/system/generate-network-config.service b/ic-os/hostos/rootfs/etc/systemd/system/generate-network-config.service deleted file mode 100644 index 9362874e417..00000000000 --- a/ic-os/hostos/rootfs/etc/systemd/system/generate-network-config.service +++ /dev/null @@ -1,14 +0,0 @@ -[Unit] -Description=Generate network config -After=store-hsm.service -Before=systemd-networkd.service -Before=systemd-networkd-wait-online.service - -[Service] -Type=oneshot -RemainAfterExit=true -ExecStart=/opt/ic/bin/generate-network-config.sh - -[Install] -WantedBy=systemd-networkd.service -WantedBy=multi-user.target diff --git a/ic-os/hostos/rootfs/etc/systemd/system/guestos.service b/ic-os/hostos/rootfs/etc/systemd/system/guestos.service deleted file mode 100644 index ea9f2a3596d..00000000000 --- a/ic-os/hostos/rootfs/etc/systemd/system/guestos.service +++ /dev/null @@ -1,17 +0,0 @@ -[Unit] -Description=Manage GuestOS virtual machine -Requires=libvirtd.service -After=libvirtd.service -Requires=generate-guestos-config.service -After=generate-guestos-config.service - -[Service] -Type=forking -ExecStartPre=/opt/ic/bin/detect-first-boot.sh -ExecStart=/opt/ic/bin/start-guestos.sh -ExecStop=/opt/ic/bin/stop-guestos.sh -Restart=on-failure -PIDFile=/var/run/libvirt/qemu/guestos.pid - -[Install] -WantedBy=multi-user.target diff --git a/ic-os/hostos/rootfs/etc/systemd/system/journalbeat.service b/ic-os/hostos/rootfs/etc/systemd/system/journalbeat.service deleted file mode 100644 index 309eae8bbc3..00000000000 --- a/ic-os/hostos/rootfs/etc/systemd/system/journalbeat.service +++ /dev/null @@ -1,23 +0,0 @@ -[Unit] -Description=Journalbeat ships systemd journal entries to Elasticsearch or Logstash. -Documentation=https://www.elastic.co/beats/journalbeat -Wants=network-online.target -After=network-online.target -# We must wait for IC bootstrap to complete: It writes various -# state files and may also be needed to obtain network config. -After=bootstrap-ic-node.service -Wants=bootstrap-ic-node.service - -[Service] -User=journalbeat -Group=journalbeat -Environment="GODEBUG='madvdontneed=1'" -Environment="BEAT_LOG_OPTS=" -Environment="BEAT_CONFIG_OPTS=-c /run/ic-node/etc/journalbeat/journalbeat.yml" -Environment="BEAT_PATH_OPTS=--path.home /usr/share/journalbeat --path.config /run/ic-node/etc/journalbeat/journalbeat --path.data /var/lib/journalbeat --path.logs /var/log/journalbeat" -ExecStartPre=+/opt/ic/bin/generate-journalbeat-config.sh -ExecStart=/usr/local/bin/journalbeat --environment systemd $BEAT_LOG_OPTS $BEAT_CONFIG_OPTS $BEAT_PATH_OPTS -Restart=always - -[Install] -WantedBy=multi-user.target diff --git a/ic-os/hostos/rootfs/etc/systemd/system/monitor-guestos.service b/ic-os/hostos/rootfs/etc/systemd/system/monitor-guestos.service deleted file mode 100644 index 13fc3fea7e5..00000000000 --- a/ic-os/hostos/rootfs/etc/systemd/system/monitor-guestos.service +++ /dev/null @@ -1,13 +0,0 @@ -[Unit] -Description=Monitor GuestOS virtual machine -Requires=libvirtd.service -After=libvirtd.service -Requires=generate-guestos-config.service -After=generate-guestos-config.service - -[Service] -Type=oneshot -ExecStart=/opt/ic/bin/monitor-guestos.sh - -[Install] -WantedBy=multi-user.target diff --git a/ic-os/hostos/rootfs/etc/systemd/system/monitor-guestos.timer b/ic-os/hostos/rootfs/etc/systemd/system/monitor-guestos.timer deleted file mode 100644 index b098006c245..00000000000 --- a/ic-os/hostos/rootfs/etc/systemd/system/monitor-guestos.timer +++ /dev/null @@ -1,10 +0,0 @@ -[Unit] -Description=Monitor GuestOS virtual machine on a regular basis -Requires=monitor-guestos.service - -[Timer] -Unit=monitor-guestos.service -OnCalendar=*-*-* *:*:00 - -[Install] -WantedBy=timers.target diff --git a/ic-os/hostos/rootfs/etc/systemd/system/node_exporter.service b/ic-os/hostos/rootfs/etc/systemd/system/node_exporter.service deleted file mode 100644 index 3f7549b7180..00000000000 --- a/ic-os/hostos/rootfs/etc/systemd/system/node_exporter.service +++ /dev/null @@ -1,15 +0,0 @@ -[Unit] -Description=Node Exporter -After=syslog.target network.target - -[Service] -User=node_exporter -Group=node_exporter -EnvironmentFile=/etc/default/node_exporter -ExecStart=/usr/local/bin/node_exporter $OPTIONS -ExecReload=/bin/kill -HUP $MAINPID -Restart=on-failure -RestartSec=5s - -[Install] -WantedBy=multi-user.target diff --git a/ic-os/hostos/rootfs/etc/systemd/system/relabel-machine-id.service b/ic-os/hostos/rootfs/etc/systemd/system/relabel-machine-id.service deleted file mode 100644 index 0b2d86c5912..00000000000 --- a/ic-os/hostos/rootfs/etc/systemd/system/relabel-machine-id.service +++ /dev/null @@ -1,13 +0,0 @@ -[Unit] -Description=Relabel /etc/machine-id -Before=systemd-journald.service -DefaultDependencies=no - -[Service] -Type=oneshot -RemainAfterExit=true -ExecStart=/opt/ic/bin/relabel-machine-id.sh - -[Install] -WantedBy=multi-user.target -RequiredBy=systemd-journald.service diff --git a/ic-os/hostos/rootfs/etc/systemd/system/save-machine-id.service b/ic-os/hostos/rootfs/etc/systemd/system/save-machine-id.service deleted file mode 100644 index ee2c667e183..00000000000 --- a/ic-os/hostos/rootfs/etc/systemd/system/save-machine-id.service +++ /dev/null @@ -1,12 +0,0 @@ -[Unit] -Description=Save machine-id -Requires=boot-config.mount -After=boot-config.mount - -[Service] -Type=oneshot -RemainAfterExit=true -ExecStart=/opt/ic/bin/save-machine-id.sh - -[Install] -WantedBy=multi-user.target diff --git a/ic-os/hostos/rootfs/etc/systemd/system/setup-hostname.service b/ic-os/hostos/rootfs/etc/systemd/system/setup-hostname.service deleted file mode 100644 index 259ea2f49d7..00000000000 --- a/ic-os/hostos/rootfs/etc/systemd/system/setup-hostname.service +++ /dev/null @@ -1,15 +0,0 @@ -[Unit] -Description=Set up hostname -Before=systemd-networkd.target -DefaultDependencies=no -Before=systemd-networkd.service -After=systemd-tmpfiles-setup.service -After=store-hsm.service - -[Service] -Type=oneshot -RemainAfterExit=true -ExecStart=/opt/ic/bin/setup-hostname.sh --type=host - -[Install] -WantedBy=multi-user.target diff --git a/ic-os/hostos/rootfs/etc/systemd/system/setup-libvirt.service b/ic-os/hostos/rootfs/etc/systemd/system/setup-libvirt.service deleted file mode 100644 index fe42f35ea0a..00000000000 --- a/ic-os/hostos/rootfs/etc/systemd/system/setup-libvirt.service +++ /dev/null @@ -1,11 +0,0 @@ -[Unit] -Description=Set up libvirt -Before=libvirtd.service - -[Service] -Type=oneshot -RemainAfterExit=true -ExecStart=/opt/ic/bin/setup-libvirt.sh - -[Install] -WantedBy=multi-user.target diff --git a/ic-os/hostos/rootfs/etc/systemd/system/setup-node_exporter-keys.service b/ic-os/hostos/rootfs/etc/systemd/system/setup-node_exporter-keys.service deleted file mode 100644 index 0e1994b3e02..00000000000 --- a/ic-os/hostos/rootfs/etc/systemd/system/setup-node_exporter-keys.service +++ /dev/null @@ -1,12 +0,0 @@ -[Unit] -Description=Generate node_exporter TLS key pair on first boot -After=boot-config.mount -Before=node_exporter.service - -[Service] -Type=oneshot -RemainAfterExit=true -ExecStart=/opt/ic/bin/setup-node_exporter-keys.sh - -[Install] -WantedBy=multi-user.target diff --git a/ic-os/hostos/rootfs/etc/systemd/system/setup-ssh-account-keys.service b/ic-os/hostos/rootfs/etc/systemd/system/setup-ssh-account-keys.service deleted file mode 100644 index 8cca8600f89..00000000000 --- a/ic-os/hostos/rootfs/etc/systemd/system/setup-ssh-account-keys.service +++ /dev/null @@ -1,11 +0,0 @@ -[Unit] -Description=Set up ssh account keys -Before=ssh.service - -[Service] -Type=oneshot -RemainAfterExit=true -ExecStart=/opt/ic/bin/setup-ssh-account-keys.sh - -[Install] -WantedBy=multi-user.target diff --git a/ic-os/hostos/rootfs/etc/systemd/system/setup-ssh-keys.service b/ic-os/hostos/rootfs/etc/systemd/system/setup-ssh-keys.service deleted file mode 100644 index 7560dc9b311..00000000000 --- a/ic-os/hostos/rootfs/etc/systemd/system/setup-ssh-keys.service +++ /dev/null @@ -1,11 +0,0 @@ -[Unit] -Description=Generate ssh keys on first boot -Before=ssh.service - -[Service] -Type=oneshot -RemainAfterExit=true -ExecStart=/opt/ic/bin/setup-ssh-keys.sh - -[Install] -WantedBy=multi-user.target diff --git a/ic-os/hostos/rootfs/etc/systemd/system/store-hsm.service b/ic-os/hostos/rootfs/etc/systemd/system/store-hsm.service deleted file mode 100644 index 41c3776de0d..00000000000 --- a/ic-os/hostos/rootfs/etc/systemd/system/store-hsm.service +++ /dev/null @@ -1,9 +0,0 @@ -[Unit] -Description=Store HSM to config partition - -[Service] -Type=oneshot -ExecStart=/opt/ic/bin/hsm-utils.sh --save - -[Install] -WantedBy=multi-user.target diff --git a/ic-os/hostos/rootfs/etc/systemd/system/vsock-agent.service b/ic-os/hostos/rootfs/etc/systemd/system/vsock-agent.service deleted file mode 100644 index c36e080e92d..00000000000 --- a/ic-os/hostos/rootfs/etc/systemd/system/vsock-agent.service +++ /dev/null @@ -1,17 +0,0 @@ -[Unit] -Description=HSM Agent -After=syslog.target - -[Service] -User=root -Group=root -ExecStart=python3 /opt/ic/bin/hostos-vsock-agent/hostos_vsock_agent.py server --verbose -Restart=always -RuntimeMaxSec=3600 -RestartSec=10 -KillSignal=SIGINT -StartLimitBurst=5 -StartLimitInterval=60 - -[Install] -WantedBy=multi-user.target diff --git a/ic-os/hostos/rootfs/etc/tmpfiles.d/ic-node.conf b/ic-os/hostos/rootfs/etc/tmpfiles.d/ic-node.conf deleted file mode 100644 index 93592a2d469..00000000000 --- a/ic-os/hostos/rootfs/etc/tmpfiles.d/ic-node.conf +++ /dev/null @@ -1,15 +0,0 @@ -# This file is part of ic-node configuration to support ro root. - -# See tmpfiles.d(5) for details - -# Type Path Mode User Group Age Argument -d /run/ic-node 0755 root root - -d /run/ic-node/etc 0755 root root - -d /run/ic-node/root/ 0700 root root - -d /run/ic-node/root/.ssh 0700 root root - -d /run/ic-node/etc/ssh 0755 root root - -d /run/ic-node/etc/node_exporter 0755 root root - -d /run/ic-node/etc/journalbeat 0755 root root - -d /run/ic-node/config 0755 root root - -d /run/node_exporter/collector_textfile 0755 root root - -d /run/libvirt 0755 root root - diff --git a/ic-os/hostos/rootfs/etc/udev/rules.d/10-vhost-vsock.rules b/ic-os/hostos/rootfs/etc/udev/rules.d/10-vhost-vsock.rules deleted file mode 100644 index f8080dc527e..00000000000 --- a/ic-os/hostos/rootfs/etc/udev/rules.d/10-vhost-vsock.rules +++ /dev/null @@ -1 +0,0 @@ -KERNEL=="vsock", GROUP="vsock", MODE="0660" diff --git a/ic-os/hostos/rootfs/opt/ic/bin/build-bootstrap-config-image.sh b/ic-os/hostos/rootfs/opt/ic/bin/build-bootstrap-config-image.sh deleted file mode 100755 index 742cc634666..00000000000 --- a/ic-os/hostos/rootfs/opt/ic/bin/build-bootstrap-config-image.sh +++ /dev/null @@ -1,261 +0,0 @@ -#!/usr/bin/env bash - -set -e - -function usage() { - cat >&2 <&2 - exit 1 - } - - local BOOTSTRAP_TMPDIR=$(mktemp -d) - - cat >"${BOOTSTRAP_TMPDIR}/network.conf" <"${BOOTSTRAP_TMPDIR}/journalbeat.conf" - fi - if [ "${JOURNALBEAT_TAGS}" != "" ]; then - echo "journalbeat_tags=$JOURNALBEAT_TAGS" >>"${BOOTSTRAP_TMPDIR}/journalbeat.conf" - fi - if [ "${NNS_PUBLIC_KEY}" != "" ]; then - cp "${NNS_PUBLIC_KEY}" "${BOOTSTRAP_TMPDIR}/nns_public_key.pem" - fi - if [ "${NNS_URL}" != "" ]; then - echo "nns_url=${NNS_URL}" >"${BOOTSTRAP_TMPDIR}/nns.conf" - fi - if [ "${BACKUP_RETENTION_TIME_SECS}" != "" ] || [ "${BACKUP_PURGING_INTERVAL_SECS}" != "" ]; then - echo "backup_retention_time_secs=${BACKUP_RETENTION_TIME_SECS}" >"${BOOTSTRAP_TMPDIR}/backup.conf" - echo "backup_puging_interval_secs=${BACKUP_PURGING_INTERVAL_SECS}" >>"${BOOTSTRAP_TMPDIR}/backup.conf" - fi - if [ "${LOG_DEBUG_OVERRIDES}" != "" ]; then - echo "log_debug_overrides=${LOG_DEBUG_OVERRIDES}" >"${BOOTSTRAP_TMPDIR}/log.conf" - fi - if [ "${MALICIOUS_BEHAVIOR}" != "" ]; then - echo "malicious_behavior=${MALICIOUS_BEHAVIOR}" >"${BOOTSTRAP_TMPDIR}/malicious_behavior.conf" - fi - if [ "${IC_CRYPTO}" != "" ]; then - cp -r "${IC_CRYPTO}" "${BOOTSTRAP_TMPDIR}/ic_crypto" - fi - if [ "${IC_REGISTRY_LOCAL_STORE}" != "" ]; then - cp -r "${IC_REGISTRY_LOCAL_STORE}" "${BOOTSTRAP_TMPDIR}/ic_registry_local_store" - fi - if [ "${ACCOUNTS_SSH_AUTHORIZED_KEYS}" != "" ]; then - cp -r "${ACCOUNTS_SSH_AUTHORIZED_KEYS}" "${BOOTSTRAP_TMPDIR}/accounts_ssh_authorized_keys" - fi - - tar cf "${OUT_FILE}" -C "${BOOTSTRAP_TMPDIR}" . - - rm -rf "${BOOTSTRAP_TMPDIR}" -} - -# Arguments: -# - $1 the disk image to be built -# - all remaining arguments: parameters to encode into the bootstrap - -function build_ic_bootstrap_diskimage() { - local OUT_FILE="$1" - shift - - local TMPDIR=$(mktemp -d) - build_ic_bootstrap_tar "${TMPDIR}/ic-bootstrap.tar" "$@" - - truncate -s 10M "${OUT_FILE}" - mkfs.vfat "${OUT_FILE}" - mcopy -i "${OUT_FILE}" -o "${TMPDIR}/ic-bootstrap.tar" :: - - rm -rf "${TMPDIR}" -} - -BUILD_TAR_ONLY=0 -if [ "$1" == "-t" -o "$1" == "--tar" ]; then - BUILD_TAR_ONLY=1 - shift -fi - -if [ "$#" -lt 2 ]; then - usage - exit 1 -fi - -if [ "${BUILD_TAR_ONLY}" == 0 ]; then - build_ic_bootstrap_diskimage "$@" -else - build_ic_bootstrap_tar "$@" -fi diff --git a/ic-os/hostos/rootfs/opt/ic/bin/deploy-updated-ssh-account-keys.sh b/ic-os/hostos/rootfs/opt/ic/bin/deploy-updated-ssh-account-keys.sh deleted file mode 100755 index 9f1ec49456e..00000000000 --- a/ic-os/hostos/rootfs/opt/ic/bin/deploy-updated-ssh-account-keys.sh +++ /dev/null @@ -1,36 +0,0 @@ -#!/bin/bash - -set -e - -# Update configured ssh keys for the role accounts if a newer version -# is available. - -# Only update readonly and backup keys. -for ACCOUNT in backup readonly; do - echo "Checking authorized keys for ${ACCOUNT}" - ORIGIN="/opt/ic/share/authorized_keys/${ACCOUNT}" - if [ ! -r "${ORIGIN}" ]; then - continue - fi - TARGET="/boot/config/hostos_accounts_ssh_authorized_keys/${ACCOUNT}" - if [ ! -r "${TARGET}" ]; then - echo "${ORIGIN} keys exist, but no ${TARGET} keys are present, skipping" - continue - fi - ORIGIN_ENV=$(head -n 1 $ORIGIN) - TARGET_ENV=$(head -n 1 $TARGET) - if [ "${TARGET_ENV:0:1}" != "#" ]; then - echo "Authorized keys for ${ACCOUNT} have no environment header, updating" - cp "${ORIGIN}" "${TARGET}" - elif [ "${TARGET_ENV}" = "${ORIGIN_ENV}" ]; then - # Target's environment matches, check which is newer. - ORIGIN_TIME=$(head -n 2 $ORIGIN | tail -n 1 | cut -c 3- | date -f - +%s) - TARGET_TIME=$(head -n 2 $TARGET | tail -n 1 | cut -c 3- | date -f - +%s) - if [ $ORIGIN_TIME -gt $TARGET_TIME ]; then - echo "Authorized keys for ${ACCOUNT} are too old, updating: ${ORIGIN_TIME} vs ${TARGET_TIME}" - cp "${ORIGIN}" "${TARGET}" - fi - else - echo "The environments do not match, skipping: ${ORIGIN_ENV} vs ${TARGET_ENV}" - fi -done diff --git a/ic-os/hostos/rootfs/opt/ic/bin/detect-first-boot.sh b/ic-os/hostos/rootfs/opt/ic/bin/detect-first-boot.sh deleted file mode 100755 index d8295d4afb4..00000000000 --- a/ic-os/hostos/rootfs/opt/ic/bin/detect-first-boot.sh +++ /dev/null @@ -1,118 +0,0 @@ -#!/bin/bash - -set -e - -# Detect the first boot of GuestOS virtual machine. - -SCRIPT="$(basename $0)[$$]" -METRICS_DIR="/run/node_exporter/collector_textfile" -FIRST_BOOT_FILE="/boot/config/first_boot" - -# Get keyword arguments -for argument in "${@}"; do - case ${argument} in - -h | --help) - echo 'Usage: -Detect GuestOS Virtual Machine First Boot - -Arguments: - -h, --help show this help message and exit -' - exit 1 - ;; - *) - echo "Error: Argument is not supported." - exit 1 - ;; - esac -done - -write_log() { - local message=$1 - - if [ -t 1 ]; then - echo "${SCRIPT} ${message}" >/dev/stdout - fi - - logger -t ${SCRIPT} "${message}" -} - -write_metric() { - local name=$1 - local value=$2 - local help=$3 - local type=$4 - - echo -e "# HELP ${name} ${help}\n# TYPE ${type}\n${name} ${value}" >"${METRICS_DIR}/${name}.prom" -} - -function print_to_terminal() { - local message=$1 - - echo "${SCRIPT} ${message}" >/dev/tty1 -} - -function get_first_boot_state() { - if [ -r ${FIRST_BOOT_FILE} ]; then - FIRST_BOOT_STATE=$(cat ${FIRST_BOOT_FILE}) - else - FIRST_BOOT_STATE=1 - fi -} - -function request_hsm() { - retry=0 - /opt/ic/bin/hsm-utils.sh --check - while [ ${?} -ne 0 ]; do - let retry=retry+1 - if [ ${retry} -ge 3600 ]; then - write_log "Nitrokey HSM USB device could not be detected, giving up." - write_metric "hostos_guestos_first_boot_hsm_state" \ - "1" \ - "GuestOS virtual machine first boot HSM state" \ - "gauge" - exit 1 - else - message="Please insert Nitrokey HSM USB device." - print_to_terminal "* $(echo ${message}).." - write_log "${message}" - write_metric "hostos_guestos_first_boot_hsm_state" \ - "0" \ - "GuestOS virtual machine first boot HSM state" \ - "gauge" - sleep 3 - fi - done -} - -function write_first_boot_state() { - echo "0" >${FIRST_BOOT_FILE} -} - -function detect_first_boot() { - get_first_boot_state - - if [ ${FIRST_BOOT_STATE} -eq 1 ]; then - write_log "First boot detected." - request_hsm - write_log "HSM was detected, continuing with startup." - write_first_boot_state - write_metric "hostos_guestos_first_boot_state state" \ - "1" \ - "GuestOS virtual machine first boot" \ - "gauge" - else - write_log "Not first boot, continuing with startup." - write_metric "hostos_guestos_first_boot_state" \ - "0" \ - "GuestOS virtual machine first boot state" \ - "gauge" - fi -} - -function main() { - # Establish run order - detect_first_boot -} - -main diff --git a/ic-os/hostos/rootfs/opt/ic/bin/fetch-mgmt-mac.sh b/ic-os/hostos/rootfs/opt/ic/bin/fetch-mgmt-mac.sh deleted file mode 100755 index 76d6c52fd00..00000000000 --- a/ic-os/hostos/rootfs/opt/ic/bin/fetch-mgmt-mac.sh +++ /dev/null @@ -1,78 +0,0 @@ -#!/bin/bash - -set -e - -# Fetch the management MAC address of the physical machine. - -SCRIPT="$(basename $0)[$$]" -METRICS_DIR="/run/node_exporter/collector_textfile" - -# Get keyword arguments -for argument in "${@}"; do - case ${argument} in - -h | --help) - echo 'Usage: -Fetch Management MAC Address - -Arguments: - -h, --help show this help message and exit -' - exit 1 - ;; - *) - echo "Error: Argument is not supported." - exit 1 - ;; - esac -done - -write_log() { - local message=$1 - - if [ -t 1 ]; then - echo "${SCRIPT} ${message}" >/dev/stdout - fi - - logger -t ${SCRIPT} "${message}" -} - -write_metric() { - local name=$1 - local value=$2 - local help=$3 - local type=$4 - - echo -e "# HELP ${name} ${help}\n# TYPE ${type}\n${name} ${value}" >"${METRICS_DIR}/${name}.prom" -} - -# Fetch the management MAC address of the physical machine. -# The management MAC address will be used as unique key for: -# - Hostnames -# - IPv6 addresses -function fetch_mgmt_mac() { - MAC=$(ipmitool lan print | sed -e 's/^MAC Address.*\([0-9a-f:]\{17\}\)/\1/' -e t -e d) - - if [ "${MAC}" == "" ]; then - write_log "ERROR: Unable to determine MAC address." - write_metric "hostos_fetch_mgmt_mac" \ - "1" \ - "HostOS fetch management MAC address" \ - "gauge" - exit 1 - else - write_log "Unique management MAC address is: ${MAC}" - write_metric "hostos_fetch_mgmt_mac" \ - "0" \ - "HostOS fetch management MAC address" \ - "gauge" - fi - - echo "${MAC}" -} - -function main() { - # Establish run order - fetch_mgmt_mac -} - -main diff --git a/ic-os/hostos/rootfs/opt/ic/bin/fetch-property.sh b/ic-os/hostos/rootfs/opt/ic/bin/fetch-property.sh deleted file mode 100755 index c3ecf0beee7..00000000000 --- a/ic-os/hostos/rootfs/opt/ic/bin/fetch-property.sh +++ /dev/null @@ -1,116 +0,0 @@ -#!/bin/bash - -set -e - -# Fetch configuration property - -SCRIPT="$(basename $0)[$$]" -METRICS_DIR="/run/node_exporter/collector_textfile" - -# Set argument default -UNIQUE=0 - -# Get keyword arguments -for argument in "${@}"; do - case ${argument} in - -c=* | --config=*) - CONFIG="${argument#*=}" - shift - ;; - -h | --help) - echo 'Usage: -Fetch Configuration Property - -Arguments: - -c=, --config= mandatory: specify the configuration file to read from - -h, --help show this help message and exit - -k=, --key= mandatory: specify the property key - -m=, --metric= mandatory: specify the metric name - -u, --unique optional: read per data center unique property (Default: 0) -' - exit 1 - ;; - -k=* | --key=*) - KEY="${argument#*=}" - shift - ;; - -m=* | --metric=*) - METRIC="${argument#*=}" - shift - ;; - -u | --unique) - UNIQUE=1 - ;; - *) - echo "Error: Argument is not supported." - exit 1 - ;; - esac -done - -function validate_arguments() { - if [ "${CONFIG}" == "" -o "${KEY}" == "" -o "${METRIC}" == "" ]; then - $0 --help - fi -} - -write_log() { - local message=$1 - - if [ -t 1 ]; then - echo "${SCRIPT} ${message}" >/dev/stdout - fi - - logger -t ${SCRIPT} "${message}" -} - -write_metric() { - local name=$1 - local value=$2 - local help=$3 - local type=$4 - - echo -e "# HELP ${name} ${help}\n# TYPE ${type}\n${name} ${value}" >"${METRICS_DIR}/${name}.prom" -} - -function fetch_hsm_fingerprint() { - HSM_FINGERPRINT=$(/opt/ic/bin/hsm-utils.sh --fetch) - - if [ -z "${HSM_FINGERPRINT}" -o "${HSM_FINGERPRINT}" == "null" ]; then - write_log "ERROR: HSM public key fingerprint is invalid." - exit 1 - fi -} - -function fetch_property() { - if [ ${UNIQUE} -eq 1 ]; then - fetch_hsm_fingerprint - PROPERTY=$(jq -r ".network.dcs.\"${HSM_FINGERPRINT}\"$(echo ${KEY})" ${CONFIG}) - else - PROPERTY=$(jq -r "$(echo ${KEY})" ${CONFIG}) - fi - - if [ -z "${PROPERTY}" -o "${PROPERTY}" == "null" ]; then - write_log "ERROR: Unable to fetch property: ${KEY}" - write_metric "$(echo ${METRIC})" \ - "1" \ - "Property: $(echo ${KEY})" \ - "gauge" - exit 1 - else - write_log "Using property: ${PROPERTY}" - write_metric "$(echo ${METRIC})" \ - "0" \ - "Property: $(echo ${KEY})" \ - "gauge" - echo "${PROPERTY}" - fi -} - -function main() { - # Establish run order - validate_arguments - fetch_property -} - -main diff --git a/ic-os/hostos/rootfs/opt/ic/bin/generate-deterministic-ipv6.sh b/ic-os/hostos/rootfs/opt/ic/bin/generate-deterministic-ipv6.sh deleted file mode 100755 index d4fb2fa9b4a..00000000000 --- a/ic-os/hostos/rootfs/opt/ic/bin/generate-deterministic-ipv6.sh +++ /dev/null @@ -1,95 +0,0 @@ -#!/bin/bash - -set -e - -# Generate a deterministic IPV6 address. - -SCRIPT="$(basename $0)[$$]" -METRICS_DIR="/run/node_exporter/collector_textfile" - -# Get keyword arguments -for argument in "${@}"; do - case ${argument} in - -c=* | --config=*) - CONFIG="${argument#*=}" - shift - ;; - -h | --help) - echo 'Usage: -Generate Deterministic IPV6 Address - -Arguments: - -c=, --config= specify the config.json configuration file (Default: /boot/config/config.json) - -h, --help show this help message and exit - -i=, --index= mandatory: specify the single digit node index (Examples: host: 0, guest: 1, boundary: 2) -' - exit 1 - ;; - -i=* | --index=*) - INDEX="${argument#*=}" - shift - ;; - *) - echo "Error: Argument is not supported." - exit 1 - ;; - esac -done - -# Set arguments if undefined -CONFIG="${CONFIG:=/boot/config/config.json}" - -function validate_arguments() { - if [ "${CONFIG}" == "" -o "${INDEX}" == "" ]; then - $0 --help - fi -} - -write_log() { - local message=$1 - - if [ -t 1 ]; then - echo "${SCRIPT} ${message}" >/dev/stdout - fi - - logger -t ${SCRIPT} "${message}" -} - -write_metric() { - local name=$1 - local value=$2 - local help=$3 - local type=$4 - - echo -e "# HELP ${name} ${help}\n# INDEX ${type}\n${name} ${value}" >"${METRICS_DIR}/${name}.prom" -} - -# Generate a deterministic IPV6 address based on the: -# - Deterministic MAC -# - Node index -function generate_deterministic_ipv6() { - local mac_6=$(/opt/ic/bin/generate-deterministic-mac.sh --version=6 --index=${INDEX}) - local ipv6_prefix=$(/opt/ic/bin/fetch-property.sh --key=.ipv6_prefix --metric=hostos_ipv6_prefix --config=${CONFIG} -u) - local ipv6_subnet=$(/opt/ic/bin/fetch-property.sh --key=.ipv6_subnet --metric=hostos_ipv6_subnet --config=${CONFIG} -u) - local output=$(echo "${mac_6}" | sed 's/[.:-]//g' | tr '[:upper:]' '[:lower:]') - local output="${output:0:6}fffe${output:6}" - local output=$(printf "%02x%s" "$((0x${output:0:2} ^ 2))" "${output:2}") - local output=$(echo "${output}" | sed 's/.\{4\}/&:/g;s/:$//') - DETERMINISTIC_IPV6=$(echo "${ipv6_prefix}:${output}${ipv6_subnet}") - - echo "${DETERMINISTIC_IPV6}" - - write_log "Using deterministically generated IPV6 address: ${DETERMINISTIC_IPV6}" - write_metric "hostos_generate_deterministic_ipv6" \ - "0" \ - "HostOS generate deterministic IPV6 address" \ - "gauge" -} - -function main() { - # Establish run order - validate_arguments - generate_deterministic_ipv6 -} - -main diff --git a/ic-os/hostos/rootfs/opt/ic/bin/generate-deterministic-mac.sh b/ic-os/hostos/rootfs/opt/ic/bin/generate-deterministic-mac.sh deleted file mode 100755 index 16342a5fce8..00000000000 --- a/ic-os/hostos/rootfs/opt/ic/bin/generate-deterministic-mac.sh +++ /dev/null @@ -1,100 +0,0 @@ -#!/bin/bash - -set -e - -# Generate a deterministic MAC address. - -SCRIPT="$(basename $0)[$$]" -METRICS_DIR="/run/node_exporter/collector_textfile" - -# Default arguments if undefined -VERSION=6 - -# Get keyword arguments -for argument in "${@}"; do - case ${argument} in - -h | --help) - echo 'Usage: -Generate Deterministic MAC Address - -Arguments: - -h, --help show this help message and exit - -i=, --index= mandatory: specify the single digit node index (Examples: host: 0, guest: 1, boundary: 2) - -v=, --version= optional: specify the IP protocol version (Default: 6) -' - exit 1 - ;; - -i=* | --index=*) - INDEX="${argument#*=}" - shift - ;; - -v=* | --version=*) - VERSION="${argument#*=}" - shift - ;; - *) - echo "Error: Argument is not supported." - exit 1 - ;; - esac -done - -function validate_arguments() { - if [ "${INDEX}" == "" -o "${VERSION}" == "" ]; then - $0 --help - fi -} - -write_log() { - local message=$1 - - if [ -t 1 ]; then - echo "${SCRIPT} ${message}" >/dev/stdout - fi - - logger -t ${SCRIPT} "${message}" -} - -write_metric() { - local name=$1 - local value=$2 - local help=$3 - local type=$4 - - echo -e "# HELP ${name} ${help}\n# INDEX ${type}\n${name} ${value}" >"${METRICS_DIR}/${name}.prom" -} - -# Generate a deterministic MAC address based on the: -# - Management MAC address -# - Deployment name -# - Node index -function generate_deterministic_mac() { - MAC=$(/opt/ic/bin/fetch-mgmt-mac.sh) - DEPLOYMENT=$(/opt/ic/bin/fetch-property.sh --key=.deployment.name --metric=hostos_deployment_name --config=/boot/config/deployment.json) - SEED="${MAC}${DEPLOYMENT}" - VENDOR_PART=$(echo ${SEED} | sha256sum | cut -c 1-8) - - if [ ${VERSION} -eq 4 ]; then - VERSION_OCTET="4a" - else - VERSION_OCTET="6a" - fi - - DETERMINISTIC_MAC=$(echo "${VERSION_OCTET}0${INDEX}${OUI_PART}${VENDOR_PART}" | sed 's/\(..\)/\1:/g;s/:$//') - - echo "${DETERMINISTIC_MAC}" - - write_log "Using deterministically generated MAC address: ${DETERMINISTIC_MAC}" - write_metric "hostos_generate_deterministic_mac" \ - "0" \ - "HostOS generate deterministic MAC address" \ - "gauge" -} - -function main() { - # Establish run order - validate_arguments - generate_deterministic_mac -} - -main diff --git a/ic-os/hostos/rootfs/opt/ic/bin/generate-guestos-config.sh b/ic-os/hostos/rootfs/opt/ic/bin/generate-guestos-config.sh deleted file mode 100755 index 5a824fcf199..00000000000 --- a/ic-os/hostos/rootfs/opt/ic/bin/generate-guestos-config.sh +++ /dev/null @@ -1,133 +0,0 @@ -#!/bin/bash - -set -e - -# Generate the GuestOS configuration. - -SCRIPT="$(basename $0)[$$]" -METRICS_DIR="/run/node_exporter/collector_textfile" - -# Get keyword arguments -for argument in "${@}"; do - case ${argument} in - -c=* | --config=*) - CONFIG="${argument#*=}" - shift - ;; - -d=* | --deployment=*) - DEPLOYMENT="${argument#*=}" - shift - ;; - -h | --help) - echo 'Usage: -Generate GuestOS Configuration - -Arguments: - -c=, --config= specify the config.json configuration file (Default: /boot/config/config.json) - -d=, --deployment= specify the deployment.json configuration file (Default: /boot/config/deployment.json) - -h, --help show this help message and exit - -i=, --input= specify the input template file (Default: /opt/ic/share/guestos.xml.template) - -m=, --media= specify the config media image file (Default: /run/ic-node/config.img) - -o=, --output= specify the output configuration file (Default: /var/lib/libvirt/guestos.xml) -' - exit 1 - ;; - -i=* | --input=*) - INPUT="${argument#*=}" - shift - ;; - -m=* | --media=*) - MEDIA="${argument#*=}" - shift - ;; - -o=* | --output=*) - OUTPUT="${argument#*=}" - shift - ;; - *) - echo "Error: Argument is not supported." - exit 1 - ;; - esac -done - -function validate_arguments() { - if [ "${CONFIG}" == "" -o "${DEPLOYMENT}" == "" -o "${INPUT}" == "" -o "${OUTPUT}" == "" ]; then - $0 --help - fi -} - -# Set arguments if undefined -CONFIG="${CONFIG:=/boot/config/config.json}" -DEPLOYMENT="${DEPLOYMENT:=/boot/config/deployment.json}" -INPUT="${INPUT:=/opt/ic/share/guestos.xml.template}" -MEDIA="${MEDIA:=/run/ic-node/config.img}" -OUTPUT="${OUTPUT:=/var/lib/libvirt/guestos.xml}" - -write_log() { - local message=$1 - - if [ -t 1 ]; then - echo "${SCRIPT} ${message}" >/dev/stdout - fi - - logger -t ${SCRIPT} "${message}" -} - -write_metric() { - local name=$1 - local value=$2 - local help=$3 - local type=$4 - - echo -e "# HELP ${name} ${help}\n# INDEX ${type}\n${name} ${value}" >"${METRICS_DIR}/${name}.prom" -} - -function assemble_config_media() { - cmd=(/opt/ic/bin/build-bootstrap-config-image.sh ${MEDIA}) - if [ -d "/boot/config/guestos_accounts_ssh_authorized_keys" ]; then - cmd+=(--accounts_ssh_authorized_keys /boot/config/guestos_accounts_ssh_authorized_keys) - fi - cmd+=(--nns_public_key "/boot/config/nns_public_key.pem") - cmd+=(--journalbeat_hosts "$(/opt/ic/bin/fetch-property.sh --key=.logging.hosts --metric=hostos_logging_hosts --config=${DEPLOYMENT})") - cmd+=(--ipv6_address "$(/opt/ic/bin/generate-deterministic-ipv6.sh --index=1)") - cmd+=(--ipv6_gateway "$(/opt/ic/bin/fetch-property.sh --key=.ipv6_gateway --metric=hostos_ipv6_gateway --config=${CONFIG} -u)") - cmd+=(--name_servers "$(/opt/ic/bin/fetch-property.sh --key=.network.name_servers --metric=hostos_name_servers --config=${CONFIG})") - cmd+=(--hostname "guest-$(/opt/ic/bin/fetch-mgmt-mac.sh | sed 's/://g')") - cmd+=(--nns_url "$(/opt/ic/bin/fetch-property.sh --key=.nns.url --metric=hostos_nns_url --config=${DEPLOYMENT})") - - # Run the above command - "${cmd[@]}" - write_log "Assembling config media for GuestOS: ${MEDIA}" -} - -function generate_guestos_config() { - RESOURCES_MEMORY=$(/opt/ic/bin/fetch-property.sh --key=.resources.memory --metric=hostos_resources_memory --config=${DEPLOYMENT}) - MAC_ADDRESS=$(/opt/ic/bin/generate-deterministic-mac.sh --index=1) - - if [ ! -f "${OUTPUT}" ]; then - sed -e "s@{{ resources_memory }}@${RESOURCES_MEMORY}@" \ - -e "s@{{ mac_address }}@${MAC_ADDRESS}@" \ - "${INPUT}" >"${OUTPUT}" - write_log "Generating GuestOS configuration file: ${OUTPUT}" - write_metric "hostos_generate_guestos_config" \ - "1" \ - "HostOS generate GuestOS config" \ - "gauge" - else - write_log "GuestOS configuration file already exists: ${OUTPUT}" - write_metric "hostos_generate_guestos_config" \ - "0" \ - "HostOS generate GuestOS config" \ - "gauge" - fi -} - -function main() { - # Establish run order - validate_arguments - assemble_config_media - generate_guestos_config -} - -main diff --git a/ic-os/hostos/rootfs/opt/ic/bin/generate-journalbeat-config.sh b/ic-os/hostos/rootfs/opt/ic/bin/generate-journalbeat-config.sh deleted file mode 100755 index b5802d3896e..00000000000 --- a/ic-os/hostos/rootfs/opt/ic/bin/generate-journalbeat-config.sh +++ /dev/null @@ -1,87 +0,0 @@ -#!/bin/bash - -set -e - -# Generate the Journalbeat configuration. - -SCRIPT="$(basename $0)[$$]" -METRICS_DIR="/run/node_exporter/collector_textfile" - -# Get keyword arguments -for argument in "${@}"; do - case ${argument} in - -c=* | --config=*) - CONFIG="${argument#*=}" - shift - ;; - -h | --help) - echo 'Usage: -Generate Journalbeat Configuration - -Arguments: - -c=, --config= specify the deployment.json configuration file (Default: /boot/config/deployment.json) - -h, --help show this help message and exit - -i=, --input= specify the input template file (Default: /etc/journalbeat/journalbeat.yml.template) - -o=, --output= specify the output configuration file (Default: /run/ic-node/etc/journalbeat/journalbeat.yml) -' - exit 1 - ;; - -i=* | --input=*) - INPUT="${argument#*=}" - shift - ;; - -o=* | --output=*) - OUTPUT="${argument#*=}" - shift - ;; - *) - echo "Error: Argument is not supported." - exit 1 - ;; - esac -done - -# Set arguments if undefined -CONFIG="${CONFIG:=/boot/config/deployment.json}" -INPUT="${INPUT:=/etc/journalbeat/journalbeat.yml.template}" -OUTPUT="${OUTPUT:=/run/ic-node/etc/journalbeat/journalbeat.yml}" - -write_log() { - local message=$1 - - if [ -t 1 ]; then - echo "${SCRIPT} ${message}" >/dev/stdout - fi - - logger -t ${SCRIPT} "${message}" -} - -write_metric() { - local name=$1 - local value=$2 - local help=$3 - local type=$4 - - echo -e "# HELP ${name} ${help}\n# INDEX ${type}\n${name} ${value}" >"${METRICS_DIR}/${name}.prom" -} - -function generate_journalbeat_config() { - JOURNALBEAT_HOSTS=$(/opt/ic/bin/fetch-property.sh --key=.logging.hosts --metric=hostos_logging_hosts --config=${CONFIG}) - - if [ "${JOURNALBEAT_HOSTS}" != "" ]; then - # Covert string into comma separated array - if [ "$(echo ${JOURNALBEAT_HOSTS} | grep ':')" ]; then - journalbeat_hosts_array=$(for host in ${JOURNALBEAT_HOSTS}; do echo -n "\"${host}\", "; done | sed -E "s@, \$@@g") - else - journalbeat_hosts_array=$(for host in ${JOURNALBEAT_HOSTS}; do echo -n "\"${host}:443\", "; done | sed -E "s@, \$@@g") - fi - sed -e "s@{{ journalbeat_hosts }}@${journalbeat_hosts_array}@" "${INPUT}" >"${OUTPUT}" - fi -} - -function main() { - # Establish run order - generate_journalbeat_config -} - -main diff --git a/ic-os/hostos/rootfs/opt/ic/bin/generate-network-config.sh b/ic-os/hostos/rootfs/opt/ic/bin/generate-network-config.sh deleted file mode 100755 index 5dea0afb779..00000000000 --- a/ic-os/hostos/rootfs/opt/ic/bin/generate-network-config.sh +++ /dev/null @@ -1,287 +0,0 @@ -#!/bin/bash - -set -e - -# Generate the network configuration. - -SCRIPT="$(basename $0)[$$]" -METRICS_DIR="/run/node_exporter/collector_textfile" - -# Get keyword arguments -for argument in "${@}"; do - case ${argument} in - -c=* | --config=*) - CONFIG="${argument#*=}" - shift - ;; - -h | --help) - echo 'Usage: -Generate Network Configuration - -Arguments: - -c=, --config= specify the config.json configuration file (Default: /boot/config/config.json) - -h, --help show this help message and exit - -o=, --output= specify the systemd-networkd output directory (Default: /run/systemd/network) -' - exit 1 - ;; - -t=* | --type=*) - TYPE="${argument#*=}" - shift - ;; - *) - echo "Error: Argument is not supported." - exit 1 - ;; - esac -done - -# Set arguments if undefined -CONFIG="${CONFIG:=/boot/config/config.json}" -OUTPUT="${OUTPUT:=/run/systemd/network}" - -function validate_arguments() { - if [ "${CONFIG}" == "" -o "${OUTPUT}" == "" ]; then - $0 --help - fi -} - -function generate_name_server_list() { - if [ "${NAME_SERVERS}" != "null" ]; then - for name_server in ${NAME_SERVERS}; do - echo DNS="${name_server}" - done - fi -} - -# Convert MAC address to SLAAC compatible (EUI64) IPv6 address -function generate_ipv6_address() { - # TODO: This field is not mandatory, so we need to be able to optionally grab it - overrides=$(jq -r ".overrides" ${CONFIG}) - if [ "${overrides}" != "null" ]; then - IPV6_ADDRESS=$(/opt/ic/bin/fetch-property.sh --key=.overrides.ipv6_address --metric=overrides_ipv6_address --config=${CONFIG}) - IPV6_GATEWAY=$(/opt/ic/bin/fetch-property.sh --key=.overrides.ipv6_gateway --metric=overrides_ipv6_gateway --config=${CONFIG}) - - # TODO: This field is not mandatory, so we need to be able to optionally grab it - NAME_SERVERS=$(jq -r ".overrides.name_servers" ${CONFIG}) - else - IPV6_GATEWAY=$(/opt/ic/bin/fetch-property.sh --key=.ipv6_gateway --metric=hostos_ipv6_gateway --config=${CONFIG} -u) - # TODO: This field is not mandatory, so we need to be able to optionally grab it - NAME_SERVERS=$(jq -r ".network.name_servers" ${CONFIG}) - - MAC_6=$(/opt/ic/bin/generate-deterministic-mac.sh --version=6 --index=0) - MAC_4=$(/opt/ic/bin/generate-deterministic-mac.sh --version=4 --index=0) - IPV6_ADDRESS=$(/opt/ic/bin/generate-deterministic-ipv6.sh --index=0) - fi -} - -# Detect physical network interfaces -function detect_network_interfaces() { - INTERFACES=($(find /sys/class/net -type l -not -lname '*virtual*' -exec basename '{}' ';' | sort)) - INTERFACES_10GBE=() - INTERFACES_1GBE=() - - # Detect interface speed - for interface in ${INTERFACES[@]}; do - if [ "$(ethtool ${interface} | grep '10000baseT/Full')" ]; then - INTERFACES_10GBE+=("${interface}") - else - INTERFACES_1GBE+=("${interface}") - fi - done -} - -# Generate network configuration files -function generate_network_config() { - if [ -d /run/systemd ]; then - mkdir -p /run/systemd/network - fi - - # 10 Gigabit Ethernet Network Interfaces - for interface in ${INTERFACES_10GBE[0]}; do - ( - cat <"${OUTPUT}/10-${interface}.network" - done - - # 10-bond4.netdev - ( - if [ "${MAC_4}" != "" ]; then - local MAC="MACAddress=${MAC_4}" - fi - cat <"${OUTPUT}/10-bond4.netdev" - - # 10-bond4.network - ( - cat <"${OUTPUT}/10-bond4.network" - - # 10-br4.netdev - ( - cat <"${OUTPUT}/10-br4.netdev" - - # 10-br4.network - ( - cat <"${OUTPUT}/10-br4.network" - - # 10 Gigabit Ethernet Network Interfaces - for interface in ${INTERFACES_10GBE[1]}; do - ( - cat <"${OUTPUT}/20-${interface}.network" - done - - # 20-bond6.netdev - ( - if [ "${MAC_4}" != "" ]; then - local MAC="MACAddress=${MAC_6}" - fi - cat <"${OUTPUT}/20-bond6.netdev" - - # 20-bond6.network - ( - cat <"${OUTPUT}/20-bond6.network" - - # 20-br6.netdev - ( - cat <"${OUTPUT}/20-br6.netdev" - - # 20-br6.network - ( - cat <"${OUTPUT}/20-br6.network" - - # 1 Gigabit Ethernet Network Interfaces - for interface in ${INTERFACES_1GBE[@]}; do - ( - if [ "${#INTERFACES_1GBE[@]}" -eq "1" ]; then - local BOND="Bond=bond6" - fi - cat <"${OUTPUT}/30-${interface}.network" - done -} - -function main() { - # Establish run order - validate_arguments - detect_network_interfaces - generate_ipv6_address - generate_network_config -} - -main diff --git a/ic-os/hostos/rootfs/opt/ic/bin/hostos-vsock-agent/__init__.py b/ic-os/hostos/rootfs/opt/ic/bin/hostos-vsock-agent/__init__.py deleted file mode 100644 index e69de29bb2d..00000000000 diff --git a/ic-os/hostos/rootfs/opt/ic/bin/hostos-vsock-agent/hostos_vsock_agent.py b/ic-os/hostos/rootfs/opt/ic/bin/hostos-vsock-agent/hostos_vsock_agent.py deleted file mode 100644 index 2c142b08630..00000000000 --- a/ic-os/hostos/rootfs/opt/ic/bin/hostos-vsock-agent/hostos_vsock_agent.py +++ /dev/null @@ -1,71 +0,0 @@ -#!/usr/local/bin/env python3 -import argparse -import asyncio -import logging -import sys - -import vsock_client -import vsock_server - - -def client_handler(args): - if args.verbose: - logging.basicConfig(level=logging.DEBUG) - else: - logging.basicConfig(level=logging.INFO) - - client = vsock_client.VsockStream() - endpoint = (args.cid, args.port) - client.connect(endpoint) - msg = "Hello, world!" - client.send_data(msg.encode()) - - -def server_handler(args): - if args.verbose: - logging.basicConfig(level=logging.DEBUG) - else: - logging.basicConfig(level=logging.INFO) - - # We use an async server to support multiple clients sending requests in parallel - server = vsock_server.AsyncVsockListener(args.port) - asyncio.run(server.main_loop()) - - -def main(): - parser = argparse.ArgumentParser(prog="vsock-sample") - parser.add_argument( - "--version", - action="version", - help="Prints version information.", - version="%(prog)s 0.1.0", - ) - subparsers = parser.add_subparsers(title="options") - - client_parser = subparsers.add_parser("client", description="Client", help="Connect to a given cid and port.") - client_parser.add_argument("--verbose", "-v", action="store_true", help="Verbose mode") - client_parser.add_argument("cid", type=int, help="The remote endpoint CID.") - client_parser.add_argument("port", type=int, help="The remote endpoint port.") - client_parser.set_defaults(func=client_handler) - - server_parser = subparsers.add_parser("server", description="Server", help="Listen on a given port.") - server_parser.add_argument( - "--port", - type=int, - default=19090, - help="The local port to listen on.", - ) - server_parser.add_argument("--verbose", "-v", action="store_true", help="Verbose mode") - - server_parser.set_defaults(func=server_handler) - - if len(sys.argv) < 2: - parser.print_usage() - sys.exit(1) - - args = parser.parse_args() - args.func(args) - - -if __name__ == "__main__": - main() diff --git a/ic-os/hostos/rootfs/opt/ic/bin/hostos-vsock-agent/libvirt_domains.py b/ic-os/hostos/rootfs/opt/ic/bin/hostos-vsock-agent/libvirt_domains.py deleted file mode 100644 index 514f17ac4f6..00000000000 --- a/ic-os/hostos/rootfs/opt/ic/bin/hostos-vsock-agent/libvirt_domains.py +++ /dev/null @@ -1,63 +0,0 @@ -import logging -import sys -from xml.dom import minidom - -import libvirt - - -class CidLibvirtDomain: - """Maps the CID to LibVirt Domains.""" - - def __init__(self): - """Init the object.""" - try: - self.conn = libvirt.openReadOnly(None) - except libvirt.libvirtError: - print("Failed to open connection to the hypervisor") - sys.exit(1) - - self._domains = {} - self.refresh_domains() - - def refresh_domains(self): - """Get a list of domains. Then updates self.domains to have {cid: domain_name}.""" - self._domains = {} - domain_ids = self.conn.listDomainsID() - if domain_ids is None: - logging.error("LibVirt: failed to get a list of domain IDs") - else: - for domain_id in domain_ids: - domain = self.conn.lookupByID(domain_id) - domain_raw_xml = domain.XMLDesc(0) - domain_cids = self._extract_domain_cids(domain_raw_xml) - for cid in domain_cids: - self._domains[cid] = domain.name() - # logging.debug("LibVirt: refreshed VM domains %s", self._domains) - if not self._domains: - logging.warning("LibVirt: no domains with vsock and CIDs found") - - def _extract_domain_cids(self, raw_xml): - """Extract the vsock CIDs in the provided XML description.""" - xml = minidom.parseString(raw_xml) - cids = [] - for vsock in xml.getElementsByTagName("vsock"): - if vsock.getAttribute("model") == "virtio": - for cid_elem in vsock.getElementsByTagName("cid"): - cid = cid_elem.getAttribute("address") - if cid: - cids.append(cid) - return cids - - def cid_to_domain(self, cid): - """Translate the domain's CID to the domain name.""" - if cid not in self._domains: - self.refresh_domains() - return self._domains.get(cid) - - def list_cids(self): - """List all found CIDs.""" - return list(self._domains.keys()) - - def list_domain_names(self): - """List all found domain names.""" - return sorted(list(self._domains.values())) diff --git a/ic-os/hostos/rootfs/opt/ic/bin/hostos-vsock-agent/vsock_agent.py b/ic-os/hostos/rootfs/opt/ic/bin/hostos-vsock-agent/vsock_agent.py deleted file mode 100644 index b646379a44f..00000000000 --- a/ic-os/hostos/rootfs/opt/ic/bin/hostos-vsock-agent/vsock_agent.py +++ /dev/null @@ -1,348 +0,0 @@ -""" -Attaches the HSM to the guest VM domains, when they request HSM access. - -The script periodically scans the attached HSMs and the guest VM domains. -* If an "attach-hsm" message comes from a guest VM domain (A) and the HSM is not already attached - to any guest, the HSM will immediately be attached to the requesting VM. -* The HSM is detached from the guest VM after HSM_ATTACH_SECONDS, and will be immediately attached - to other guest VM domain if there is a pending request. -* Every RESET_AFTER_SECONDS, if the HSM has been attached to any VM domain, the HSM will be - detached from all guest VM domains, and the struct will be reinitialized (reset). - This is done to address some libvirt (or qemu/kvm) issues where the HSM stays half-attached to - the guest VM, but the HSM isn't usable within the VM. -""" -import asyncio -import hashlib -import logging -import os -import subprocess -import tempfile -import textwrap -import threading -import time -from threading import Timer - -import libvirt_domains -import requests - -HSM_VENDOR = "20a0" -HSM_PRODUCT = "4230" -HSM_ATTACH_SECONDS = 10 # Period after which the HSM is passed to another domain, if there are requests. -RESET_AFTER_SECONDS = 60 # After this many seconds, reset the object (and detach the HSM from all domains) - - -class VsockAgent: - """Manages running functions on the server side of the VSOCK communication.""" - - def __init__(self, libvirt_handler=None, with_timer=True): - """Init the VSOCK agent class.""" - threading.excepthook = threading_exception_hook - if libvirt_handler: - self.lv = libvirt_handler - else: - self.lv = libvirt_domains.CidLibvirtDomain() - self.hsm_dev_xml_desc = tempfile.mkstemp()[1] - self.with_timer = with_timer # Allows more controlled testing - if self.with_timer: - self.timer = Timer(HSM_ATTACH_SECONDS, self._periodic_checks) - self.timer.start() - else: - self.timer = None - self.lock = threading.Lock() - self._reset() - - def _reset(self): - logging.debug("HSM agent: Initializing") - self.hsm_attach_reqs = {} - self.hsm_detach_reqs = {} - self.attached_cid = None - self.attached_timestamp = None - self.resets_enable = False # resets are enabled if there were any attach requests - self.reset_counter = RESET_AFTER_SECONDS / HSM_ATTACH_SECONDS - self.lsusb_hsm_dev = None - self._lsusb_parse_hsm_dev() - self._remove_hsm_from_all_domains() - - def _periodic_checks(self): - logging.debug("HSM agent: Running periodic checks") - with self.lock: - if self.reset_counter > 0 and self.lv.list_cids(): - # If there are active VM domains, run the reset counter - self.reset_counter -= 1 - if self.resets_enable and self.reset_counter <= 0: - self._reset() - else: - self._lsusb_parse_hsm_dev() - self.lv.refresh_domains() - self._detach_hsm_if_needed() - self._process_detach_requests() - self._process_one_attach_request() - if self.with_timer: - self.timer = Timer(HSM_ATTACH_SECONDS, self._periodic_checks) - self.timer.start() - - def terminate(self): - """Cleanup the temp files and stop the timer.""" - if self.attached_cid: - logging.info("Removing HSM from domain %s", self.lv.cid_to_domain(self.attached_cid)) - self._detach_hsm() - if self.hsm_dev_xml_desc: - logging.info("Removing temp file %s", self.hsm_dev_xml_desc) - os.unlink(self.hsm_dev_xml_desc) - self.hsm_dev_xml_desc = None - if self.timer: - logging.info("Stopping the timer") - self.timer.cancel() - self.timer = None - - def __del__(self): - """Cleanup before deleting the object.""" - self.terminate() - - def _remove_hsm_from_all_domains(self): - for cid in self.lv.list_cids(): - logging.info( - "Ensuring HSM is not in domain %s", - self.lv.cid_to_domain(cid), - ) - self._detach_hsm_unchecked(cid) - - def _lsusb_parse_hsm_dev(self): - lsusb_lines = subprocess.check_output(["lsusb"]).strip().decode("utf8").splitlines() - lsusb_hsm = [_ for _ in lsusb_lines if f"{HSM_VENDOR}:{HSM_PRODUCT}" in _] - if len(lsusb_hsm) < 1: - logging.info("No HSM devices detected") - self.lsusb_hsm_dev = None - return - elif len(lsusb_hsm) > 1: - logging.info("More than one HSM devices detected, will use the first one") - lsusb_hsm = sorted(lsusb_hsm)[0].split() - if self.lsusb_hsm_dev != lsusb_hsm: - self.lsusb_hsm_dev = lsusb_hsm - self._prepare_libvirt_hsm_dev_xml() - - def _prepare_libvirt_hsm_dev_xml(self): - # Runs the following steps: - # 1. run lsusb - # 2. extract lines with desired VENDOR:PRODUCT - # 3. take the first HSM device - # 4. prepare the XML file with the HSM device description - if not self.lsusb_hsm_dev: - logging.debug("No HSM dev found. Can't prepare the HSM dev XML description.") - return - hsm_bus = int(self.lsusb_hsm_dev[1]) - hsm_device = int(self.lsusb_hsm_dev[3].replace(":", "")) - with open(self.hsm_dev_xml_desc, "w") as f: - f.write( - textwrap.dedent( - f""" - - - - -
- -
- - """ - ) - ) - print("HSM device XML description for LibVirt:") - print(open(self.hsm_dev_xml_desc).read()) - - def _detach_hsm_unchecked(self, guest_cid): - """Try to detach the HSM device from the guest, but don't check for success.""" - domain = self.lv.cid_to_domain(guest_cid) - logging.debug("Trying to detach the HSM device from domain %s", domain) - cmd = ["virsh", "detach-device", domain, "--file", self.hsm_dev_xml_desc] - subprocess.call(cmd) - - def _detach_hsm(self): - """Detach the HSM device from the currently attached guest, and check for success.""" - domain = self.lv.cid_to_domain(self.attached_cid) - logging.info( - "Detaching the HSM device from domain %s (cid %s)", - domain, - self.attached_cid, - ) - cmd = ["virsh", "detach-device", domain, "--file", self.hsm_dev_xml_desc] - subprocess.check_call(cmd) - self.attached_cid = None - self.attached_timestamp = None - - def _detach_hsm_if_needed(self): - if self.attached_cid: - if not self.lsusb_hsm_dev: - logging.debug( - "HSM attached to CID %s but detached on the host. Detaching from the guest.", - self.attached_cid, - ) - self._detach_hsm() - return - if not self.lv.cid_to_domain(self.attached_cid): - logging.debug( - "HSM attached to CID %s which does not exist anymore. Marking as detached.", - self.attached_cid, - ) - self.attached_cid = None - self.attached_timestamp = None - return - if self.attached_cid and self.attached_timestamp: - # HSM is attached to the domain guest - if time.time() - self.attached_timestamp < HSM_ATTACH_SECONDS: - # but for a short time - logging.debug( - "HSM attached to domain %s and the timer didn't expire", - self.attached_cid, - ) - return - else: - logging.debug( - "HSM attached to domain %s and the timer expired", - self.attached_cid, - ) - self._detach_hsm() - - def _attach_hsm(self, guest_cid): - if not self.lsusb_hsm_dev: - logging.debug("HSM not present on the host. Cannot attach to the guest.") - return - domain = self.lv.cid_to_domain(guest_cid) - logging.info("Attaching the HSM device to domain %s (cid %s)", domain, guest_cid) - cmd = ["virsh", "attach-device", domain, "--file", self.hsm_dev_xml_desc] - subprocess.check_call(cmd) - self.attached_cid = guest_cid - self.attached_timestamp = time.time() - - def _process_one_attach_request(self): - """ - Attach the HSM to a domain, if there are pending requests. - - The HSM gets attached to a domain when the domain requests it. - If the HSM is already attached to another domain, then the new request is queued up. - """ - self._detach_hsm_if_needed() - if self.attached_cid: - # HSM is still attached to a domain. - # The current request will be processed later, in self._periodic_checks() - logging.info( - "HSM currently attached to: %s (%s)", - self.lv.cid_to_domain(self.attached_cid), - self.attached_cid, - ) - return - if self.hsm_attach_reqs: - logging.info("HSM attach reqs: %s", self.hsm_attach_reqs) - guest_cid = self.hsm_attach_reqs.popitem()[0] - self._attach_hsm(guest_cid) - - def _process_detach_requests(self): - """ - Detach the HSM from a domain, if there are such requests. - - The HSM is detached from a domain when the domain either: - a) explicitly requests that the HSM is detached, or - b) when the timeout of HSM_ATTACH_SECONDS expires. - However, if no other domain requests the HSM to be attached, - the HSM will not be detached immediately. - """ - # The HSM is kept attached if other guest do not needs the HSM - if not self.hsm_attach_reqs: - return - for cid, _ts in self.hsm_detach_reqs.copy().items(): - logging.info("Processing the HSM detach request from: %s", cid) - if cid == self.attached_cid: - self._detach_hsm() - else: - self._detach_hsm_unchecked(cid) - if cid in self.hsm_detach_reqs: - del self.hsm_detach_reqs[cid] - if self.attached_cid is None: - self._process_one_attach_request() - - def _upgrade(self, info): - """ - Upgrade this machine. - - Use `info` to apply upgrade image to alternate install partitions (A or - B). - """ - UPGRADE_PATH = "/tmp/upgrade.tar.gz" - logging.info("Downloading image: " + info.url) - r = requests.get(info.url) - with open(UPGRADE_PATH, "wb") as f: - f.write(r.content) - f.truncate() - - logging.info("Checking image hash against: " + info.target_hash) - hasher = hashlib.sha256() - BUFF_SIZE = 65536 - with open(UPGRADE_PATH, "rb") as f: - # Chunk up the hashing - while True: - data = f.read(BUFF_SIZE) - if not data: - break - hasher.update(data) - download_hash = hasher.hexdigest() - - if download_hash != info.target_hash: - logging.debug("Download failed, incorrect hash.") - return - - logging.info("Applying update.") - cmd = ["sudo", "/opt/ic/bin/install-upgrade.sh", UPGRADE_PATH] - subprocess.check_call(cmd) - - logging.info("Update applied, going down for reboot.") - cmd = ["sudo", "reboot"] - subprocess.check_call(cmd) - - def handle_attach_request(self, sender_cid): - """Handle the HSM attach request from the sender_cid.""" - logging.info("Registering the HSM attach request from: %s", sender_cid) - with self.lock: - if sender_cid not in self.hsm_attach_reqs and sender_cid != self.attached_cid: - self.hsm_attach_reqs[sender_cid] = time.time() - self.resets_enable = True - self._process_one_attach_request() - - def handle_detach_request(self, sender_cid): - """Handle the HSM detach request from the sender_cid.""" - logging.info("Registering the HSM detach request from: %s", sender_cid) - with self.lock: - self.hsm_detach_reqs[sender_cid] = time.time() - self._process_detach_requests() - - def set_node_id(self, sender_cid, node_id): - """Set node ID from guest-os.""" - logging.info("Setting node ID, from: %s", sender_cid) - with open("/boot/config/node-id", "w") as f: - f.write(node_id) - cmd = ["sudo", "/opt/ic/bin/setup-hostname.sh", "--type=host"] - subprocess.check_call(cmd) - - def handle_join_success(self, sender_cid): - """Notify of a successful join request.""" - - async def alert(): - with open("/dev/tty1", "w") as tty: - for _ in range(20): - tty.write("Join request successful!\n") - tty.write("You may now safely remove the HSM\n\n") - await asyncio.sleep(2) - - logging.info("Notifying a successful join from: %s", sender_cid) - return alert() - - def handle_upgrade_request(self, sender_cid, info): - """Handle an upgrade request from the sender_cid.""" - logging.info("Upgrade hostOS on request of: %s", sender_cid) - self._upgrade(info) - - -def threading_exception_hook(args): - logging.exception("Caught an exception in a thread, exiting") - # Exit the process with status n, without calling cleanup handlers, flushing stdio buffers, etc. - # https://docs.python.org/3/library/os.html#os._exit - os._exit(1) diff --git a/ic-os/hostos/rootfs/opt/ic/bin/hostos-vsock-agent/vsock_client.py b/ic-os/hostos/rootfs/opt/ic/bin/hostos-vsock-agent/vsock_client.py deleted file mode 100644 index aae4f63e0b3..00000000000 --- a/ic-os/hostos/rootfs/opt/ic/bin/hostos-vsock-agent/vsock_client.py +++ /dev/null @@ -1,20 +0,0 @@ -import socket - - -class VsockStream: - """Vsock (stream) client.""" - - def __init__(self, conn_tmo=5): - """Create a new vsock client.""" - self.conn_tmo = conn_tmo - - def connect(self, endpoint): - """Connect to the remote endpoint.""" - self.sock = socket.socket(socket.AF_VSOCK, socket.SOCK_STREAM) - self.sock.settimeout(self.conn_tmo) - self.sock.connect(endpoint) - - def send_data(self, data): - """Send data to the remote endpoint.""" - self.sock.sendall(data) - self.sock.close() diff --git a/ic-os/hostos/rootfs/opt/ic/bin/hostos-vsock-agent/vsock_server.py b/ic-os/hostos/rootfs/opt/ic/bin/hostos-vsock-agent/vsock_server.py deleted file mode 100644 index 51fc24b256d..00000000000 --- a/ic-os/hostos/rootfs/opt/ic/bin/hostos-vsock-agent/vsock_server.py +++ /dev/null @@ -1,97 +0,0 @@ -import asyncio -import json -import logging -import socket -from collections import namedtuple - -import vsock_agent - - -class AsyncVsockListener: - """ - Async Vsock Server. Serves clients concurrently. - - Based on: - https://docs.python.org/3.8/library/asyncio-stream.html#tcp-echo-client-using-streams - """ - - def __init__(self, port, conn_backlog=128): - """Init the server with the given port and the connection backlog.""" - self.port = port - self.conn_backlog = conn_backlog - self.vsock_agent = vsock_agent.VsockAgent() - - async def _handle_connection(self, reader, writer): - data = await reader.read(1024 * 1024) # a message may be up to 1MiB in size - message = data.decode() - addr = writer.get_extra_info("peername") - sender_cid = str(addr[0]) - task = None - try: - message_json = json.loads(message) - logging.info("Received a message from %s: %s", addr, message_json) - - # As a sanity check, we request that the sender adds its own CID to the message - # and that *must* match the addr[0] CID - message_cid = str(message_json.get("sender_cid", "0")) - - if message_cid == sender_cid: - response = json.dumps({"message": "accepted request", "status": "ok"}) - request = message_json.get("message") - if request == "attach-hsm": - self.vsock_agent.handle_attach_request(sender_cid) - elif request == "detach-hsm": - self.vsock_agent.handle_detach_request(sender_cid) - elif request.startswith("set-node-id"): - node_id = request[12:-1] - self.vsock_agent.set_node_id(sender_cid, node_id) - elif request == "join-success": - task = self.vsock_agent.handle_join_success(sender_cid) - elif request.startswith("upgrade"): - data = request[8:-1].split() - Info = namedtuple("Info", ["url", "target_hash"]) - info = Info(data[0], data[1]) - self.vsock_agent.handle_upgrade_request(sender_cid, info) - else: - logging.warning("Unsupported request from %s: %s", addr, request) - else: - logging.warning("Non-matching sender CID %s in message: %s", addr, message) - response = json.dumps({"message": "invalid request", "status": "error"}) - - except ValueError: - logging.exception("Error processing message from %s: %s", addr, message) - response = json.dumps({"message": "invalid request", "status": "error"}) - - logging.debug("Sending response: %s", response) - writer.write(response.encode("utf8")) - await writer.drain() - - logging.debug("Closing the connection") - writer.close() - - # Tie off any async tasks - if task: - await task - - async def main_loop(self): - """Run the main async loop of the server on the configured port.""" - sock = socket.socket(socket.AF_VSOCK, socket.SOCK_STREAM) - sock.settimeout(5) - sock.bind((socket.VMADDR_CID_ANY, self.port)) - - server = await asyncio.start_server( - client_connected_cb=self._handle_connection, - sock=sock, - ) - - addr = server.sockets[0].getsockname() - logging.info(f"AsyncVsockListener listening on VMADDR_CID_ANY and port {addr[1]}") - - try: - async with server: - await server.serve_forever() - except KeyboardInterrupt: # pragma: no branch - pass - finally: - logging.info("Shutting down the server") - self.vsock_agent.terminate() diff --git a/ic-os/hostos/rootfs/opt/ic/bin/hsm-utils.sh b/ic-os/hostos/rootfs/opt/ic/bin/hsm-utils.sh deleted file mode 100755 index a71aca090c6..00000000000 --- a/ic-os/hostos/rootfs/opt/ic/bin/hsm-utils.sh +++ /dev/null @@ -1,119 +0,0 @@ -#!/bin/bash - -set -e - -# Utils for working with the HSM on HostOS - -SCRIPT="$(basename $0)[$$]" -METRICS_DIR="/run/node_exporter/collector_textfile" - -# Default arguments if undefined -CHECK=0 -FETCH=0 -SAVE=0 - -# Get keyword arguments -for argument in "${@}"; do - case ${argument} in - -c | --check) - CHECK=1 - ;; - -d=* | --dir=*) - CONFIG_DIR="${argument#*=}" - shift - ;; - -f | --fetch) - FETCH=1 - ;; - -h | --help) - echo 'Usage: -Fetch Management MAC Address - -Arguments: - -c, --check check if an HSM is present - -d=, --dir= specify the config partition directory (Default: /boot/config) - -f, --fetch fetch the fingerprint of the stored HSM public key - -h, --help show this help message and exit - -s, --save save the HSM public key as PEM file on the config partition -' - exit 1 - ;; - -s | --save) - SAVE=1 - ;; - *) - echo "Error: Argument is not supported." - exit 1 - ;; - esac -done - -# Set arguments if undefined -CONFIG_DIR="${CONFIG_DIR:=/boot/config}" - -write_log() { - local message=$1 - - if [ -t 1 ]; then - echo "${SCRIPT} ${message}" >/dev/stdout - fi - - logger -t ${SCRIPT} "${message}" -} - -write_metric() { - local name=$1 - local value=$2 - local help=$3 - local type=$4 - - echo -e "# HELP ${name} ${help}\n# TYPE ${type}\n${name} ${value}" >"${METRICS_DIR}/${name}.prom" -} - -# Check if the HSM is plugged in -function check_hsm() { - retry=0 - if [ "$(lsusb | grep -E 'Nitro|Clay')" ]; then - write_log "Nitrokey HSM USB device detected." - else - write_log "Nitrokey HSM USB device could not be detected." - exit 1 - fi -} - -# Fetch the HSM public key fingerprint -function fetch_hsm_fingerprint() { - if [ -r "${CONFIG_DIR}/hsm.pem" ]; then - PUBKEY=$(cat "${CONFIG_DIR}/hsm.pem" | sha256sum | cut -d " " -f 1) - echo "${PUBKEY}" - write_log "Using HSM public key fingerprint: ${PUBKEY}" - else - write_log "ERROR: Unable to read HSM public key file: ${CONFIG_DIR}/hsm.pem" - exit 1 - fi -} - -# Extract the HSM public key file and store it as PEM formatted file on the -# config partition -function save_hsm_key() { - TMPDIR=$(mktemp -d) - pkcs11-tool --read-object --type pubkey --id 01 --output-file "${TMPDIR}"/hsm.der >/dev/null 2>&1 - openssl ec -pubin -inform DER -outform PEM -in "${TMPDIR}"/hsm.der -out ${CONFIG_DIR}/hsm.pem >/dev/null 2>&1 - rm -rf "${TMPDIR}" - write_log "Saving HSM public key on config partition." -} - -function main() { - # Establish run order - if [ ${CHECK} -eq 1 ]; then - check_hsm - elif [ ${FETCH} -eq 1 ]; then - fetch_hsm_fingerprint - elif [ ${SAVE} -eq 1 ]; then - save_hsm_key - else - $0 --help - fi -} - -main diff --git a/ic-os/hostos/rootfs/opt/ic/bin/install-upgrade.sh b/ic-os/hostos/rootfs/opt/ic/bin/install-upgrade.sh deleted file mode 100755 index 2e4f84c07e5..00000000000 --- a/ic-os/hostos/rootfs/opt/ic/bin/install-upgrade.sh +++ /dev/null @@ -1,13 +0,0 @@ -#!/bin/bash - -# Install an update artifact and prepare to boot it next time. -# The update artifact is read from the file pointed to by the first argument. - -set -eo pipefail - -TMPDIR=$(mktemp -d) -trap "rm -rf ${TMPDIR}" exit - -tar -xf "$1" -C "${TMPDIR}" - -/opt/ic/bin/manageboot.sh install "${TMPDIR}"/boot.img "${TMPDIR}"/root.img diff --git a/ic-os/hostos/rootfs/opt/ic/bin/manageboot.sh b/ic-os/hostos/rootfs/opt/ic/bin/manageboot.sh deleted file mode 100755 index 5d9e51baac3..00000000000 --- a/ic-os/hostos/rootfs/opt/ic/bin/manageboot.sh +++ /dev/null @@ -1,217 +0,0 @@ -#!/bin/bash - -set -e - -# Reads properties "boot_alternative" and "boot_cycle" from the grubenv -# file. The properties are stored as global variables. -# -# Arguments: -# $1 - name of grubenv file -function read_grubenv() { - local GRUBENV_FILE="$1" - - while IFS="=" read -r key value; do - case "$key" in - '#'*) ;; - 'boot_alternative') ;& - 'boot_cycle') - eval "$key=\"$value\"" - ;; - *) ;; - - esac - done <"$GRUBENV_FILE" -} - -# Writes "boot_alternative" and "boot_cycle" global variables to grubenv file -# -# Arguments: -# $1 - name of grubenv file -function write_grubenv() { - local GRUBENV_FILE="$1" - - TMP_FILE=$(mktemp /tmp/grubenv-XXXXXXXXXXXX) - ( - echo "# GRUB Environment Block" - echo boot_alternative="$boot_alternative" - echo boot_cycle="$boot_cycle" - # Fill to make sure we will have 1024 bytes - echo -n "################################################################################################################################################################################################################################################################################################################################################################################################################################################################################################################################################################################################################################################################################################################################################################################################################################################################################################################################################################################################################################################################" - ) >"${TMP_FILE}" - # Truncate to arrive at precisely 1024 bytes - truncate --size=1024 "${TMP_FILE}" - cat "${TMP_FILE}" >"${GRUBENV_FILE}" - rm "${TMP_FILE}" -} - -# Convert A -> B and B -> A -function swap_alternative() { - if [ "$1" == B ]; then - echo A - else - echo B - fi -} - -function get_boot_partition() { - if [ "$1" == B ]; then - echo /dev/hostlvm/B_boot - else - echo /dev/hostlvm/A_boot - fi -} -function get_root_partition() { - if [ "$1" == B ]; then - echo /dev/hostlvm/B_root - else - echo /dev/hostlvm/A_root - fi -} -function get_var_partition() { - if [ "$1" == B ]; then - echo /dev/hostlvm/B_var - else - echo /dev/hostlvm/A_var - fi -} - -function usage() { - cat <2 - exit 1 - fi - BOOT_IMG="$1" - ROOT_IMG="$2" - - if [ "${BOOT_IMG}" == "" -o "${ROOT_IMG}" == "" ]; then - usage - exit 1 - fi - - # Write to target partitions, and "wipe" header of var partition - # (to ensure that new target starts from a pristine state). - - dd if="${BOOT_IMG}" of="${TARGET_BOOT}" bs=1M status=progress - dd if="${ROOT_IMG}" of="${TARGET_ROOT}" bs=1M status=progress - dd if=/dev/zero of="${TARGET_VAR}" bs=1M count=16 status=progress - - boot_alternative="${TARGET_ALTERNATIVE}" - boot_cycle=first_boot - write_grubenv "${GRUBENV_FILE}" - ;; - confirm) - if [ "$boot_cycle" != "stable" ]; then - boot_cycle=stable - write_grubenv "${GRUBENV_FILE}" - fi - ;; - current) - echo "${CURRENT_ALTERNATIVE}" - ;; - target) - echo "${TARGET_ALTERNATIVE}" - ;; - next) - echo "${NEXT_BOOT}" - ;; - current_partition) - echo "${CURRENT_ROOT}" - ;; - target_partition) - echo "${TARGET_ROOT}" - ;; - *) - usage - ;; -esac diff --git a/ic-os/hostos/rootfs/opt/ic/bin/monitor-guestos.sh b/ic-os/hostos/rootfs/opt/ic/bin/monitor-guestos.sh deleted file mode 100755 index 2393051e3cc..00000000000 --- a/ic-os/hostos/rootfs/opt/ic/bin/monitor-guestos.sh +++ /dev/null @@ -1,77 +0,0 @@ -#!/bin/bash - -set -e - -# Monitor the GuestOS virtual machine. - -SCRIPT="$(basename $0)[$$]" -METRICS_DIR="/run/node_exporter/collector_textfile" - -# Get keyword arguments -for argument in "${@}"; do - case ${argument} in - -h | --help) - echo 'Usage: -Monitor GuestOS Virtual Machine - -Arguments: - -h, --help show this help message and exit -' - exit 1 - ;; - *) - echo "Error: Argument is not supported." - exit 1 - ;; - esac -done - -write_log() { - local message=$1 - - if [ -t 1 ]; then - echo "${SCRIPT} ${message}" >/dev/stdout - fi - - logger -t ${SCRIPT} "${message}" -} - -write_metric() { - local name=$1 - local value=$2 - local help=$3 - local type=$4 - - echo -e "# HELP ${name} ${help}\n# TYPE ${type}\n${name} ${value}" >"${METRICS_DIR}/${name}.prom" -} - -function monitor_guestos() { - if [ ! "$(virsh list --all | grep 'guestos')" ]; then - write_log "ERROR: GuestOS virtual machine is not defined." - write_metric "hostos_guestos_state" \ - "1" \ - "GuestOS virtual machine state" \ - "gauge" - exit 1 - fi - - if [ "$(virsh list --state-running | grep 'guestos')" ]; then - write_metric "hostos_guestos_state" \ - "0" \ - "GuestOS virtual machine state" \ - "gauge" - else - write_log "GuestOS virtual machine is not running." - write_metric "hostos_guestos_state" \ - "2" \ - "GuestOS virtual machine state" \ - "gauge" - fi -} - -function main() { - # Establish run order - monitor_guestos -} - -main diff --git a/ic-os/hostos/rootfs/opt/ic/bin/relabel-machine-id.sh b/ic-os/hostos/rootfs/opt/ic/bin/relabel-machine-id.sh deleted file mode 100755 index 7adda9e3e1c..00000000000 --- a/ic-os/hostos/rootfs/opt/ic/bin/relabel-machine-id.sh +++ /dev/null @@ -1,7 +0,0 @@ -#!/bin/bash - -# On anything but first boot, machine-id is set up in initramfs and bind-mounted -# over to the rootfs. Since policy is not loaded in initramfs yet, it has -# wrong security context. Fix this up, but ignore failures (this will not -# work on first boot). -restorecon -v /etc/machine-id || true diff --git a/ic-os/hostos/rootfs/opt/ic/bin/save-machine-id.sh b/ic-os/hostos/rootfs/opt/ic/bin/save-machine-id.sh deleted file mode 100755 index 878b9b57f2b..00000000000 --- a/ic-os/hostos/rootfs/opt/ic/bin/save-machine-id.sh +++ /dev/null @@ -1,5 +0,0 @@ -#!/bin/bash - -if [ ! -e /boot/config/machine-id ]; then - cp /etc/machine-id /boot/config/machine-id -fi diff --git a/ic-os/hostos/rootfs/opt/ic/bin/setup-hostname.sh b/ic-os/hostos/rootfs/opt/ic/bin/setup-hostname.sh deleted file mode 100755 index b3c6108f023..00000000000 --- a/ic-os/hostos/rootfs/opt/ic/bin/setup-hostname.sh +++ /dev/null @@ -1,119 +0,0 @@ -#!/bin/bash - -set -e - -# Set the transient or persistent hostname. - -SCRIPT="$(basename $0)[$$]" -METRICS_DIR="/run/node_exporter/collector_textfile" - -# Get keyword arguments -for argument in "${@}"; do - case ${argument} in - -c=* | --config=*) - CONFIG="${argument#*=}" - shift - ;; - -f=* | --file=*) - FILE="${argument#*=}" - shift - ;; - -h | --help) - echo 'Usage: -Set Transient Or Persistent Hostname - -Arguments: - -c=, --config= optional: specify the config.json configuration file (Default: /boot/config/config.json) - -f=, --file= optional: specify the file containing the node-id (Default: /boot/config/node-id) - -h, --help show this help message and exit - -t=, --type= mandatory: specify the node type (Examples: host, guest, boundary...) -' - exit 1 - ;; - -t=* | --type=*) - TYPE="${argument#*=}" - shift - ;; - *) - echo "Error: Argument is not supported." - exit 1 - ;; - esac -done - -# Set arguments if undefined -CONFIG="${CONFIG:=/boot/config/config.json}" -FILE="${FILE:=/boot/config/node-id}" - -function validate_arguments() { - if [ "${CONFIG}" == "" -o "${FILE}" == "" -o "${TYPE}" == "" ]; then - $0 --help - fi -} - -write_log() { - local message=$1 - - if [ -t 1 ]; then - echo "${SCRIPT} ${message}" >/dev/stdout - fi - - logger -t ${SCRIPT} "${message}" -} - -write_metric() { - local name=$1 - local value=$2 - local help=$3 - local type=$4 - - echo -e "# HELP ${name} ${help}\n# TYPE ${type}\n${name} ${value}" >"${METRICS_DIR}/${name}.prom" -} - -function construct_hostname() { - # TODO: This field is not mandatory, so we need to be able to optionally grab it - overrides=$(jq -r ".overrides" ${CONFIG}) - if [ "${overrides}" != "null" ]; then - HOSTNAME=$(/opt/ic/bin/fetch-property.sh --key=.overrides.hostname --metric=overrides_hostname --config=${CONFIG}) - else - local mac=$(/opt/ic/bin/fetch-mgmt-mac.sh | sed 's/://g') - - if [[ -r ${FILE} && $(cat ${FILE}) != "" ]]; then - HOSTNAME=$(echo ${TYPE}-${mac}-$(cat ${FILE})) - write_log "Using hostname: ${HOSTNAME}" - write_metric "hostos_setup_hostname" \ - "1" \ - "HostOS setup hostname" \ - "gauge" - else - HOSTNAME=$(echo ${TYPE}-${mac}) - write_log "Using hostname: ${HOSTNAME}" - write_metric "hostos_setup_hostname" \ - "0" \ - "HostOS setup hostname" \ - "gauge" - fi - fi -} - -function setup_hostname() { - if [ "$(mount | grep '/etc/hostname')" ]; then - umount /etc/hostname - fi - - if [ -d /run/ic-node/etc ]; then - echo "${HOSTNAME}" >/run/ic-node/etc/hostname - mount --bind /run/ic-node/etc/hostname /etc/hostname - restorecon -v /etc/hostname - hostname "${HOSTNAME}" - fi -} - -function main() { - # Establish run order - validate_arguments - construct_hostname - setup_hostname -} - -main diff --git a/ic-os/hostos/rootfs/opt/ic/bin/setup-libvirt.sh b/ic-os/hostos/rootfs/opt/ic/bin/setup-libvirt.sh deleted file mode 100755 index 5525702d98a..00000000000 --- a/ic-os/hostos/rootfs/opt/ic/bin/setup-libvirt.sh +++ /dev/null @@ -1,7 +0,0 @@ -#!/bin/bash - -set -e - -# Create space for libvirt to manage its config - -mount --bind /run/libvirt /etc/libvirt diff --git a/ic-os/hostos/rootfs/opt/ic/bin/setup-node_exporter-keys.sh b/ic-os/hostos/rootfs/opt/ic/bin/setup-node_exporter-keys.sh deleted file mode 100755 index 548e08f8f39..00000000000 --- a/ic-os/hostos/rootfs/opt/ic/bin/setup-node_exporter-keys.sh +++ /dev/null @@ -1,24 +0,0 @@ -#!/bin/bash - -# If no node_exporter TLS private key exist, copy from "config" partition over -# to our system. Create TLS key pair in "config" partition as needed. - -set -e - -if [ ! -e "/boot/config/node_exporter" ]; then - TMPDIR="$(mktemp -d)" - mkdir -p "${TMPDIR}" - openssl req -new -newkey rsa:2048 -days 3650 -nodes -x509 -keyout "${TMPDIR}/node_exporter.key" -out "${TMPDIR}/node_exporter.crt" -subj '/C=CH/ST=Zurich/L=Zurich/O=DFINITY Stiftung/OU=PfOps/CN=localhost' -addext 'subjectAltName = DNS:localhost' - mkdir -p /boot/config/node_exporter - cp --archive ${TMPDIR}/node_exporter\.* /boot/config/node_exporter/ - rm -rf ${TMPDIR} -fi - -cp -ar /etc/node_exporter/* /run/ic-node/etc/node_exporter/ -cp /boot/config/node_exporter/node_exporter\.* /run/ic-node/etc/node_exporter -chown root:root /run/ic-node/etc/node_exporter/node_exporter.crt -chmod 0644 /run/ic-node/etc/node_exporter/node_exporter.crt -chown root:node_exporter /run/ic-node/etc/node_exporter/node_exporter.key -chmod 0640 /run/ic-node/etc/node_exporter/node_exporter.key -mount --bind /run/ic-node/etc/node_exporter /etc/node_exporter -restorecon -v -r /etc/node_exporter diff --git a/ic-os/hostos/rootfs/opt/ic/bin/setup-ssh-account-keys.sh b/ic-os/hostos/rootfs/opt/ic/bin/setup-ssh-account-keys.sh deleted file mode 100755 index ff3df3507ad..00000000000 --- a/ic-os/hostos/rootfs/opt/ic/bin/setup-ssh-account-keys.sh +++ /dev/null @@ -1,22 +0,0 @@ -#!/bin/bash - -set -e - -# Set up ssh keys for the role accounts: This is required to allow -# key-based login to these accounts - -# TBD: should only allow root ssh key for test builds - -mount --bind /run/ic-node/root/.ssh /root/.ssh - -for ACCOUNT in root backup readonly admin; do - ORIGIN="/boot/config/hostos_accounts_ssh_authorized_keys/${ACCOUNT}" - if [ -e "${ORIGIN}" ]; then - HOMEDIR=$(getent passwd "${ACCOUNT}" | cut -d: -f6) - GROUP=$(id -ng "${ACCOUNT}") - mkdir -p "${HOMEDIR}/.ssh" - cp "${ORIGIN}" "${HOMEDIR}/.ssh/authorized_keys" - chown -R "${ACCOUNT}:${GROUP}" "${HOMEDIR}/.ssh" - restorecon -vr "${HOMEDIR}/.ssh" - fi -done diff --git a/ic-os/hostos/rootfs/opt/ic/bin/setup-ssh-keys.sh b/ic-os/hostos/rootfs/opt/ic/bin/setup-ssh-keys.sh deleted file mode 100755 index 27b6ac4bdcc..00000000000 --- a/ic-os/hostos/rootfs/opt/ic/bin/setup-ssh-keys.sh +++ /dev/null @@ -1,21 +0,0 @@ -#!/bin/bash - -# If no ssh keys exist, copy them from "config" partition over to our -# system. Create them in "config" partition as needed. - -set -e - -if [ ! -e /boot/config/ssh ]; then - TMPDIR=$(mktemp -d) - mkdir -p "${TMPDIR}"/etc/ssh - ssh-keygen -A -f "${TMPDIR}" - mkdir /boot/config/ssh - cp "${TMPDIR}"/etc/ssh/ssh_host* /boot/config/ssh - rm -rf "${TMPDIR}" -fi - -cp -ar /etc/ssh/* /run/ic-node/etc/ssh/ -cp /boot/config/ssh/* /run/ic-node/etc/ssh/ -mount --bind /run/ic-node/etc/ssh /etc/ssh -# Fix security labels -restorecon -v -r /etc/ssh diff --git a/ic-os/hostos/rootfs/opt/ic/bin/setup-var.sh b/ic-os/hostos/rootfs/opt/ic/bin/setup-var.sh deleted file mode 100755 index b5431318797..00000000000 --- a/ic-os/hostos/rootfs/opt/ic/bin/setup-var.sh +++ /dev/null @@ -1,22 +0,0 @@ -#!/bin/bash - -VAR_PARTITION="$1" - -echo "Seting up ${VAR_PARTITION} for use as /var." - -# Check whether there is already a luks header in the partition. -TYPE=$(blkid -o value --match-tag TYPE "${VAR_PARTITION}") - -# Defer this because blkid can output "" with a state of 2 if nothing is found -# at all (completely empty partition) -set -e - -# cf. the upgrade logic in "manageboot.sh": The target partition is wiped -# clean as part of the upgrade procedure. We can therefore really rely -# on having a clean slate here after first boot of an upgrade. -if [ "${TYPE}" == "ext4" ]; then - echo "Found ext4 header in partition ${VAR_PARTITION} for /var." -else - echo "No ext4 header found in partition ${VAR_PARTITION} for /var. Setting it up on first boot." - mkfs.ext4 -F ${VAR_PARTITION} -d /var -fi diff --git a/ic-os/hostos/rootfs/opt/ic/bin/start-guestos.sh b/ic-os/hostos/rootfs/opt/ic/bin/start-guestos.sh deleted file mode 100755 index a275598f986..00000000000 --- a/ic-os/hostos/rootfs/opt/ic/bin/start-guestos.sh +++ /dev/null @@ -1,110 +0,0 @@ -#!/bin/bash - -set -e - -# Start the GuestOS virtual machine. - -SCRIPT="$(basename $0)[$$]" -METRICS_DIR="/run/node_exporter/collector_textfile" - -# Get keyword arguments -for argument in "${@}"; do - case ${argument} in - -h | --help) - echo 'Usage: -Start GuestOS virtual machine - -Arguments: - -c=, --config= specify the GuestOS configuration file (Default: /var/lib/libvirt/guestos.xml) - -h, --help show this help message and exit -' - exit 1 - ;; - *) - echo "Error: Argument is not supported." - exit 1 - ;; - esac -done - -# Set arguments if undefined -CONFIG="${CONFIG:=/var/lib/libvirt/guestos.xml}" - -write_log() { - local message=$1 - - if [ -t 1 ]; then - echo "${SCRIPT} ${message}" >/dev/stdout - fi - - logger -t ${SCRIPT} "${message}" -} - -write_metric() { - local name=$1 - local value=$2 - local help=$3 - local type=$4 - - echo -e "# HELP ${name} ${help}\n# TYPE ${type}\n${name} ${value}" >"${METRICS_DIR}/${name}.prom" -} - -function define_guestos() { - if [ "$(virsh list --all | grep 'guestos')" ]; then - write_log "GuestOS virtual machine is already defined." - write_metric "hostos_guestos_service_define" \ - "0" \ - "GuestOS virtual machine define state" \ - "gauge" - else - virsh define ${CONFIG} - write_log "Defining GuestOS virtual machine." - write_metric "hostos_guestos_service_define" \ - "1" \ - "GuestOS virtual machine define state" \ - "gauge" - fi -} - -function start_guestos() { - if [ "$(virsh list --state-running | grep 'guestos')" ]; then - write_log "GuestOS virtual machine is already running." - write_metric "hostos_guestos_service_start" \ - "0" \ - "GuestOS virtual machine start state" \ - "gauge" - else - virsh start guestos - write_log "Starting GuestOS virtual machine." - write_metric "hostos_guestos_service_start" \ - "1" \ - "GuestOS virtual machine start state" \ - "gauge" - fi -} - -function enable_guestos() { - if [ "$(virsh list --autostart | grep 'guestos')" ]; then - write_log "GuestOS virtual machine is already enabled." - write_metric "hostos_guestos_service_enable" \ - "0" \ - "GuestOS virtual machine enable state" \ - "gauge" - else - virsh autostart guestos - write_log "Enabling GuestOS virtual machine." - write_metric "hostos_guestos_service_enable" \ - "1" \ - "GuestOS virtual machine enable state" \ - "gauge" - fi -} - -function main() { - # Establish run order - define_guestos - start_guestos - enable_guestos -} - -main diff --git a/ic-os/hostos/rootfs/opt/ic/bin/stop-guestos.sh b/ic-os/hostos/rootfs/opt/ic/bin/stop-guestos.sh deleted file mode 100755 index bd468668951..00000000000 --- a/ic-os/hostos/rootfs/opt/ic/bin/stop-guestos.sh +++ /dev/null @@ -1,88 +0,0 @@ -#!/bin/bash - -set -e - -# Stop the GuestOS virtual machine. - -SCRIPT="$(basename $0)[$$]" -METRICS_DIR="/run/node_exporter/collector_textfile" - -# Get keyword arguments -for argument in "${@}"; do - case ${argument} in - -h | --help) - echo 'Usage: -Stop GuestOS virtual machine - -Arguments: - -h, --help show this help message and exit -' - exit 1 - ;; - *) - echo "Error: Argument is not supported." - exit 1 - ;; - esac -done - -write_log() { - local message=$1 - - if [ -t 1 ]; then - echo "${SCRIPT} ${message}" >/dev/stdout - fi - - logger -t ${SCRIPT} "${message}" -} - -write_metric() { - local name=$1 - local value=$2 - local help=$3 - local type=$4 - - echo -e "# HELP ${name} ${help}\n# TYPE ${type}\n${name} ${value}" >"${METRICS_DIR}/${name}.prom" -} - -function stop_guestos() { - if [ "$(virsh list --state-shutoff | grep 'guestos')" ]; then - write_log "GuestOS virtual machine is already stopped." - write_metric "hostos_guestos_service_stop" \ - "0" \ - "GuestOS virtual machine stop state" \ - "gauge" - else - virsh destroy --graceful guestos - write_log "Stopping GuestOS virtual machine." - write_metric "hostos_guestos_service_stop" \ - "1" \ - "GuestOS virtual machine stop state" \ - "gauge" - fi -} - -function disable_guestos() { - if [ "$(virsh list --autostart | grep 'guestos')" ]; then - virsh autostart --disable guestos - write_log "Disabling GuestOS virtual machine." - write_metric "hostos_guestos_service_disable" \ - "1" \ - "GuestOS virtual machine disable state" \ - "gauge" - else - write_log "GuestOS virtual machine is already disabled." - write_metric "hostos_guestos_service_disable" \ - "0" \ - "GuestOS virtual machine disable state" \ - "gauge" - fi -} - -function main() { - # Establish run order - stop_guestos - disable_guestos -} - -main diff --git a/ic-os/hostos/rootfs/opt/ic/share/.gitignore b/ic-os/hostos/rootfs/opt/ic/share/.gitignore deleted file mode 100644 index 7f4dc648dc5..00000000000 --- a/ic-os/hostos/rootfs/opt/ic/share/.gitignore +++ /dev/null @@ -1 +0,0 @@ -version.txt diff --git a/ic-os/hostos/rootfs/opt/ic/share/guestos.xml.template b/ic-os/hostos/rootfs/opt/ic/share/guestos.xml.template deleted file mode 100755 index 353b8849c51..00000000000 --- a/ic-os/hostos/rootfs/opt/ic/share/guestos.xml.template +++ /dev/null @@ -1,182 +0,0 @@ - - guestos - fd897da5-8017-41c8-8575-a706dba30766 - - - - - - {{ resources_memory }} - {{ resources_memory }} - 64 - - - - - - - /machine - - - hvm - /usr/share/OVMF/OVMF_CODE.fd - /var/lib/libvirt/qemu/nvram/guestos_VARS.fd - - - - - - - - - - - - restart - restart - restart - - - - - - /usr/local/bin/qemu-system-x86_64 - - - - - - -
- - - - - - - -
- - - - -
- - - - -
- - - - -
- - - -
- - - - - - -
- - - - - -
- - - - - -
- - - - - -
- - - - - -
- - - - - -
- - - - - -
- - - - - -
- - - - - - - -
- - - - - - - - - - - - - - - - - - - - - - -
- - - - - - - - - - - - -
- - - /dev/urandom - -
- - - - - +64055:+108 - - diff --git a/ic-os/hostos/rootfs/packages.common b/ic-os/hostos/rootfs/packages.common deleted file mode 100644 index 1bfc288477a..00000000000 --- a/ic-os/hostos/rootfs/packages.common +++ /dev/null @@ -1,64 +0,0 @@ -# This defines all Ubuntu packages to be installed on the target image. The -# packages here are intended to be the bare minimum required for replica -# operation for the "prod" image. Please put debugging / dev -# utilities into packages.dev, these will then be available on the dev -# image only. - -# Need kernel to boot anything -linux-image-generic-hwe-20.04 -initramfs-tools - -# Need systemd for boot process -systemd -systemd-sysv -systemd-journal-remote - -# Third-party services we will be running -chrony -openssh-server - -# Smartcard support -pcsc-tools -pcscd -opensc - -# Required system setup tools -attr -ca-certificates -curl -faketime -fdisk -iproute2 -isc-dhcp-client -jq -less -lvm2 -net-tools -nftables -parted -rsync -sudo -udev -usbutils - -# SELinux support -selinux-policy-default -selinux-utils -semodule-utils -policycoreutils -# this is required for policy building -- presently policy modules are built -# inside the target which is not fully proper. When the build is moved out, -# this package can be removed -selinux-policy-dev -checkpolicy - -# HostOS additions -dosfstools -ethtool -ipmitool -locales -libvirt-daemon-system libvirt-dev -mtools -ovmf -python3-requests -python3-libvirt diff --git a/ic-os/hostos/rootfs/packages.dev b/ic-os/hostos/rootfs/packages.dev deleted file mode 100644 index cc6ac44e977..00000000000 --- a/ic-os/hostos/rootfs/packages.dev +++ /dev/null @@ -1,21 +0,0 @@ -# These are additional Ubuntu packages installed on the "dev" images. - -# editor for convenience -vim - -# packages requested by networking -tcpdump -iperf -netcat -curl -iputils-ping - -# may want to ssh into other hosts -- not sure if this is really advisable -openssh-client - -# useful for first-order debugging -strace - -# useful for SELinux development -setools - diff --git a/ic-os/hostos/tests/Readme.md b/ic-os/hostos/tests/Readme.md deleted file mode 100644 index 6e79c3a9824..00000000000 --- a/ic-os/hostos/tests/Readme.md +++ /dev/null @@ -1,171 +0,0 @@ -XXX TODO - -Adding new CI tests ----------- - -In order to add a new guest OS CI tests, do the following. - - 1. Create a copy of an existing test, pick the one closes to your need: - - `e2e_upgrade.py` boots a guest OS instance and upgrades it - - `e2e_workload.py` boots a guest OS intance and runs the workload generator against it - - 2. Register your test to gitlab CI. Add a new section to - `gitlab-ci/config/47--guest-os-test--guest-os-e2e-test.yml`. Don't be shy to - simply copy paste for now, we will clean up later. Be sure to rename the test to create - a distinct pipeline step on CI (e.g. copy section `e2e-workload-test` and rename - to `e2e-foobar-test`) - - 3. Create a PR and ensure that your new test is running. It should be listed under Downstream > - child pipeline. - - -Interactive testing ----------- - -You can also run your test manually. For that, you need to have a machine with qemu and kvm -set up. One such machine is `zh1-spm34.zh1.dfinity.network`. Be sure to ask Saša to put you in -the `kvm` group. It should look something like that. - - $ id - uid=1031(skaestle) gid=1033(skaestle) groups=1033(skaestle),..,108(kvm),998(docker),1002(libvirt),30001(nix-users) - - -In order for the tests to run, you need to have a bunch of artifacts available. You can -download the latest ones from our S3 store. First, configure it: - - $ cat ~/.rclone.conf - [public-s3] - type = s3 - provider = AWS - env_auth = false - # Credentials should be set with environment variables: - # export AWS_ACCESS_KEY_ID=xxx - # export AWS_SECRET_ACCESS_KEY=yyyy - region = eu-central-1 - location_constraint = eu-central-1 - -Then run to get build artifacts from master. - - GIT=$(git rev-parse --verify origin/master) - -Or, if you want to run it on your branch, make sure to create a PR (so artifacts get built by CI) and do and then download artifacts. - - ic-os/guestos/scripts/get-artifacts.sh - -You should now have all artifacts from master in folders `/artifacts/{canisters,release,guest-os,guest-os-master}`. - -If you execute this on `zh1-spm22.zh1.dfinity.network` or `zh1-spm34.zh1.dfinity.network`, you are good to go. Otherwise, read under "Setting up the host machine" . - -You can then execute the tests like this: - - mkdir -p artifacts/e2e-upgrade-logs - ic-os/guestos/tests/e2e-upgrade.py \ - --vmtoolscfg=internal \ - --disk_image "artifacts/guest-os/disk-img/disk.img" \ - --ic_prep_bin "artifacts/release/ic-prep" \ - --install_nns_bin "artifacts/release/ic-nns-init" \ - --upgrade_tar "artifacts/guest-os/update-img/update-img.tar.gz" \ - --ic_admin_bin "artifacts/release/ic-admin" \ - --nns_canisters "artifacts/canisters/" \ - --log_directory "artifacts/e2e-upgrade-logs" \ - --timeout "60" \ - --ic_workload_generator_bin "artifacts/release/ic-workload-generator" \ - --is_upgrade_test - - -Interactive testing (experimental set up, Ubuntu host) ----------- - -Set up qemu to allow connecting VMs to these bridges by putting the following -into /etc/qemu/bridge.conf: - - allow ipv6_ic - -and setting up qemu helper (as root): - - chmod u+s /usr/lib/qemu/qemu-bridge-helper - -Lastly, put the provided vmtoolscfg-sample.json into /etc by the name of -/etc/vmtoolscfg.json. Afterwards, you can run tests with all network -set up taken care of: - - tests/e2e-upgrade.py \ - --disk_image guest-os/disk.img \ - --ic_prep_bin artifacts/ic-prep \ - --install_nns_bin "artifacts/ic-nns-init" \ - --upgrade_script "scripts/ci-upgrade.sh" \ - --upgrade_tar "$(pwd)/guest-os/update-img/update-img.tar.gz" \ - --ic_admin_bin "artifacts/ic-admin" \ - --nns_canisters "artifacts" \ - --version $(cat guest-os/version.txt) - -Running on a new host ----------- - -If running on machine that hasn't been setup already you need to be `sudo`. -You need to run the following script before you want to run guest OS in qemu for the first time. - - #!/usr/bin/env bash - if [ "$1" == up ]; then - USER=$(id -nu) - sudo ip tuntap add ipv6_ic_node0 mode tap user "$USER" - sudo ip link set dev ipv6_ic_node0 up - sudo ip tuntap add ipv6_ic_node1 mode tap user "$USER" - sudo ip link set dev ipv6_ic_node1 up - sudo ip link add name ipv6_ic type bridge - sudo ip link set ipv6_ic_node0 master ipv6_ic - sudo ip link set ipv6_ic_node1 master ipv6_ic - sudo ip link set dev ipv6_ic up - sudo ip addr add fd00:2:1:1:1::1/64 dev ipv6_ic - fi - if [ "$1" == down ]; then - sudo ip link del ipv6_ic_node0 - sudo ip link del ipv6_ic_node1 - sudo ip link del ipv6_ic - fi - -Call it like this: - - sudo script.sh down - sudo script.sh up - - -Running master to branch upgrade tests ----------- - -If you want to test upgrades between master an your branch, you first -need to get artifacts from master, similarly to before: - - # Find merge base to upgrade from - GIT_REV=$(git merge-base HEAD origin/master) - - # Download artifacts from master - ../../gitlab-ci/src/artifacts/rclone_download.py --git-rev $GIT_REV --out=guest-os-master --remote-path guest-os --latest-to - ../../gitlab-ci/src/artifacts/rclone_download.py --git-rev $GIT_REV --out=artifacts-master --remote-path canisters --latest-to - ../../gitlab-ci/src/artifacts/rclone_download.py --git-rev $GIT_REV --out=artifacts-master --remote-path release --latest-to - -Extract the content of those directories as described above. - -Then, in the e2e test change the arguments accordingly. - - tests/e2e-upgrade.py --disk_image guest-os-master/disk.img ... - -Note that you should also use tools such as `ic-admin` from master. - - -How to build your own guest OS image ----------- - - 1. Put your replica and your orchestrator in `rootfs/opt/ic/bin` - 2. Copy `vsock_agent` from `artifacts` to `rootfs/opt/ic/bin` - 2. Build a new disk image: `scripts/build-disk-image.sh -o /tmp/disk.img` - - -Known issues ----------- - -If you get: - - subprocess.CalledProcessError: Command '['cp', '--sparse=always', 'guest-os/disk.img', '/tmp/disk-node0.img']' returned non-zero exit status 1. - -Make sure `/tmp/disk-node*.img` doesn't already exist from a different user. If so, remove them first. diff --git a/ic-os/hostos/tests/hostos-upgrade.py b/ic-os/hostos/tests/hostos-upgrade.py deleted file mode 100755 index f0c044a5818..00000000000 --- a/ic-os/hostos/tests/hostos-upgrade.py +++ /dev/null @@ -1,72 +0,0 @@ -#!/usr/bin/env python3 -import sys - -import gflags -import ictools -import vmtools - -FLAGS = gflags.FLAGS - -gflags.DEFINE_string("upgrade_tar", None, "Path to upgrade tar file") -gflags.MarkFlagAsRequired("upgrade_tar") -gflags.DEFINE_string("disk_image", None, "Path to disk image to use for VMs") -gflags.MarkFlagAsRequired("disk_image") - - -def upgrade(ic_url): - filename = "/tmp/update-img.tar.gz" - - ictools.send_upgrade_ssh(ic_url, FLAGS.upgrade_tar, filename) - ictools.apply_upgrade_ssh(ic_url, filename) - - return ictools.get_upgrade_image_version(FLAGS.upgrade_tar) - - -def main(argv): - argv = FLAGS(argv) - - machines = vmtools.pool().request_machines( - [ - {"name": "node0", "ram": "6G", "disk": "101G", "cores": 1}, - {"name": "node1", "ram": "6G", "disk": "101G", "cores": 1}, - ], - ) - - system_image = vmtools.SystemImage.open_local(FLAGS.disk_image) - - ssh = ictools.prep_ssh() - - # NOTE: Instead of config image, copy the files directly onto the partition. - # This is temporary until we run the install through setupos. - machine_configs = [ - ictools.build_config_folder(machines[0].get_name(), machines[0].get_ips(6)[0], ssh), - ictools.build_config_folder(machines[1].get_name(), machines[1].get_ips(6)[0], ssh), - ] - - vmtools.start_machines( - [(machine, system_image, config) for machine, config in zip(machines, machine_configs)], - start_ssh_log_streaming=True, - ) - - ictools.wait_ssh_up(machines[0].get_ipv6()) - ictools.wait_ssh_up(machines[1].get_ipv6()) - - # Check version on each machine - for m in machines: - version = ictools.get_host_version(m.get_ipv6()) - print("%-30s %s" % (m.get_ipv6(), version)) - - upgrade(machines[0].get_ipv6()) - version = upgrade(machines[1].get_ipv6()) - - # Check version on each machine - print("Checking versions on all hosts") - for m in machines: - ictools.wait_host_version(m.get_ipv6(), version, 120) - - machines[0].stop() - machines[1].stop() - - -if __name__ == "__main__": - main(sys.argv) diff --git a/ic-os/hostos/tests/hostos-upgrade.sh b/ic-os/hostos/tests/hostos-upgrade.sh deleted file mode 100755 index abe48f70647..00000000000 --- a/ic-os/hostos/tests/hostos-upgrade.sh +++ /dev/null @@ -1,78 +0,0 @@ -#!/usr/bin/env bash -# -# Runs a Host OS upgrade from base version to new version -# -: <<'DOC' -tag::catalog[] - -Title:: HostOS upgrade test - -Parameters:: -. ci_project_dir - the directory of the IC repository being checked out at. - -Success:: -. Testnet upgraded successfully and performs healthy after the upgrade. - -end::catalog[] -DOC - -set -e - -if (($# < 1)); then - echo >&2 "Usage: hostos-upgrade.sh \n - Example #1: hostos-upgrade.sh \"/builds/git/JgGsR4vA/4/dfinity-lab/public/ic\" - Example #2: hostos-upgrade.sh \"/builds/git/JgGsR4vA/4/dfinity-lab/public/ic\" " - exit 1 -fi - -ci_project_dir="$1" - -# Make sure the host has mounted necessary devices into the docker container. -# And check dependencies. -ls -lah /dev/kvm /dev/net/tun - -mkdir -p gitlab-runner-tmp -cd gitlab-runner-tmp - -ls "${ci_project_dir}/ic-os/hostos/build-out/disk-img/host-disk-img.tar.gz" -ls "${ci_project_dir}/ic-os/hostos/build-out/update-img/host-update-img.tar.gz" -stat "${ci_project_dir}/ic-os/hostos/build-out/disk-img/host-disk-img.tar.gz" -tar --sparse -xvf "${ci_project_dir}/ic-os/hostos/build-out/disk-img/host-disk-img.tar.gz" - -ls -lah - -# Prepare network. There are more convenient ways to do it if requisite -# services are set up (which they aren't in a simple docker runner), -# but probably also helpful for debugging to have this "explicit" for now. - -sudo ip link del ipv6_ic_node0 || true -sudo ip link del ipv6_ic_node1 || true -sudo ip link del ipv6_ic || true - -sudo ip tuntap add ipv6_ic_node0 mode tap user ubuntu -sudo ip link set dev ipv6_ic_node0 up - -sudo ip tuntap add ipv6_ic_node1 mode tap user ubuntu -sudo ip link set dev ipv6_ic_node1 up - -sudo ip link add name ipv6_ic type bridge -sudo ip link set ipv6_ic_node0 master ipv6_ic -sudo ip link set ipv6_ic_node1 master ipv6_ic -sudo ip link set dev ipv6_ic up - -sudo ip addr add fd00:2:1:1:1::1/64 dev ipv6_ic - -HOSTOS_IMG="$(pwd)/disk.img" -UPGRADE_IMG="${ci_project_dir}/ic-os/hostos/build-out/update-img/host-update-img.tar.gz" -echo "Initial HostOS image: ${HOSTOS_IMG}" -echo "Upgrade HostOS image: ${UPGRADE_IMG}" - -mkdir -p "${ci_project_dir}/ic-os/hostos/test-out/$out_dir" - -# Actual test script, sets up VMs and drives the test. -"${ci_project_dir}/ic-os/hostos/tests/hostos-upgrade.py" \ - --vmtoolscfg=internal \ - --disk_image "${HOSTOS_IMG}" \ - --upgrade_tar "${UPGRADE_IMG}" \ - --log_directory "${ci_project_dir}/ic-os/hostos/test-out/$out_dir" \ - --timeout "$E2E_TEST_TIMEOUT" diff --git a/ic-os/hostos/tests/ictools.py b/ic-os/hostos/tests/ictools.py deleted file mode 100644 index b0a2a79b5d9..00000000000 --- a/ic-os/hostos/tests/ictools.py +++ /dev/null @@ -1,392 +0,0 @@ -#!/usr/bin/env python3 -import atexit -import json -import os -import shutil -import subprocess -import sys -import tempfile -import time - -import cbor -import gflags -import requests -import vmtools - -FLAGS = gflags.FLAGS - -gflags.DEFINE_integer("timeout", 240, "Timeout in seconds to wait for IC to come up") - - -class ICConfig(object): - """Store configuration for an instance of the Internet Computer.""" - - def __init__(self, workdir, nns_ips, node_subnet_index, root_subnet): - """Initialize an IC with the given settings.""" - self.workdir = workdir - self.nns_ips = list(nns_ips) - self.node_subnet_index = node_subnet_index - self.root_subnet = root_subnet - - -def send_upgrade_ssh(host, image, filename): - command_line = [ - "scp", - "-o", - "StrictHostKeyChecking=no", - "-o", - "UserKnownHostsFile=/dev/null", - "-o", - "PasswordAuthentication=false", - image, - "root@[%s]:%s" % (host, filename), - ] - subprocess.run(command_line, check=True) - - -def apply_upgrade_ssh(host, image): - command_line = [ - "ssh", - "-o", - "ConnectTimeout=1", - "-o", - "StrictHostKeyChecking=no", - "-o", - "UserKnownHostsFile=/dev/null", - "-o", - "ServerAliveCountMax=3", - "-o", - "ServerAliveInterval=1", - "-o", - "PasswordAuthentication=false", - "-tt", - "root@%s" % host, - "/opt/ic/bin/install-upgrade.sh", - image, - "&&", - "reboot", - ] - subprocess.run(command_line, check=True) - - -def prep_ssh(): - config = build_ssh_extra_config()["accounts_ssh_authorized_keys"] - - ssh_keys_dir = tempfile.mkdtemp() - atexit.register(lambda: shutil.rmtree(ssh_keys_dir)) - for account, keyfile in config.items(): - with open(keyfile) as f: - keys = f.read() - with open(os.path.join(ssh_keys_dir, account), "w") as f: - f.write(keys) - return ssh_keys_dir - - -def build_config_folder(name, ip, ssh_keys): - output = tempfile.mkdtemp() - atexit.register(lambda: shutil.rmtree(output)) - - ip_address = "%s/%d" % (ip["address"], ip["mask_length"]) - ip_gateway = ip["gateway"] - config = {"overrides": {"ipv6_address": ip_address, "ipv6_gateway": ip_gateway, "hostname": name}} - config_json = json.dumps(config) - with open(os.path.join(output, "config.json"), "w") as f: - f.write(config_json) - subprocess.run(["cp", "-r", ssh_keys, "%s/hostos_accounts_ssh_authorized_keys" % output], check=True) - return output - - -def build_bootstrap_config_image(name, **kwargs): - config_image_dir = tempfile.mkdtemp() - atexit.register(lambda: shutil.rmtree(config_image_dir)) - config_image = os.path.join(config_image_dir, "config-%s.img" % name) - - if "accounts_ssh_authorized_keys" in kwargs: - accounts_ssh_authorized_keys = kwargs["accounts_ssh_authorized_keys"] - ssh_keys_dir = tempfile.mkdtemp() - atexit.register(lambda: shutil.rmtree(ssh_keys_dir)) - for account, keyfile in accounts_ssh_authorized_keys.items(): - with open(keyfile) as f: - keys = f.read() - with open(os.path.join(ssh_keys_dir, account), "w") as f: - f.write(keys) - kwargs["accounts_ssh_authorized_keys"] = ssh_keys_dir - - bootstrap_script = os.path.join(os.path.dirname(__file__), "..", "scripts", "build-bootstrap-config-image.sh") - args = [bootstrap_script, config_image] - for key, value in kwargs.items(): - args.append("--" + key) - args.append(value) - subprocess.run(args, stdout=subprocess.DEVNULL, check=True) - return config_image - - -def wait_ic_version(replica_url, version, timeout): - start = time.time() - now = start - while now < start + timeout: - try: - req = requests.get(replica_url) - status = cbor.loads(req.content) - if version == status.value["impl_version"]: - print("✅ ic-version on %-30s %s" % (replica_url, version)) - return - except Exception as e: - print(e) - time.sleep(1) - now = time.time() - raise TimeoutError("Timeout when waiting for IC version %s." % version) - - -def wait_host_version(host, target_version, timeout): - start = time.time() - now = start - command_line = [ - "ssh", - "-o", - "ConnectTimeout=1", - "-o", - "StrictHostKeyChecking=no", - "-o", - "UserKnownHostsFile=/dev/null", - "-o", - "ServerAliveCountMax=3", - "-o", - "ServerAliveInterval=1", - "-o", - "PasswordAuthentication=false", - "-tt", - "root@%s" % host, - "cat", - "/boot/version.txt", - ] - while now < start + timeout: - try: - version = subprocess.run(command_line, check=True, capture_output=True).stdout.decode("utf-8").strip() - if version == target_version: - print("✅ host version on %-30s %s" % (host, version)) - return - except Exception as e: - print(e) - time.sleep(1) - now = time.time() - raise TimeoutError("Timeout when waiting for host version %s." % version) - - -def get_ic_version(replica_url): - timeout = 5 - start = time.time() - now = start - while now < start + timeout: - try: - req = requests.get(replica_url) - status = cbor.loads(req.content) - return status.value["impl_version"] - except Exception as e: - print(e) - time.sleep(1) - now = time.time() - raise TimeoutError("Failed to determine IC version.") - - -def get_host_version(host): - timeout = 5 - start = time.time() - now = start - while now < start + timeout: - try: - command_line = [ - "ssh", - "-o", - "ConnectTimeout=1", - "-o", - "StrictHostKeyChecking=no", - "-o", - "UserKnownHostsFile=/dev/null", - "-o", - "ServerAliveCountMax=3", - "-o", - "ServerAliveInterval=1", - "-o", - "PasswordAuthentication=false", - "-tt", - "root@%s" % host, - "cat", - "/boot/version.txt", - ] - version = subprocess.run(command_line, check=True, capture_output=True).stdout.decode("utf-8").strip() - return version - except Exception as e: - print(e) - time.sleep(1) - now = time.time() - raise TimeoutError("Failed to determine host version.") - - -def ic_prep(subnets, version, root_subnet=0): - workdir = tempfile.mkdtemp() - atexit.register(lambda workdir=workdir: shutil.rmtree(workdir)) - - nns_ips = [] - nodes = [] - subnet_index = 0 - node_subnet_index = [] - for subnet in subnets: - for ipv6 in subnet: - node_index = len(nodes) - nodes.append("%d-%d-[%s]:4100-[%s]:2497-0-[%s]:8080" % (node_index, subnet_index, ipv6, ipv6, ipv6)) - if subnet_index == root_subnet: - nns_ips.append(ipv6) - node_subnet_index.append(subnet_index) - subnet_index += 1 - - subprocess.run( - [ - FLAGS.ic_prep_bin, - "--working-dir", - workdir, - "--replica-version", - version, - "--dkg-interval-length", - "10", - "--p2p-flows", - "1234-1", - "--nns-subnet-index", - "%d" % root_subnet, - "--nodes", - ] - + nodes, - check=True, - ) - - return ICConfig(workdir, nns_ips, node_subnet_index, root_subnet) - - -def build_ic_prep_inject_config(machine, ic_config, index, extra_config={}): - ipv6 = machine.get_ips(6)[0] - args = { - "ipv6_address": "%s/%d" % (ipv6["address"], ipv6["mask_length"]), - "ipv6_gateway": ipv6["gateway"], - "nns_url": "http://[%s]:8080" % ic_config.nns_ips[0], - "nns_public_key": os.path.join(ic_config.workdir, "nns_public_key.pem"), - "ic_crypto": os.path.join(ic_config.workdir, "node-%d" % index, "crypto"), - } - if ic_config.node_subnet_index[index] == ic_config.root_subnet: - args["ic_registry_local_store"] = os.path.join(ic_config.workdir, "ic_registry_local_store") - args.update(extra_config) - - return build_bootstrap_config_image(machine.get_name(), **args) - - -def wait_ic_up(ic_config, timeout=FLAGS.timeout): - wait_http_up("http://[%s]:8080" % ic_config.nns_ips[0], timeout) - - -def wait_http_up(url, timeout=FLAGS.timeout): - start = time.time() - now = start - while now < start + timeout: - try: - requests.get(url) - return - except Exception: - sys.stderr.write( - ("Waiting for IC to come up at %s, retrying for next %.1f seconds\n" % (url, start + timeout - now)) - ) - sys.stderr.flush() - time.sleep(1) - now = time.time() - raise TimeoutError("Time out waiting for IC instance to come up.") - - -def wait_ssh_up(host, timeout=FLAGS.timeout): - start = time.time() - now = start - command_line = [ - "ssh", - "-o", - "ConnectTimeout=1", - "-o", - "StrictHostKeyChecking=no", - "-o", - "UserKnownHostsFile=/dev/null", - "-o", - "ServerAliveCountMax=3", - "-o", - "ServerAliveInterval=1", - "-o", - "PasswordAuthentication=false", - "-tt", - "root@%s" % host, - "echo", - "alive", - ] - while now < start + timeout: - try: - subprocess.run(command_line, check=True) - return - except Exception: - sys.stderr.write( - ( - "Waiting for machine to come up at %s, retrying for next %.1f seconds\n" - % (host, start + timeout - now) - ) - ) - sys.stderr.flush() - time.sleep(1) - now = time.time() - raise TimeoutError("Time out waiting for IC instance to come up.") - - -def _get_artifact_version(artifact, kind): - if isinstance(artifact, vmtools.SystemImage): - artifact = artifact.local_path - - get_artifact_version = os.path.join( - os.path.dirname(os.path.abspath(__file__)), - "..", - "..", - "scripts", - "get-artifact-version.sh", - ) - process = subprocess.Popen([get_artifact_version, kind, artifact], stdout=subprocess.PIPE) - return process.stdout.read().decode("utf-8").strip() - - -def get_disk_image_version(image): - return _get_artifact_version(image, "--disk") - - -def get_upgrade_image_version(image): - return _get_artifact_version(image, "--upgrade") - - -def build_ssh_extra_config(): - """ - Build extra config containing ssh keys. - - Build an amendent to the IC guest OS bootstrap config that contains - ssh keys for accessing the node. If there are no ssh keys existing - yet (this is the case for CI runners), also create ssh keys. - """ - # Ensure that $HOME/.ssh/id_rsa.pub exists - home_ssh = os.path.join(os.environ["HOME"], ".ssh") - id_rsa_pub = os.path.join(home_ssh, "id_rsa.pub") - - if not os.path.exists(home_ssh): - os.mkdir(home_ssh) - if not os.path.exists(id_rsa_pub): - subprocess.run( - ["ssh-keygen", "-q", "-N", "", "-f", os.path.join(home_ssh, "id_rsa")], - check=True, - ) - - # Assign keys to root user so we have root login on the node. - return { - "accounts_ssh_authorized_keys": { - "root": id_rsa_pub, - "backup": id_rsa_pub, - "readonly": id_rsa_pub, - "admin": id_rsa_pub, - } - } diff --git a/ic-os/hostos/tests/log-streamer.py b/ic-os/hostos/tests/log-streamer.py deleted file mode 100755 index d295cb24152..00000000000 --- a/ic-os/hostos/tests/log-streamer.py +++ /dev/null @@ -1,55 +0,0 @@ -#!/usr/bin/env python3 -import subprocess -import sys -import time - -host = sys.argv[1] -num_boots = sys.argv[2] - -command_line = [ - "ssh", - "-o", - "ConnectTimeout=1", - "-o", - "StrictHostKeyChecking=no", - "-o", - "UserKnownHostsFile=/dev/null", - "-o", - "ServerAliveCountMax=3", - "-o", - "ServerAliveInterval=1", - "-o", - "PasswordAuthentication=false", - "-tt", - host, - "journalctl", - "--no-tail", - "-u", - '"*"', - "-f", -] - -for i in range(int(num_boots)): - print("--------------------------------------------------") - time.sleep(5) - received_logs = False - while not received_logs: - proc = subprocess.Popen(command_line, stdin=subprocess.DEVNULL, stdout=subprocess.PIPE) - line = b"" - while True: - # This is somewhat silly -- when not specifying size limit - # it will block indefinitely filling internal buffers (not helpful). - # Despite the looks of it, read(1) will still not result in - # single byte OS level reads (python will buffer internally). - c = proc.stdout.read(1) - if c: - line += c - if c == b"\n": - # Flushing each line makes it easier to follow in interactive - # debugging. - sys.stdout.buffer.write(line) - sys.stdout.flush() - line = b"" - received_logs = True - else: - break diff --git a/ic-os/hostos/tests/vmtools.py b/ic-os/hostos/tests/vmtools.py deleted file mode 100644 index 3aa23c37376..00000000000 --- a/ic-os/hostos/tests/vmtools.py +++ /dev/null @@ -1,675 +0,0 @@ -#!/usr/bin/env python3 -""" -Tools for working with virtual machines. - -This module provides tools to set up and control virtual machines. -The API is structured to allow allocation of machines from a -'pool' of available machines, like this: - - machines = vmtools.pool().request_machines( - [ - {"name": "node0", "ram": "6G", "disk": "100G", "cores": 1}, - {"name": "node1", "ram": "6G", "disk": "100G", "cores": 1}, - ], - ) - -And then started like this: - - vmtools.start_machines( - [ - (machines[0], system_disk_image, config_disk_image[0]), - (machines[1], system_disk_image, config_disk_image[1]), - ], - start_ssh_log_streaming=True, - ) - -All virtual machines will automatically be killed when the script -terminates. -""" -import atexit -import fcntl -import json -import os -import subprocess -import sys - -import gflags - -FLAGS = gflags.FLAGS - -gflags.DEFINE_string("log_directory", "/tmp", "Directory where log files are stored") -gflags.DEFINE_string("vmtoolscfg", "/etc/vmtoolscfg.json", "Configuration file for vmtools") -gflags.DEFINE_bool( - "is_upgrade_test", - False, - "Enable for upgrade tests. Will make sure we collect logs after reboot", -) - - -class MachineTemplate(object): - """ - 'Slot' in which a virtual machine can be spawned. - - This represents an "available VM slot" in which a user - can spawn a specific VM instance. Each template has unique - per-slot information associated with it such that multiple - VMs spawned on the target do not collide. - - Each MachineTemplate instance must be used by at most - one Machine instance. - """ - - def __init__(self, name, ipv6, ipv6_gateway, mac1, mac2): - """Initialize a new Machine with various configurations.""" - self.name = name - self.ipv6 = ipv6 - self.ipv6_gateway = ipv6_gateway - self.mac1 = mac1 - self.mac2 = mac2 - - def get_ipv6(self): - """Return machine's ipv6 address.""" - return self.ipv6.split("/")[0] - - -class Machine(object): - """ - Configuration of virtual machine instance. - - Holds the actual configuration of the machine. This - amends the information held in MachineTemplate above - with "dynamic" configuration, such as requested amount - of RAM and disk size. - """ - - def __init__(self, template, ram, disk): - """Initialize a new Machine with various configurations.""" - self.template = template - self.ram = ram - self.disk = disk - self.process = None - - def execute(self, command, check=True): - """Execute the given command on the given machine via SSH.""" - command_line = [ - "ssh", - "-o", - "ConnectTimeout=1", - "-o", - "StrictHostKeyChecking=no", - "-o", - "UserKnownHostsFile=/dev/null", - "-o", - "ServerAliveCountMax=3", - "-o", - "ServerAliveInterval=1", - "-o", - "PasswordAuthentication=false", - "root@%s" % self.get_ipv6(), - command, - ] - subprocess.run(command_line, check=check) - - def reboot(self): - """Hard-reboot this machine.""" - self.execute("reboot -ff", False) - - def get_ips(self, family): - """ - Return IP addresses for family. - - The "family" parameter must be either 4 or 6 (for IPv4 or IPv6). - - Return the list of addresses associated with then machine - for given family. The list could be empty if there are no - addresses of the family. Each entry will be a dictionary - of the form: - { - "address": , - "mask_length": , - "gateway": - } - """ - addrs = [] - for nic in self.template["nics"]: - for nic_addr in nic["addresses"]: - if nic_addr["family"] == family: - addrs.append(nic_addr) - return addrs - - def get_ipv6(self): - """Return machine's ipv6 address.""" - return self.get_ips(6)[0]["address"] - - def get_ram_mb(self): - """Return the machine's RAM in MB.""" - return self.ram // (1024 * 1024) - - def get_disk_gb(self): - """Return the machine's disk in GB.""" - return self.disk // (1024 * 1024 * 1024) - - def get_name(self): - """Return name of the virtual machine.""" - return self.template["name"] - - def stop(self): - """Stop the virtual machine.""" - if self.process: - self.process.terminate() - try: - self.process.poll(1) - self.process = None - return - except Exception: - pass - self.process.kill() - self.process.wait() - self.process = None - return - - -class QEMUConfig(object): - """ - Auxiliary object for QEMU config. - - Represent configuration for launching qemu command. - """ - - def __init__(self, name, ram="2G"): - """Create baseline qemu configuration.""" - self.name = name - self.ram = ram - self.primary_hd_img = None - self.usb_hd_imgs = [] - self.netdevs = [] - - def set_primary_hd_image(self, path): - """Set disk image for primary hard disk.""" - self.primary_hd_img = path - - def add_usb_hd_image(self, path): - """Set disk image for additional USB hard disk.""" - self.usb_hd_imgs.append(path) - - def add_netdev(self, netdev, mac): - """Add a network device.""" - self.netdevs.append((netdev, mac)) - - def _build_base_cmdline(self): - return [ - "qemu-system-x86_64", - "-machine", - "type=q35,accel=kvm", - "-enable-kvm", - "-nographic", - "-display", - "none", - "-serial", - "mon:stdio", - "-m", - self.ram, - "-bios", - "/usr/share/OVMF/OVMF_CODE.fd", - # We need a USB controller in order to be able to - # dynamically attach either removable media or HSMs - "-device", - "qemu-xhci,bus=pcie.0,addr=2.0", - ] - - def _build_primary_hd_cmdline(self): - return ( - [ - "-device", - "virtio-blk-pci,drive=drive0,bus=pcie.0,addr=3.0", - "-drive", - "file=%s,format=raw,id=drive0,if=none" % self.primary_hd_img, - ] - if self.primary_hd_img is not None - else [] - ) - - def _build_usb_hds_cmdline(self): - cmdline = [] - for usb_hd_img in self.usb_hd_imgs: - cmdline += [ - "-device", - "usb-storage,drive=removable,removable=true", - "-drive", - "file=%s,format=raw,id=removable,if=none" % usb_hd_img, - ] - return cmdline - - def _build_netdevs_cmdline(self): - cmdline = [] - for n in range(len(self.netdevs)): - index = n + 1 - netdev, mac = self.netdevs[n] - name = "enp%ds0" % index - cmdline += [ - "-device", - "pcie-root-port,id=pcie.%d,chassis=%d" % (index, index), - "-netdev", - "%s,id=%s" % (netdev, name), - "-device", - "virtio-net-pci,netdev=%s,bus=pcie.%d,addr=0.0,mac=%s" % (name, index, mac), - ] - return cmdline - - def build_cmdline(self): - """Build command line for QEMU process launch.""" - return ( - self._build_base_cmdline() - + self._build_primary_hd_cmdline() - + self._build_usb_hds_cmdline() - + self._build_netdevs_cmdline() - ) - - -def prep_image(name, image, config): - config_img = "/tmp/config-%s.img" % name - - subprocess.run(["truncate", "--size", "100M", config_img], check=True) - subprocess.run(["make_ext4fs", "-T", "0", "-l", "100M", config_img, config], check=True) - config_script = os.path.join(os.path.dirname(__file__), "write_config_part.sh") - subprocess.run([config_script, config_img, image], check=True) - - -def start_machine_local(machine, disk_image, config, interactive=False): - name = machine.get_name() - disk_image = disk_image.get_local_filename() - machine_disk = "/tmp/disk-%s.img" % name - disk_size = machine.get_disk_gb() - - subprocess.run(["cp", "--sparse=always", disk_image, machine_disk], check=True) - subprocess.run(["truncate", "--size", "%dG" % disk_size, machine_disk], check=True) - prep_image(name, machine_disk, config) - - qemu_config = QEMUConfig(name=machine.get_name(), ram="%dM" % machine.get_ram_mb()) - qemu_config.set_primary_hd_image(machine_disk) - for nic in machine.template["nics"]: - mac = nic["mac"] - netdev = nic["netdev"] - if netdev["mode"] == "tap": - qemu_netdev = "tap,ifname=%s,script=no,downscript=no" % netdev["ifname"] - elif netdev["mode"] == "bridge": - qemu_netdev = "bridge,br=%s" % netdev["bridge"] - qemu_config.add_netdev(qemu_netdev, mac) - - qemu_cmdline = qemu_config.build_cmdline() - if interactive: - stdin, stdout, stderr = None, None, None - else: - f_out = os.path.join(FLAGS.log_directory, "%s.serial.log" % machine.get_name()) - f_err = os.path.join(FLAGS.log_directory, "%s.stderr.log" % machine.get_name()) - stdin = subprocess.DEVNULL - stdout = open(f_out, "wb") - stderr = open(f_err, "wb") - process = machine.process = subprocess.Popen( - qemu_cmdline, - stdin=stdin, - stdout=stdout, - stderr=stderr, - ) - - if interactive: - process.wait() - else: - atexit.register(lambda machine=machine: machine.stop()) - - -def start_log_streamer(machine): - f_journal = os.path.join(FLAGS.log_directory, "%s.journal.log" % machine.get_name()) - f_ssh = os.path.join(FLAGS.log_directory, "%s.log_streamer_ssh.log" % machine.get_name()) - cmdline = [ - os.path.join(os.path.dirname(os.path.abspath(__file__)), "log-streamer.py"), - "root@%s" % machine.get_ipv6(), - "2" if FLAGS.is_upgrade_test else "1", - ] - log_process = subprocess.Popen( - cmdline, - stdin=subprocess.DEVNULL, - stdout=open(f_journal, "wb"), - stderr=open(f_ssh, "wb"), - ) - atexit.register(lambda log_process=log_process: log_process.kill()) - - -def start_machines(items, start_ssh_log_streaming=True): - for machine, disk_image, config in items: - start_machine_local(machine, disk_image, config) - if start_ssh_log_streaming: - start_log_streamer(machine) - - -class SystemImage(object): - """Represent a system disk image.""" - - def __init__(self, local_path): - """Initialize system image with the provided image path.""" - self.local_path = local_path - - @classmethod - def open_local(cls, local_path): - """Create a local system image.""" - return SystemImage(local_path) - - def get_local_filename(self): - """Return the system image's local filepath.""" - return self.local_path - - -class StaticNamePool(object): - """ - A pool of names that can be locked by user. - - Provide a pool of names where multiple users (in multiple processes) can - acquire a number of individual names. This pool simply uses a static - in-process list of names. - - Names are acquired using the acquire_name method. They are released either - explicitly through the release_name method, or implicitly on process exit. - """ - - def __init__(self, names): - """Initialize name pool for given set of names.""" - self.names = tuple(names) - self.index = 0 - - def acquire_name(self): - """ - Locks an available name. - - Returns the next availabel name from the pool. - """ - if self.index < len(self.names): - name = self.names[self.index] - self.index += 1 - return name - else: - return None - assert False, "abstract method" - - def release_name(self, name): - """ - Release a previously locked name. - - Does nothing (as this is simply an in-memory pool. - """ - pass - - -class LockFileNamePool(object): - """ - A pool of names that can be locked by user. - - Provide a pool of names where multiple users (in multiple processes) can - acquire a number of individual names. The locking mechanism uses lockfiles - stored in a specified directory. - - Names are acquired using the acquire_name method. They are released either - explicitly through the release_name method, or implicitly on process exit. - """ - - def __init__(self, base_dir, names): - """ - Initialize the lock file pool. - - Initialize the pool of lock files. Files will be stored in the given - base_dir (which must be at least group-writable by everyone who is - entitled to work with this pool). The list of available names is - given the the "names" variable. - """ - self.base_dir = base_dir - self.tier_index = 0 - self.name_index = 0 - self.name_tiers = [[], [], []] - self.locked = {} - - owned = set() - other_owned = set() - - uid = os.getuid() - for name in os.listdir(base_dir): - st = os.stat(os.path.join(base_dir, name)) - if st.st_uid == uid: - owned.add(name) - else: - other_owned.add(name) - for name in names: - if name in owned: - self.name_tiers[0].append(name) - elif name in other_owned: - self.name_tiers[2].append(name) - else: - self.name_tiers[1].append(name) - - def acquire_name(self): - """ - Locks an available name. - - Searches for an available name and locks it. Returns the acquired - name if successful, or None if no name is available at present. - - When looking for an available name, the search tries in this order: - - a name that was previously reserved to the same user - - a name that was never reserved by any user - - a name that was reserved by another user - - This strategy has the effect that a user performing interactive tests - will mostly work with "stable" assignment: Two calls reserving the - same number of names in short succession will result in the same - names. - """ - while self.tier_index < 3: - names = self.name_tiers[self.tier_index] - while self.name_index < len(names): - name = names[self.name_index] - fd = self._try_lock(name) - if fd is not None: - self.locked[name] = fd - return name - self.name_index += 1 - self.tier_index += 1 - self.name_index = 0 - return None - - def release_name(self, name): - """ - Release a previously locked name. - - Releases a name that was locked previously. Note that any locked name - will be released when the process exits, so it is not absolutely - necessary to explicitly release locked names. - - Precondition: The given name was previously returned from "acquire_name" - and it was not passed to "release_name" yet. - """ - fd = self.locked[name] - del self.locked[name] - os.close(fd) - - def _try_lock(self, name): - """ - Try to obtain named lock file. - - Tries to get exclusive lock for specified name - in pool. Returns descriptor of opened file if - successful. Retuns None if file is locked already. - - Post-condition: - - named file exists - - named file is owned by calling user - - returned file handle corresponds to named file - - there is an exclusive lock on returned file handle - """ - while True: - # Open (and maybe create) lock file. - p = os.path.join(self.base_dir, name) - fd = os.open(p, os.O_RDWR | os.O_CREAT, 0o666) - try: - os.fchmod(fd, 0o666) - except PermissionError: - pass - - # Try to obtain lock. - try: - fcntl.flock(fd, fcntl.LOCK_EX | fcntl.LOCK_NB) - except BlockingIOError: - os.close(fd) - return None - - # Now that file is locked, verify that obtained - # handle matches file on fs. This closes a race - # between us opening the file and someone else - # removing it underneath. - st_fs = os.stat(p) - st = os.fstat(fd) - if st_fs.st_ino != st.st_ino: - os.close(fd) - continue - break - - # At this point we have opened the file that is linked - # on fs, and we own an exclusive lock to it. The last - # thing to do is to check ownership -- if this file - # is owned by us, then we are done. - if st.st_uid == os.getuid(): - return fd - - # Create a replacement file, and also lock it instantly. - replacement_file = os.path.join(self.base_dir, "." + name) - # Remove possibly existing stale replacement file. - try: - os.unlink(replacement_file) - except FileNotFoundError: - pass - new_fd = os.open(replacement_file, os.O_RDWR | os.O_CREAT | os.O_EXCL, 0o666) - os.fchmod(new_fd, 0o666) - fcntl.flock(fd, fcntl.LOCK_EX | fcntl.LOCK_NB) - os.rename(replacement_file, p) - os.close(fd) - - return new_fd - - -class MachinePool(object): - """ - Pool of machines available to user. - - Represent the pool of virtual machines that can be used. - A test run can request a certain number of machines that - will then be reserved for duration of the test. - - Depending on configuration, this will be either a "system-wide" - pool of machines, or some in-process construct representing - a static set of machines for isolated environments (e.g. CI). - """ - - def __init__(self, vmtoolcfg_json): - """ - Initialize machine pool. - - Initializes machine pool from the given configuration - description. - """ - machine_templates = vmtoolcfg_json["machine_templates"] - names = [tpl["name"] for tpl in machine_templates] - self.machine_templates = {tpl["name"]: tpl for tpl in machine_templates} - - machine_lock_dir = vmtoolcfg_json["machine_lock_directory"] - if machine_lock_dir: - self.name_pool = LockFileNamePool(machine_lock_dir, names) - else: - self.name_pool = StaticNamePool(names) - - @classmethod - def _format_machine_template(cls, tpl): - addrs = [addr["address"] for nic in tpl["nics"] for addr in nic["addresses"]] - return "%s (%s)" % (tpl["name"], " ".join(addrs)) - - @classmethod - def _int_from_unit(cls, value): - if value[-1] == "G": - return int(value[:-1]) * 1024 * 1024 * 1024 - elif value[-1] == "M": - return int(value[:-1]) * 1024 * 1024 - elif value[-1] == "K": - return int(value[:-1]) * 1024 - else: - return int(value) - - def request_machine(self, name=None, ram="2G", disk="100G", cores=1): - """Request a single machine.""" - name = self.name_pool.acquire_name() - assert name is not None, "No machine available" - tpl = self.machine_templates[name] - sys.stderr.write("Reserved VM %s\n" % self._format_machine_template(tpl)) - sys.stderr.flush() - return Machine(tpl, self._int_from_unit(ram), self._int_from_unit(disk)) - - def request_machines(self, machine_descriptions): - """Request multiple machines.""" - return [self.request_machine(**d) for d in machine_descriptions] - - -# This is the configuration using a "fake" machine pool when specified -# to run with --vmtoolscfg=internal. This is used in CI tests for now where -# no other setup is available. -BUILTIN_VMTOOLSCFG = """ -{ - "machine_lock_directory": null, - "machine_templates": [ - { - "name": "node0", - "nics": [ - { - "mac": "52:54:00:e8:3c:db", - "netdev": { - "mode": "tap", - "ifname": "ipv6_ic_node0" - }, - "addresses": [ - {"family": 6, "address": "fd00:2:1:1:1::11", "mask_length": 64, "gateway": "fd00:2:1:1:1::1"} - ] - } - ] - }, - { - "name": "node1", - "nics": [ - { - "mac": "52:54:00:33:b2:41", - "netdev": { - "mode": "tap", - "ifname": "ipv6_ic_node1" - }, - "addresses": [ - {"family": 6, "address": "fd00:2:1:1:1::12", "mask_length": 64, "gateway": "fd00:2:1:1:1::1"} - ] - } - ] - } - ] -} -""" - - -def _create_default_pool(): - """Create default machine pool.""" - if FLAGS.vmtoolscfg == "internal": - return MachinePool(json.loads(BUILTIN_VMTOOLSCFG)) - else: - with open(FLAGS.vmtoolscfg) as file: - return MachinePool(json.loads(file.read())) - - -def pool(): - """Return pool of available machines (singleton).""" - global _machine_pool - if not _machine_pool: - _machine_pool = _create_default_pool() - return _machine_pool - - -_machine_pool = None diff --git a/ic-os/hostos/tests/vmtoolscfg-sample.json b/ic-os/hostos/tests/vmtoolscfg-sample.json deleted file mode 100644 index bf180f5b4c7..00000000000 --- a/ic-os/hostos/tests/vmtoolscfg-sample.json +++ /dev/null @@ -1,46 +0,0 @@ -{ - "machine_lock_directory": "/tmp", - "machine_templates": [ - { - "name": "node0", - "nics": [ - { - "mac": "52:54:00:e8:3c:db", - "netdev": { - "mode": "bridge", - "bridge": "ipv6_ic" - }, - "addresses": [ - { - "family": 6, - "address": "fd00:2:1:1:1::11", - "mask_length": 64, - "gateway": "fd00:2:1:1:1::1" - } - ] - } - ] - }, - { - "name": "node1", - "nics": [ - { - "mac": "52:54:00:33:b2:41", - "netdev": { - "mode": "bridge", - "bridge": "ipv6_ic" - }, - "addresses": [ - { - "family": 6, - "address": "fd00:2:1:1:1::12", - "mask_length": 64, - "gateway": "fd00:2:1:1:1::1" - } - ] - } - ] - } - ] -} - diff --git a/ic-os/hostos/tests/write_config_part.sh b/ic-os/hostos/tests/write_config_part.sh deleted file mode 100755 index b40e72231db..00000000000 --- a/ic-os/hostos/tests/write_config_part.sh +++ /dev/null @@ -1,18 +0,0 @@ -#!/usr/bin/env bash - -# Write image to config LVM of hostos image -# -# Arguments: -# $1: The disk image to be read from. -# $2: The disk image to write to. - -set -eo pipefail - -# ----------------------------------------------------------------------- - -BASE_DIR=$(dirname "${BASH_SOURCE[0]}") - -cd "${BASE_DIR}"/../.. -source scripts/partitions.sh hostos/build - -write_single_lvm_volume $2 hostlvm config $1 diff --git a/ic-os/scripts/README.adoc b/ic-os/scripts/README.adoc deleted file mode 100644 index 039df31d997..00000000000 --- a/ic-os/scripts/README.adoc +++ /dev/null @@ -1,5 +0,0 @@ -= Scripts - -This folder contains build and utility scripts for HostOS, intended to be -unified with `ic-os/guestos/scripts` and `ic-os/generic-guestos/scripts` to be -a common build system for any docker based images. diff --git a/ic-os/scripts/artifact-utils.sh b/ic-os/scripts/artifact-utils.sh deleted file mode 100755 index 59b11a5552b..00000000000 --- a/ic-os/scripts/artifact-utils.sh +++ /dev/null @@ -1,33 +0,0 @@ -#!/usr/bin/env bash - -source $(dirname "${BASH_SOURCE[0]}")/partitions.sh "" - -# Extract the version number from an upgrade artifact -# Arguments: -# - $1: upgrade artifact file -# -# Output: the version number -function version_from_upgrade_image() { - # Search for both "VERSION.TXT" (new form) and "version.txt" in - # the archive. The former is quickly found if it exists (because - # it is sorted first lexicographically). The latter requires - # unpacking the entire archive, so should be avoided. This is - # left here for the "upgrade-to-master" test where we try an - # upgrade to an artifact of older form. - tar xOzf "$1" --occurrence=1 ./VERSION.TXT || tar xOzf "$1" --occurrence=1 ./version.txt -} - -# Extracts the version number from built disk image -# Arguments: -# - $1: disk image file -# -# Output: the version number -function version_from_disk_image() { - local DISK_IMAGE=$1 - local PART_IMAGE=$(mktemp) - extract_single_partition "${DISK_IMAGE}" A_boot "${PART_IMAGE}" 2>/dev/null - VERSION=$(debugfs "${PART_IMAGE}" -R "cat version.txt" 2>/dev/null || echo -n "unknown") - #debugfs "${PART_IMAGE}" -R ls - rm "${PART_IMAGE}" - echo "${VERSION}" -} diff --git a/ic-os/scripts/build-boot-and-root-fsimage.sh b/ic-os/scripts/build-boot-and-root-fsimage.sh deleted file mode 100755 index 66ec4253acf..00000000000 --- a/ic-os/scripts/build-boot-and-root-fsimage.sh +++ /dev/null @@ -1,80 +0,0 @@ -#!/usr/bin/env bash - -# Takes a filesystem tree, optionally applies selinux labels (as -# configured in file contexts), and turns it into two filesystem images: -# one for the "boot" directory, and one for the "root". -# -# This needs to be done in a single step such that this can all be run -# under a single "fakeroot" invocation -- it appears that fakeroot has -# a bug that it does not preserve extended attributes across sessions. - -set -e - -BASEDIR="$1" -ROOT_IMAGE="$2" -BOOT_IMAGE="$3" - -# This is only relevant if SELinux is used inside the target system -- -# label all files correctly in this case. -FILE_CONTEXTS="${BASEDIR}/etc/selinux/default/contexts/files/file_contexts" - -if [ -e "${FILE_CONTEXTS}" ]; then - TMPDIR=$(mktemp -d) - trap "rm -rf ${TMPDIR}" exit - ROOT_FILE_CONTEXTS="${TMPDIR}/root_file_contexts" - BOOT_FILE_CONTEXTS="${TMPDIR}/boot_file_contexts" - sed -e '/<>/d' -e 's!^/!!' <"${FILE_CONTEXTS}" >"${ROOT_FILE_CONTEXTS}" - sed -e '/<>/d' -e 's!^/boot/!!' -e t -e d <"${FILE_CONTEXTS}" >"${BOOT_FILE_CONTEXTS}" -fi - -BOOT_SIZE=$(stat --print=%s "${BOOT_IMAGE}") -ROOT_SIZE=$(stat --print=%s "${ROOT_IMAGE}") - -if [ "${BOOT_FILE_CONTEXTS}" != "" ]; then - make_ext4fs -T 0 -l "${BOOT_SIZE}" -S "${BOOT_FILE_CONTEXTS}" "${BOOT_IMAGE}" "${BASEDIR}/boot" - - # It appears the context of the root inode is not set correctly. Fix it up. - ROOT_CONTEXT=$(sed -e 's#^/boot[ \t]\+-d[ \t]\+##' -e 't' -e 'd' <"${FILE_CONTEXTS}") - echo Setting root inode context of 'boot' image to "${ROOT_CONTEXT}" - echo 'ea_set / security.selinux "'"${ROOT_CONTEXT}"'\000"' | debugfs -w "${BOOT_IMAGE}" - echo -else - make_ext4fs -T 0 -l "${BOOT_SIZE}" "${BOOT_IMAGE}" "${BASEDIR}/boot" -fi - -# Delete the contents of /boot/ -- boot partition will be mounted -# on top of this directory. We don't want its contents in the root -# image. -rm -rf "${BASEDIR}"/boot/* - -rm -rf "${BASEDIR}"/run/* -chmod 0644 "${BASEDIR}"/etc/hosts "${BASEDIR}"/etc/hostname "${BASEDIR}"/etc/resolv.conf - -if [ "${ROOT_FILE_CONTEXTS}" != "" ]; then - make_ext4fs -T 0 -l "${ROOT_SIZE}" -S "${ROOT_FILE_CONTEXTS}" "${ROOT_IMAGE}" "${BASEDIR}" - - # It appears the context of the root inode is not set correctly. Fix it up. - ROOT_CONTEXT=$(sed -e 's#^/[ \t]\+-d[ \t]\+##' -e 't' -e 'd' <"${FILE_CONTEXTS}") - echo Setting root inode context of 'root' image to "${ROOT_CONTEXT}" - echo 'ea_set / security.selinux "'"${ROOT_CONTEXT}"'\000"' | debugfs -w "${ROOT_IMAGE}" - echo -else - make_ext4fs -T 0 -l "${ROOT_SIZE}" "${ROOT_IMAGE}" "${BASEDIR}" -fi - -# make_ext4fs has the defect that it does not preserve file ownership of -# input files when creating the FS image. Luckily, we do not have many files -# in this category. Identify all files, and fix them up in the file system -# image after build. - -# Find all files that are not owned root:root. -for FIXUP_FILE in $(find "${BASEDIR}" -uid +0 -o -gid +0); do - # Get ownership of file. - FILE_UID=$(stat --format "%u" ${FIXUP_FILE}) - FILE_GID=$(stat --format "%g" ${FIXUP_FILE}) - # Strip prefix to get correct target file. - TARGET_FILE="${FIXUP_FILE#"${BASEDIR}/"}" - # Apply ownership changes. - echo "Fix ownership of ${TARGET_FILE} to ${FILE_UID}:${FILE_GID}" - echo -e "\n${FILE_UID}\n${FILE_GID}\n" | debugfs -w "${ROOT_IMAGE}" -R "modify_inode ${TARGET_FILE}" >/dev/null 2>&1 -done diff --git a/ic-os/scripts/build-bootstrap-config-image.sh b/ic-os/scripts/build-bootstrap-config-image.sh deleted file mode 100755 index 8cec6d8dc6d..00000000000 --- a/ic-os/scripts/build-bootstrap-config-image.sh +++ /dev/null @@ -1,262 +0,0 @@ -#!/usr/bin/env bash - -set -e - -function usage() { - cat >&2 <&2 - exit 1 - } - - local BOOTSTRAP_TMPDIR=$(mktemp -d) - - cat >"${BOOTSTRAP_TMPDIR}/network.conf" <"${BOOTSTRAP_TMPDIR}/journalbeat.conf" - if [ "${JOURNALBEAT_TAGS}" != "" ]; then - echo "journalbeat_tags=$JOURNALBEAT_TAGS" >>"${BOOTSTRAP_TMPDIR}/journalbeat.conf" - fi - fi - if [ "${NNS_PUBLIC_KEY}" != "" ]; then - cp "${NNS_PUBLIC_KEY}" "${BOOTSTRAP_TMPDIR}/nns_public_key.pem" - fi - if [ "${NNS_URL}" != "" ]; then - echo "nns_url=${NNS_URL}" >"${BOOTSTRAP_TMPDIR}/nns.conf" - fi - if [ "${BACKUP_RETENTION_TIME_SECS}" != "" ] || [ "${BACKUP_PURGING_INTERVAL_SECS}" != "" ]; then - echo "backup_retention_time_secs=${BACKUP_RETENTION_TIME_SECS}" >"${BOOTSTRAP_TMPDIR}/backup.conf" - echo "backup_puging_interval_secs=${BACKUP_PURGING_INTERVAL_SECS}" >>"${BOOTSTRAP_TMPDIR}/backup.conf" - fi - if [ "${LOG_DEBUG_OVERRIDES}" != "" ]; then - echo "log_debug_overrides=${LOG_DEBUG_OVERRIDES}" >"${BOOTSTRAP_TMPDIR}/log.conf" - fi - if [ "${MALICIOUS_BEHAVIOR}" != "" ]; then - echo "malicious_behavior=${MALICIOUS_BEHAVIOR}" >"${BOOTSTRAP_TMPDIR}/malicious_behavior.conf" - fi - if [ "${IC_CRYPTO}" != "" ]; then - cp -r "${IC_CRYPTO}" "${BOOTSTRAP_TMPDIR}/ic_crypto" - fi - if [ "${IC_REGISTRY_LOCAL_STORE}" != "" ]; then - cp -r "${IC_REGISTRY_LOCAL_STORE}" "${BOOTSTRAP_TMPDIR}/ic_registry_local_store" - fi - if [ "${ACCOUNTS_SSH_AUTHORIZED_KEYS}" != "" ]; then - cp -r "${ACCOUNTS_SSH_AUTHORIZED_KEYS}" "${BOOTSTRAP_TMPDIR}/accounts_ssh_authorized_keys" - fi - - tar cf "${OUT_FILE}" -C "${BOOTSTRAP_TMPDIR}" . - - rm -rf "${BOOTSTRAP_TMPDIR}" -} - -# Arguments: -# - $1 the disk image to be built -# - all remaining arguments: parameters to encode into the bootstrap - -function build_ic_bootstrap_diskimage() { - local OUT_FILE="$1" - shift - - local TMPDIR=$(mktemp -d) - build_ic_bootstrap_tar "${TMPDIR}/ic-bootstrap.tar" "$@" - - truncate -s 10M "${OUT_FILE}" - mkfs.vfat "${OUT_FILE}" - mcopy -i "${OUT_FILE}" -o "${TMPDIR}/ic-bootstrap.tar" :: - - rm -rf "${TMPDIR}" -} - -BUILD_TAR_ONLY=0 -if [ "$1" == "-t" -o "$1" == "--tar" ]; then - BUILD_TAR_ONLY=1 - shift -fi - -if [ "$#" -lt 2 ]; then - usage - exit 1 -fi - -if [ "${BUILD_TAR_ONLY}" == 0 ]; then - build_ic_bootstrap_diskimage "$@" -else - build_ic_bootstrap_tar "$@" -fi diff --git a/ic-os/scripts/build-container.sh b/ic-os/scripts/build-container.sh deleted file mode 100755 index 98482af8b21..00000000000 --- a/ic-os/scripts/build-container.sh +++ /dev/null @@ -1,38 +0,0 @@ -#!/usr/bin/env bash - -# Build the node as a docker container. If called with no arguments, -# outputs the ID of the built docker image on stdout. -# -# If called with a single argument, tags the generated image after build -# using the given tag. - -set -e - -BUILD_TAG="$1" - -BASE_DIR=$(dirname "${BASH_SOURCE[0]}")/.. - -# Perform docker build and return the id of the built docker image. -function build_docker_return_id() { - DOCKER_ID=$( - # Account for two different output formats of docker command: - # "classic" docker and "buildkit" docker - docker build $* 2>&1 | tee /dev/fd/2 | sed -e 's/Successfully built \([0-9a-f]\{12\}\)/\1/' -e t -e 's/.*writing image sha256:\([0-9a-f]\+\).*/\1/' -e t -e d - ) - - echo "${DOCKER_ID}" -} - -UBUNTU_ROOTFS_DOCKER_ID=$(build_docker_return_id "${BASE_DIR}/rootfs") - -if [ ! -e ${BASE_DIR}/containerfs/etc/ssh/ssh_host_dsa_key ]; then - ssh-keygen -A -f ${BASE_DIR}/containerfs/ -fi - -UBUNTU_CONTAINERFS_ID=$(build_docker_return_id --build-arg UBUNTU_ROOTFS="${UBUNTU_ROOTFS_DOCKER_ID}" "${BASE_DIR}/containerfs") - -if [ "${BUILD_TAG}" != "" ]; then - docker tag "${UBUNTU_CONTAINERFS_ID}" "${BUILD_TAG}" -else - echo "${UBUNTU_CONTAINERFS_ID}" -fi diff --git a/ic-os/scripts/build-deployment.sh b/ic-os/scripts/build-deployment.sh deleted file mode 100755 index 9f7eb4bcd66..00000000000 --- a/ic-os/scripts/build-deployment.sh +++ /dev/null @@ -1,450 +0,0 @@ -#!/usr/bin/env bash - -# Build subnet based on subnet.json and transform it into removable media. - -# Build Requirements: -# - Operating System: Ubuntu 20.04 -# - Packages: coreutils, jq, mtools, tar, util-linux, wget, rclone - -set -o errexit -set -o pipefail - -BASE_DIR="$(dirname "${BASH_SOURCE[0]}")/.." -REPO_ROOT=$(git rev-parse --show-toplevel) - -# Set argument defaults -DEBUG=0 -TESTNET_KEYS="" - -# Get keyword arguments -for argument in "${@}"; do - case ${argument} in - -h | --help) - echo 'Usage: - - Internet Computer Operating System - Removable Media Builder - -Arguments: - -h, --help show this help message and exit - -i=, --input= JSON formatted input file (Default: ./subnet.json) - -o=, --output= removable media output directory (Default: ./build-out/) - -s=, --ssh= specify directory holding SSH authorized_key files (Default: ../../testnet/config/ssh_authorized_keys) - --git-revision= git revision for which to prepare the media - --whitelist= path to provisional whitelist that allows canister creation - --dkg-interval-length= number of consensus rounds between DKG (-1 if not provided explicitly, which means - default will be used) - --max-ingress-bytes-per-message= maximum size of ingress message allowed in bytes - -x, --debug enable verbose console output - --with-testnet-keys Initialize the registry with readonly and backup keys from testnet/config/ssh_authorized_keys. -' - exit 1 - ;; - -i=* | --input=*) - INPUT="${argument#*=}" - shift - ;; - -o=* | --output=*) - OUTPUT="${argument#*=}" - shift - ;; - -s=* | --ssh=*) - SSH="${argument#*=}" - shift - ;; - --git-revision=*) - GIT_REVISION="${argument#*=}" - shift - ;; - --whitelist=*) - WHITELIST="${argument#*=}" - shift - ;; - --dkg-interval-length=*) - DKG_INTERVAL_LENGTH="${argument#*=}" - shift - ;; - --max-ingress-bytes-per-message=*) - MAX_INGRESS_BYTES_PER_MESSAGE="${argument#*=}" - shift - ;; - -x | --debug) - DEBUG=1 - ;; - --with-testnet-keys) - TESTNET_KEYS="${REPO_ROOT}/testnet/config/ssh_authorized_keys/admin" - ;; - *) - echo 'Error: Argument is not supported.' - exit 1 - ;; - esac -done - -# Set arguments if undefined -INPUT="${INPUT:=${BASE_DIR}/subnet.json}" -OUTPUT="${OUTPUT:=${BASE_DIR}/build-out}" -SSH="${SSH:=${BASE_DIR}/../../testnet/config/ssh_authorized_keys}" -GIT_REVISION="${GIT_REVISION:=}" -WHITELIST="${WHITELIST:=}" -# Negative DKG value means unset (default will be used) -DKG_INTERVAL_LENGTH="${DKG_INTERVAL_LENGTH:=-1}" -# Negative value means unset (default will be used) -MAX_INGRESS_BYTES_PER_MESSAGE="${MAX_INGRESS_BYTES_PER_MESSAGE:=-1}" - -if [[ -z "$GIT_REVISION" ]]; then - echo "Please provide the GIT_REVISION as env. variable or the command line with --git-revision=" - exit 1 -fi - -if [[ -z "$WHITELIST" ]]; then - echo "Please provide the WHITELIST as env. variable or the command line with --whitelist=" - exit 1 -fi - -# Load INPUT -CONFIG="$(cat ${INPUT})" - -# Read all the top-level values out in one swoop -VALUES=$(echo ${CONFIG} | jq -r -c '[ - .deployment, - (.name_servers | join(" ")), - (.name_servers_fallback | join(" ")), - (.journalbeat_hosts | join(" ")) -] | join("\u0001")') -IFS=$'\1' read -r DEPLOYMENT NAME_SERVERS NAME_SERVERS_FALLBACK JOURNALBEAT_HOSTS < <(echo $VALUES) - -# Read all the node info out in one swoop -NODES=0 -VALUES=$(echo ${CONFIG} \ - | jq -r -c '.datacenters[] -| .aux_nodes[] += { "type": "aux" } | .boundary_nodes[] += {"type": "boundary"} | .nodes[] += { "type": "replica" } -| [.aux_nodes[], .boundary_nodes[], .nodes[]][] + { "ipv6_prefix": .ipv6_prefix, "ipv6_subnet": .ipv6_subnet } | [ - .ipv6_prefix, - .ipv6_subnet, - .ipv6_address, - .hostname, - .subnet_type, - .subnet_idx, - .node_idx, - .use_hsm, - .type -] | join("\u0001")') -while IFS=$'\1' read -r ipv6_prefix ipv6_subnet ipv6_address hostname subnet_type subnet_idx node_idx use_hsm type; do - eval "declare -A __RAW_NODE_$NODES=( - ['ipv6_prefix']=$ipv6_prefix - ['ipv6_subnet']=$ipv6_subnet - ['ipv6_address']=$ipv6_address - ['subnet_type']=$subnet_type - ['hostname']=$hostname - ['subnet_idx']=$subnet_idx - ['node_idx']=$node_idx - ['use_hsm']=$use_hsm - ['type']=$type - )" - NODES=$((NODES + 1)) -done < <(printf "%s\n" "${VALUES[@]}") -NODES=${!__RAW_NODE_@} - -function prepare_build_directories() { - TEMPDIR=$(mktemp -d /tmp/build-deployment.sh.XXXXXXXXXX) - - IC_PREP_DIR="$TEMPDIR/IC_PREP" - CONFIG_DIR="$TEMPDIR/CONFIG" - TARBALL_DIR="$TEMPDIR/TARBALL" - - mkdir -p "${IC_PREP_DIR}" - mkdir -p "${CONFIG_DIR}" - mkdir -p "${TARBALL_DIR}" - - if [ ! -d "${OUTPUT}" ]; then - mkdir -p "${OUTPUT}" - fi -} - -function cleanup_rootfs() { - rm -rf ${BASE_DIR}/rootfs/opt/ic/bin/orchestrator* - rm -rf ${BASE_DIR}/rootfs/opt/ic/bin/replica* -} - -function download_registry_canisters() { - "${REPO_ROOT}"/gitlab-ci/src/artifacts/rclone_download.py \ - --git-rev "$GIT_REVISION" --remote-path=canisters --out="${IC_PREP_DIR}/canisters" - - find "${IC_PREP_DIR}/canisters/" -name "*.gz" -print0 | xargs -P100 -0I{} bash -c "gunzip -f {}" - - rsync -a --delete "${IC_PREP_DIR}/canisters/" "$OUTPUT/canisters/" -} - -function download_binaries() { - "${REPO_ROOT}"/gitlab-ci/src/artifacts/rclone_download.py \ - --git-rev "$GIT_REVISION" --remote-path=release --out="${IC_PREP_DIR}/bin" - - find "${IC_PREP_DIR}/bin/" -name "*.gz" -print0 | xargs -P100 -0I{} bash -c "gunzip -f {} && basename {} .gz | xargs -I[] chmod +x ${IC_PREP_DIR}/bin/[]" - - mkdir -p "$OUTPUT/bin" - rsync -a --delete "${IC_PREP_DIR}/bin/" "$OUTPUT/bin/" -} - -function generate_subnet_config() { - # Start hashing in the background - mkfifo "$TEMPDIR/REPLICA_HASH" - mkfifo "$TEMPDIR/NM_HASH" - sha256sum "${IC_PREP_DIR}/bin/replica" | cut -d " " -f 1 >"$TEMPDIR/REPLICA_HASH" & - sha256sum "${IC_PREP_DIR}/bin/orchestrator" | cut -d " " -f 1 >"$TEMPDIR/NM_HASH" & - - cp -a ${IC_PREP_DIR}/bin/replica "$REPO_ROOT/ic-os/guestos/rootfs/opt/ic/bin/replica" - cp -a ${IC_PREP_DIR}/bin/orchestrator "$REPO_ROOT/ic-os/guestos/rootfs/opt/ic/bin/orchestrator" - cp -a ${IC_PREP_DIR}/bin/boundary-node-control-plane "$REPO_ROOT/ic-os/generic-guestos/rootfs/opt/dfinity/boundary-node-control-plane" - cp -a ${IC_PREP_DIR}/bin/boundary-node-prober "$REPO_ROOT/ic-os/generic-guestos/rootfs/opt/dfinity/boundary-node-prober" - - NODES_NNS=() - NODES_APP=() - # Query and list all NNS and APP node addresses in subnet - for n in $NODES; do - declare -n NODE=$n - if [[ "${NODE["type"]}" != "replica" ]]; then - continue - fi - local ipv6_address=${NODE["ipv6_address"]} - local subnet_idx=${NODE["subnet_idx"]} - local node_idx=${NODE["node_idx"]} - local subnet_type=${NODE["subnet_type"]} - - if [[ "$subnet_type" == "root_subnet" ]]; then - NODES_NNS+=("$node_idx-$subnet_idx-[${ipv6_address}]:4100-[${ipv6_address}]:2497-0-[${ipv6_address}]:8080") - elif [[ "$subnet_type" == "app_subnet" ]]; then - if [[ "$subnet_idx" == "x" ]]; then - # Unassigned nodes (nodes not assigned to any subnet) have an empty subnet_idx - # in the line submitted to ic-prep. - subnet_idx="" - fi - NODES_APP+=("$node_idx-$subnet_idx-[${ipv6_address}]:4100-[${ipv6_address}]:2497-0-[${ipv6_address}]:8080") - fi - done - - # The principal id below is the one corresponding to the hardcoded key in - # ic_test_utilities::identity::TEST_IDENTITY_KEYPAIR. We do not have access to it - # in this script, so hardcode the corresponding principal instead. - # - # It is used for both the node operator and its corresponding provider. - NODE_OPERATOR_ID="5o66h-77qch-43oup-7aaui-kz5ty-tww4j-t2wmx-e3lym-cbtct-l3gpw-wae" - - # Get the hash results - REPLICA_HASH=$(cat "$TEMPDIR/REPLICA_HASH") - NM_HASH=$(cat "$TEMPDIR/NM_HASH") - - set -x - # Generate key material for assigned nodes - # See subnet_crypto_install, line 5 - "${IC_PREP_DIR}/bin/ic-prep" \ - "--working-dir" "${IC_PREP_DIR}" \ - "--replica-download-url" "file:///opt/ic/bin/replica" \ - "--replica-hash" "${REPLICA_HASH}" \ - "--replica-version" "${GIT_REVISION}" \ - "--orchestrator-download-url" "file:///opt/ic/bin/orchestrator" \ - "--orchestrator-hash" "${NM_HASH}" \ - "--nns-subnet-index" "0" \ - "--dkg-interval-length" "${DKG_INTERVAL_LENGTH}" \ - "--max-ingress-bytes-per-message" "${MAX_INGRESS_BYTES_PER_MESSAGE}" \ - "--p2p-flows" "1234-1" \ - "--nodes" ${NODES_NNS[*]} ${NODES_APP[*]} \ - "--provisional-whitelist" "${WHITELIST}" \ - "--initial-node-operator" "${NODE_OPERATOR_ID}" \ - "--initial-node-provider" "${NODE_OPERATOR_ID}" \ - "--ssh-readonly-access-file" "${TESTNET_KEYS}" \ - "--ssh-backup-access-file" "${TESTNET_KEYS}" - set +x -} - -function create_tarball_structure() { - for n in $NODES; do - declare -n NODE=$n - local subnet_idx=${NODE["subnet_idx"]} - local node_idx=${NODE["node_idx"]} - NODE_PREFIX=${DEPLOYMENT}.$subnet_idx.$node_idx - mkdir -p "${CONFIG_DIR}/$NODE_PREFIX/node/replica_config" - done -} - -function generate_journalbeat_config() { - for n in $NODES; do - declare -n NODE=$n - local subnet_idx=${NODE["subnet_idx"]} - local node_idx=${NODE["node_idx"]} - - # Define hostname - NODE_PREFIX=${DEPLOYMENT}.$subnet_idx.$node_idx - - if [ "${JOURNALBEAT_HOSTS}" != "" ]; then - echo "journalbeat_hosts=${JOURNALBEAT_HOSTS}" >"${CONFIG_DIR}/$NODE_PREFIX/journalbeat.conf" - fi - done -} - -function generate_node_config() { - # Query and list all NNS nodes in subnet - # Populate NNS specific configuration - NNS_URL=() - for n in $NODES; do - declare -n NODE=$n - - local ipv6_address=${NODE["ipv6_address"]} - local subnet_idx=${NODE["subnet_idx"]} - local node_idx=${NODE["node_idx"]} - local subnet_type=${NODE["subnet_type"]} - - if [[ "${NODE["type"]}" != "replica" ]]; then - continue - fi - if [[ "$subnet_type" != "root_subnet" ]]; then - continue - fi - - # Copy initial NNS - NODE_PREFIX=${DEPLOYMENT}.$subnet_idx.$node_idx - cp -r "${IC_PREP_DIR}/ic_registry_local_store" "${CONFIG_DIR}/$NODE_PREFIX/" - - NNS_URL+=("http://[${ipv6_address}]:8080") - done - NNS_URL=$( - IFS=, - echo "${NNS_URL[*]}" - ) - - # Populate generic configuration - for n in $NODES; do - declare -n NODE=$n - local ipv6_address=${NODE["ipv6_address"]} - local subnet_type=${NODE["subnet_type"]} - local type=${NODE["type"]} - local subnet_idx=${NODE["subnet_idx"]} - local node_idx=${NODE["node_idx"]} - NODE_PREFIX=${DEPLOYMENT}.$subnet_idx.$node_idx - - if [[ "$type" == "replica" ]]; then - local use_hsm=${NODE["use_hsm"]} - - # Update crypto setup - if ! [[ "${use_hsm}" == "true" || "${use_hsm}" == "1" ]]; then - cp -r "${IC_PREP_DIR}/node-$node_idx/crypto/" "${CONFIG_DIR}/$NODE_PREFIX/ic_crypto/" - fi - - # Copy the NNS public key in the correct place - cp "${IC_PREP_DIR}/nns_public_key.pem" "${CONFIG_DIR}/$NODE_PREFIX/nns_public_key.pem" - echo "nns_url=${NNS_URL}" >"${CONFIG_DIR}/$NODE_PREFIX/nns.conf" - - elif [[ "$type" == "boundary" ]]; then - # Copy the NNS public key in the correct place - cp "${IC_PREP_DIR}/nns_public_key.pem" "${CONFIG_DIR}/$NODE_PREFIX/nns_public_key.pem" - echo "nns_url=${NNS_URL}" >"${CONFIG_DIR}/$NODE_PREFIX/nns.conf" - fi - done -} - -function generate_network_config() { - for n in $NODES; do - declare -n NODE=$n - local hostname=${NODE["hostname"]} - local subnet_idx=${NODE["subnet_idx"]} - local node_idx=${NODE["node_idx"]} - - # Define hostname - NODE_PREFIX=${DEPLOYMENT}.$subnet_idx.$node_idx - echo "hostname=${hostname}" >"${CONFIG_DIR}/$NODE_PREFIX/network.conf" - - # Set name servers - echo "name_servers=${NAME_SERVERS}" >>"${CONFIG_DIR}/$NODE_PREFIX/network.conf" - echo "name_servers_fallback=${NAME_SERVERS_FALLBACK}" >>"${CONFIG_DIR}/$NODE_PREFIX/network.conf" - - # IPv6 network configuration is obtained from the Router Advertisement. - done -} - -function copy_ssh_keys() { - for n in $NODES; do - declare -n NODE=$n - local subnet_idx=${NODE["subnet_idx"]} - local node_idx=${NODE["node_idx"]} - - NODE_PREFIX=${DEPLOYMENT}.$subnet_idx.$node_idx - - # Copy the contents of the directory, but make sure that we do not - # copy/create symlinks (but rather dereference file contents). - # Symlinks must be refused by the config injection script (they - # can lead to confusion and side effects when overwriting one - # file changes another). - cp -Lr "${SSH}" "${CONFIG_DIR}/$NODE_PREFIX/accounts_ssh_authorized_keys" - done -} - -function build_tarball() { - for n in $NODES; do - declare -n NODE=$n - local subnet_idx=${NODE["subnet_idx"]} - local node_idx=${NODE["node_idx"]} - - # Create temporary tarball directory per node - NODE_PREFIX=${DEPLOYMENT}.$subnet_idx.$node_idx - mkdir -p "${TARBALL_DIR}/$NODE_PREFIX" - ( - cd "${CONFIG_DIR}/$NODE_PREFIX" - tar c . - ) >${TARBALL_DIR}/$NODE_PREFIX/ic-bootstrap.tar - done - tar czf "${OUTPUT}/config.tgz" -C "${CONFIG_DIR}" . -} - -function build_removable_media() { - for n in $NODES; do - declare -n NODE=$n - local subnet_idx=${NODE["subnet_idx"]} - local node_idx=${NODE["node_idx"]} - - #echo "${DEPLOYMENT}.$subnet_idx.$node_idx" - NODE_PREFIX=${DEPLOYMENT}.$subnet_idx.$node_idx - truncate --size 4M "${OUTPUT}/$NODE_PREFIX.img" - mkfs.vfat "${OUTPUT}/$NODE_PREFIX.img" - mcopy -i "${OUTPUT}/$NODE_PREFIX.img" -o -s ${TARBALL_DIR}/$NODE_PREFIX/ic-bootstrap.tar :: - done -} - -function remove_temporary_directories() { - rm -rf ${TEMPDIR} -} - -# See how we were called -if [ ${DEBUG} -eq 1 ]; then - cleanup_rootfs - prepare_build_directories - download_binaries & - DOWNLOAD_PID=$! - download_registry_canisters - wait $DOWNLOAD_PID - generate_subnet_config - create_tarball_structure - generate_journalbeat_config - generate_node_config - generate_network_config - copy_ssh_keys - build_tarball - build_removable_media - remove_temporary_directories - cleanup_rootfs -else - cleanup_rootfs >/dev/null 2>&1 - prepare_build_directories >/dev/null 2>&1 - download_binaries >/dev/null 2>&1 & - DOWNLOAD_PID=$! - download_registry_canisters >/dev/null 2>&1 - wait $DOWNLOAD_PID - generate_subnet_config >/dev/null 2>&1 - create_tarball_structure >/dev/null 2>&1 - generate_journalbeat_config >/dev/null 2>&1 - generate_node_config >/dev/null 2>&1 - generate_network_config >/dev/null 2>&1 - copy_ssh_keys >/dev/null 2>&1 - build_tarball >/dev/null 2>&1 - build_removable_media >/dev/null 2>&1 - remove_temporary_directories >/dev/null 2>&1 - cleanup_rootfs >/dev/null 2>&1 -fi diff --git a/ic-os/scripts/build-docker-save.sh b/ic-os/scripts/build-docker-save.sh deleted file mode 100755 index ec27d45c6cc..00000000000 --- a/ic-os/scripts/build-docker-save.sh +++ /dev/null @@ -1,22 +0,0 @@ -#!/usr/bin/env bash - -# Build docker image in a specific directory and stream its "saved -# image" (layered tar) to stdout. -# -# Arguments to this script are passed verbatim to "docker build". - -# We implicitly pull dependent image. -ARGS=(--pull) -if [ "${CI_JOB_NAME:-}" == "docker-build-ic"* ]; then - # Don't use cache in "docker-build-ic*" CI job. - ARGS+=(--no-cache) -fi - -DOCKER_ID=$( - # Account for two different output formats of docker command: - # "classic" docker and "buildkit" docker - echo "docker build ${ARGS[@]} $@" >&2 - docker build "${ARGS[@]}" "$@" 2>&1 | tee /dev/fd/2 | sed -e 's/Successfully built \([0-9a-f]\{12\}\)/\1/' -e t -e 's/.*writing image sha256:\([0-9a-f]\{64\}\) .*/\1/' -e t -e d -) - -docker save "${DOCKER_ID}" diff --git a/ic-os/scripts/build-docker.sh b/ic-os/scripts/build-docker.sh deleted file mode 100755 index 5856ec18253..00000000000 --- a/ic-os/scripts/build-docker.sh +++ /dev/null @@ -1,23 +0,0 @@ -#!/usr/bin/env bash - -# Build both bootloader and rootfs docker and save them to docker -# export tar. -# -# Arguments: -# - $1: Directory under which to store the docker output -# -# This script is intended to be used as first part of CI pipeline. - -set -euo pipefail - -OUT_DIR="$1" -shift - -BASE_DIR=$(dirname "${BASH_SOURCE[0]}")/.. - -mkdir -p $OUT_DIR - -docker version - -"${BASE_DIR}"/scripts/build-docker-save.sh "${BASE_DIR}"/bootloader >"$OUT_DIR/bootloader.tar" -"${BASE_DIR}"/scripts/build-docker-save.sh "${BASE_DIR}"/rootfs >"$OUT_DIR/rootfs.tar" diff --git a/ic-os/scripts/build-ubuntu.sh b/ic-os/scripts/build-ubuntu.sh deleted file mode 100755 index cc8d7dd58a3..00000000000 --- a/ic-os/scripts/build-ubuntu.sh +++ /dev/null @@ -1,85 +0,0 @@ -#!/usr/bin/env bash - -# Build ubuntu system image -- this consists of the "boot" and "root" -# filesystem images. - -set -eo pipefail - -function usage() { - cat <"${TMPDIR}/VERSION.TXT" -# Sort by name in tar file -- makes ordering deterministic and ensures -# that VERSION.TXT is first entry, making it quick & easy to extract. -# Override owner, group and mtime to make build independent of the user -# building it. -tar czf "${OUT_FILE}" --sort=name --owner=root:0 --group=root:0 --mtime='UTC 2020-01-01' --sparse -C "${TMPDIR}" . - -rm -rf "${TMPDIR}" diff --git a/ic-os/scripts/ci-bless-version.sh b/ic-os/scripts/ci-bless-version.sh deleted file mode 100755 index 777dfb05c67..00000000000 --- a/ic-os/scripts/ci-bless-version.sh +++ /dev/null @@ -1,116 +0,0 @@ -#!/bin/bash - -set -e - -source $(dirname "${BASH_SOURCE[0]}")/artifact-utils.sh - -HTTP_PID= -HOST_IP_ADDR= - -LOG_NNS=$(mktemp) -LOG_UPGRADE=$(mktemp) -SUBNET_IDX=0 -SECOND_UPGRADE=0 - -set -x - -for argument in "${@}"; do - case ${argument} in - -d | --debug) - DEBUG=1 - ;; - -h | --help) - echo 'Usage: - -Arguments: - --origin-ip= specify IP address from which we expect requests - --nns-url= specify NNS URL - --upgrade-image= Build the image to upgrade - --ic-admin-bin= ic-admin binary path -' - exit 1 - ;; - --origin-ip=*) - ORIGIN_IP_ADDR="${argument#*=}" - # Perform a route lookup towards the given address (the IC node). - # This will yield the local address used in order to communicate - # with the IC nodes. This ensures that the address is usable as - # http endpoint address for the update fetching. - HOST_IP_ADDR=$(ip route get "${ORIGIN_IP_ADDR}" | sed -e 's/.*src \([^ ]*\).*/\1/' -e t -e d) - shift - ;; - --nns-url=*) - NNS_URL="${argument#*=}" - shift - ;; - --upgrade-image=*) - UPGRADE_IMAGE="${argument#*=}" - shift - ;; - --ic-admin-bin=*) - IC_ADMIN_BIN="${argument#*=}" - shift - ;; - *) - echo 'Error: Argument is not supported.' - exit 1 - ;; - esac -done - -[ -n "$HOST_IP_ADDR" ] || { - echo "Missing --origin-ip address, aborting" - exit 1 -} - -SCRIPT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" &>/dev/null && pwd)" -source "$SCRIPT_DIR/helpers.sh" - -echo "Assuming HTTP server serving upgrades is comming up at $HOST_IP_ADDR" - -SUBNET_URL="${SUBNET_URL:=$NNS_URL}" -SUBNET="${SUBNET:=0}" - -echo "➡️ Testing Registry call" -retry_command 5 "$IC_ADMIN_BIN" --nns-url "${NNS_URL}" get-subnet $SUBNET | grep "replica_version" - -echo "➡️ Starting HTTP server to serve upgrade $UPGRADE_IMAGE" -( - cd "$(dirname $UPGRADE_IMAGE)" - kill $(ss -plant | grep ':\<8000\>' | grep pid=[0-9]* -o | awk -F= '{ print $2 }') || true - python3 -m http.server 8000 --bind :: -) & -HTTP_PID=$! - -echo "➡️ Looking up version number for $UPGRADE_IMAGE" -VERSION=$(version_from_upgrade_image "${UPGRADE_IMAGE}") - -# Checks if the given IP contains any ":" characters that might be -# confused for the "port" separator. If that is the case, enclose -# the address using [] to disambiguate. -function quote_ip() { - echo "$1" | sed -e 's/\(.*:.*\)/[\1]/' -} - -echo "➡️ Bless upgrade $VERSION" -( - UPGRADE="$UPGRADE_IMAGE" - UPGRADE_IMAGE_NAME=$(basename "$UPGRADE_IMAGE") - UPGRADE_URL="http://$(quote_ip "${HOST_IP_ADDR}"):8000/${UPGRADE_IMAGE_NAME}" - - SHA256=$(sha256sum "$UPGRADE" | awk '{ print $1}') - echo "Checksum is: ${SHA256}" - echo -n "Checksum downloading via URL: " - curl "$UPGRADE_URL" | sha256sum || { - echo "Failed to download upgrade image, aborting" - exit 1 - } - - LOG_BLESSING=$(mktemp) - retry_command 5 $IC_ADMIN_BIN --nns-url $NNS_URL propose-to-bless-replica-version-flexible \ - --test-neuron-proposer $VERSION \ - $UPGRADE_URL $SHA256 2>&1 | tee "$LOG_BLESSING" -) - -echo "✅ Proposal success (for $VERSION) (time: $(date))" -exit 0 diff --git a/ic-os/scripts/ci-change-upgrade-version.sh b/ic-os/scripts/ci-change-upgrade-version.sh deleted file mode 100755 index d55263d9d5a..00000000000 --- a/ic-os/scripts/ci-change-upgrade-version.sh +++ /dev/null @@ -1,65 +0,0 @@ -#!/bin/bash - -set -e - -for argument in "${@}"; do - case ${argument} in - -d | --debug) - DEBUG=1 - ;; - -h | --help) - echo 'Usage: - -Arguments: - --upgrade-image= Build the image to upgrade - --out= Output file name of the modified upgrade image - --version= Version number to use in the upgrade, defaults to 42 -' - exit 1 - ;; - --upgrade-image=*) - UPGRADE_IMAGE="${argument#*=}" - shift - ;; - --out=*) - OUT="${argument#*=}" - shift - ;; - --version=*) - VERSION="${argument#*=}" - shift - ;; - *) - echo 'Error: Argument is not supported.' - exit 1 - ;; - esac -done - -echo "➡️ Preparing image to upgrade (version: $VERSION in: $UPGRADE_IMAGE out: $OUT)" -( - D=$(mktemp -d) - cd $D - tar -tf $UPGRADE_IMAGE - tar -xf $UPGRADE_IMAGE --sparse - - # Check current file number in image - echo "cat /opt/ic/share/version.txt" | debugfs root.img -f - - echo "${VERSION}" >version.txt - cat </dev/null && pwd)" -source "$SCRIPT_DIR/helpers.sh" - -echo "➡️ Testing Registry call" -retry_command 5 "$IC_ADMIN_BIN" --nns-url "${NNS_URL}" get-subnet $SUBNET | grep "replica_version" - -echo "➡️ Looking up version number in upgrade tar" -VERSION=$(version_from_upgrade_image "${UPGRADE_IMAGE}") - -echo "➡️ Upgrade subnetwork $SUBNET to $VERSION" -( - # Print state in the registry before we propose to updated. - # Do *NOT* fail the test if this goes wrong - $IC_ADMIN_BIN --nns-url=$NNS_URL get-replica-version $VERSION || true - $IC_ADMIN_BIN --nns-url=$NNS_URL get-subnet $SUBNET | grep replica_version || true - - retry_command 5 $IC_ADMIN_BIN --nns-url=$NNS_URL propose-to-update-subnet-replica-version \ - --test-neuron-proposer $SUBNET $VERSION | tee "$LOG_UPGRADE" - - sleep 5 - - # This is just a sanity check. Don't fail test if it fails. - $IC_ADMIN_BIN --nns-url=$NNS_URL get-subnet $SUBNET | grep replica_version || true - - rm "$LOG_UPGRADE" -) - -NUM=0 -echo "➡️ Waiting for version endpoint to change at: ${SUBNET_URL}/api/v2/status (takes up to 5 mins) " -date -echo -n "State: " -while ! curl -s ${SUBNET_URL}/api/v2/status --output - | egrep "impl_version..?$VERSION" -a; do - NUM=$(($NUM + 1)) - - if [[ $NUM -gt 200 ]]; then - echo "" - date - - echo "❌ Giving up" - - IPADDR=${SUBNET_URL/http:\/\/[/} - IPADDR=${IPADDR/]:8080/} - ssh -o StrictHostKeyChecking=no -o UserKnownHostsFile=/dev/null -o ServerAliveCountMax=3 -o ServerAliveInterval=1 -o PasswordAuthentication=false "root@${IPADDR}" "journalctl -u ic-replica -r" - - echo "Terminating" - exit 1 - - fi - - echo -n "." - sleep 5 -done - -echo "" -date -echo "✅ Upgrade success (to $VERSION)" - -exit 0 diff --git a/ic-os/scripts/control-subnet.sh b/ic-os/scripts/control-subnet.sh deleted file mode 100755 index cbf61e454c7..00000000000 --- a/ic-os/scripts/control-subnet.sh +++ /dev/null @@ -1,236 +0,0 @@ -#!/usr/bin/env bash - -set -o errexit -set -o pipefail - -SHELL="/bin/bash" -PATH="/sbin:/bin:/usr/sbin:/usr/bin" -BASE_DIR="$(dirname "${BASH_SOURCE[0]}")/.." - -TMP_DIR="$(mktemp -d)" - -# Set argument defaults -CREATE=0 - -# Get keyword arguments -for argument in "${@}"; do - case ${argument} in - c | cr | cre | crea | creat | create) - CREATE=1 - ;; - d=* | de=* | des=* | dest=* | destr=* | destro=* | destroy=*) - DESTROY="${argument#*=}" - shift - ;; - sta=* | star=* | start=*) - START="${argument#*=}" - shift - ;; - sto=* | stop=*) - STOP="${argument#*=}" - shift - ;; - -h | --help) - echo 'Usage: - - ____ _____ ___ _ _ ___ _______ __ - | _ \| ___|_ _| \ | |_ _|_ _\ \ / / - | | | | |_ | || \| || | | | \ V / - | |_| | _| | || |\ || | | | | | - |____/|_| |___|_| \_|___| |_| |_| - - Internet Computer Operating System - Control Subnet Deployment - -Commands: - create, cre create node - start=, sta= start node (Example: start=all|nns|app|"0,2,5,7,8") - stop=, sto= stop node (Example: stop=all|nns|app|"0,2,5,7,8") - destroy=, des= destroy node (Example: destroy=all|nns|app|"0,2,5,7,8") - -Arguments: - -d=, --disk= specify source of disk image (Default: ./build-out/disk.img) - -h, --help show this help message and exit - -i=, --input= JSON formatted input file (Default: ./subnet.json) - -m=, --media= specify source of removable media (Default: ./build-out/*.img) - -x, --debug enable verbose console output -' - exit 1 - ;; - -i=* | --input=*) - INPUT="${argument#*=}" - shift - ;; - -x | --debug) - DEBUG=1 - ;; - *) - echo 'Error: Argument is not supported.' - exit 1 - ;; - esac -done - -# Set arguments if undefined -DISK="${DISK:=${BASE_DIR}/disk.img}" -INPUT="${INPUT:=${BASE_DIR}/subnet.json}" -DESTROY="${DESTROY:=none}" -START="${START:=none}" -STOP="${STOP:=none}" - -# Load INPUT -CONFIG="$(cat ${INPUT})" - -DEPLOYMENT=$(echo ${CONFIG} | jq -r -c '.deployment') -MEDIA="${MEDIA:=${BASE_DIR}/build-out/${DEPLOYMENT}-*.img}" - -CORES=$(echo ${CONFIG} | jq -r -c '.resources.cores') -MEMORY_GB=$(echo ${CONFIG} | jq -r -c '.resources.memory_gb') -DISK_GB=$(echo ${CONFIG} | jq -r -c '.resources.disk_gb') -IPV4_BRIDGE=$(echo ${CONFIG} | jq -r -c '.resources.ipv4_bridge') - -all_nodes() { - # Query all nodes in subnet - echo ${CONFIG} | jq -c '.datacenters[]' | while read datacenters; do - echo ${datacenters} | jq -c '.hosts[]' | while read hosts; do - echo ${hosts} | jq -c '.nodes[]' | while read nodes; do - ALL_DC=$(echo ${nodes} | jq -r '.id' | while read node; do - echo "${node}" - done) - echo ${ALL_DC} >>"${TMP_DIR}/ALL" - done - done - done - ALL="$(cat ${TMP_DIR}/ALL)" - rm -f "${TMP_DIR}/ALL)" - echo "$(echo ${ALL[@]})" -} - -nns_nodes() { - # Query all NNS nodes in subnet - echo ${CONFIG} | jq -c '.datacenters[]' | while read datacenters; do - echo ${datacenters} | jq -c '.hosts[]' | while read hosts; do - echo ${hosts} | jq -c '.nodes[]' | while read nodes; do - NNS_DC=$(echo ${nodes} | jq -c 'select(.type|test("nns"))' | while read node; do - echo "$(echo ${node} | jq -r '.id')" - done) - echo "${NNS_DC}" >>"${TMP_DIR}/NNS" - done - done - done - NNS="$(cat ${TMP_DIR}/NNS)" - rm -f "${TMP_DIR}/NNS)" - echo "$(echo ${NNS[@]})" -} - -app_nodes() { - # Query all APP nodes in subnet - echo ${CONFIG} | jq -c '.datacenters[]' | while read datacenters; do - echo ${datacenters} | jq -c '.hosts[]' | while read hosts; do - echo ${hosts} | jq -c '.nodes[]' | while read nodes; do - APP_DC=$(echo ${nodes} | jq -c 'select(.type|test("app"))' | while read node; do - echo "$(echo ${node} | jq -r '.id')" - done) - echo "${APP_DC}" >>"${TMP_DIR}/APP" - done - done - done - APP="$(cat ${TMP_DIR}/APP)" - rm -f "${TMP_DIR}/APP)" - echo "$(echo ${APP[@]})" -} - -custom_nodes() { - nodes=${1} - - echo "$(echo ${nodes})" -} - -get_host() { - node=${1} - - echo ${CONFIG} | jq -c '.datacenters[]' | while read datacenters; do - echo ${datacenters} | jq -c '.hosts[]' | while read hosts; do - echo ${hosts} | jq -c "{host: .serial, id: .nodes[].id} | select(.id == \"${node}\")" | while read nodes; do - echo ${nodes} | jq -r '.host' - done - done - done -} - -get_all_hosts() { - echo ${CONFIG} | jq -c '.datacenters[]' | while read datacenters; do - echo ${datacenters} | jq -c '.hosts[]' | while read hosts; do - echo ${hosts} | jq -r '.serial' - done - done -} - -validate_input() { - input=${1} - - if [ "${input}" == "all" ]; then - VALIDATED_INPUT="$(all_nodes)" - elif [ "${input}" == "nns" ]; then - VALIDATED_INPUT="$(nns_nodes)" - elif [ "${input}" == "app" ]; then - VALIDATED_INPUT="$(app_nodes)" - else - VALIDATED_INPUT="$(custom_nodes ${input})" - fi -} - -create_node() { - for host in $(get_all_hosts); do - rsync --archive --compress --verbose --rsh="ssh -o StrictHostKeyChecking=no" --rsync-path='sudo rsync' ${DISK} ${host}:/home/ic/ - rsync --archive --compress --verbose --rsh="ssh -o StrictHostKeyChecking=no" --rsync-path='sudo rsync' ${MEDIA} ${host}:/home/ic/ - ssh -o StrictHostKeyChecking=no -t ${host} "sudo -i -u ic sh -c \"export 'ANSIBLE_CONFIG=~/ansible/testnet.cfg' ; ansible-playbook ~/ansible/testnet.yml -e ic_deployment='testnet' --tags=ic_guest -e ic_cores=${CORES} -e ic_memory_gb=${MEMORY_GB} -e ic_disk_gb=${DISK_GB} -e ic_ipv4_bridge=${IPV4_BRIDGE} -e ic_state='create'\"" - done -} - -destroy_node() { - for node in ${VALIDATED_INPUT//,/ }; do - ssh -o StrictHostKeyChecking=no -t $(get_host ${node}) "sudo -i sh -c \"virsh destroy ${DEPLOYMENT}-$(get_host ${node})-${node} ; true\"" - ssh -o StrictHostKeyChecking=no -t $(get_host ${node}) "sudo -i sh -c \"virsh undefine ${DEPLOYMENT}-$(get_host ${node})-${node} --nvram ; true\"" - ssh -o StrictHostKeyChecking=no -t $(get_host ${node}) "sudo -i sh -c \"virsh vol-delete /var/lib/libvirt/images/${DEPLOYMENT}-$(get_host ${node})-${node}.img\" ; true" - ssh -o StrictHostKeyChecking=no -t $(get_host ${node}) "sudo -i sh -c \"rm -f /var/lib/libvirt/media/${DEPLOYMENT}-$(get_host ${node})-${node}.img\"" - done -} - -start_node() { - for node in ${VALIDATED_INPUT//,/ }; do - ssh -o StrictHostKeyChecking=no -t $(get_host ${node}) "sudo -i sh -c \"virsh start ${DEPLOYMENT}-$(get_host ${node})-${node} ; true\"" - done -} - -stop_node() { - for node in ${VALIDATED_INPUT//,/ }; do - ssh -o StrictHostKeyChecking=no -t $(get_host ${node}) "sudo -i sh -c \"virsh destroy ${DEPLOYMENT}-$(get_host ${node})-${node} ; true\"" - done -} - -function remove_temporary_directory() { - rm -rf ${TMP_DIR} -} - -# See how we were called -if [ "${DESTROY}" != "none" ]; then - validate_input "${DESTROY}" - destroy_node "${VALIDATED_INPUT}" - remove_temporary_directory -elif [ "${START}" != "none" ]; then - validate_input "${START}" - start_node "${VALIDATED_INPUT}" - remove_temporary_directory -elif [ "${STOP}" != "none" ]; then - validate_input "${STOP}" - stop_node "${VALIDATED_INPUT}" - remove_temporary_directory -elif [ "${CREATE}" -eq 1 ]; then - validate_input "${CREATE}" - create_node "${VALIDATED_INPUT}" - remove_temporary_directory -else - echo 'Please specify at least one node. Example: - command=all|nns|app|"0,2,6,7,8"' -fi diff --git a/ic-os/scripts/docker_extract.py b/ic-os/scripts/docker_extract.py deleted file mode 100755 index bec186ad1df..00000000000 --- a/ic-os/scripts/docker_extract.py +++ /dev/null @@ -1,80 +0,0 @@ -#!/usr/bin/env python3 -import io -import json -import os -import shutil -import sys -import tarfile - - -def read_tar_contents(buffer): - """Read tar file as map from filename -> content.""" - with tarfile.open(fileobj=buffer, mode="r|*") as tf: - - filemap = {} - for member in tf: - buf = member.tobuf() # noqa - no idea why buf is here - if member.type == tarfile.REGTYPE: - filemap[member.name] = tf.extractfile(member).read() - elif (member.type == tarfile.LNKTYPE) or (member.type == tarfile.SYMTYPE): - filemap[member.name] = member.linkname[3:] - return filemap - - -def get_layer_data(filemap): - """Get the docker layer data from the filemap in correct order.""" - manifest = json.loads(filemap["manifest.json"]) - layers = manifest[0]["Layers"] - - out = [] - for layer in layers: - if isinstance(filemap[layer], str): - out.append(filemap[filemap[layer]]) - else: - out.append(filemap[layer]) - - return tuple(out) - - -target_dir = sys.argv[1] - -filemap = read_tar_contents(sys.stdin.buffer) -layers = get_layer_data(filemap) - -for layer in layers: - tf = tarfile.open(fileobj=io.BytesIO(layer), mode="r") - - # Process all members in the tarfile. They are either ordinary - # dirs/files/symlinks to be extracted, or they are "white-out" files: - # These direct to delete certain underlying files from previous layer. - for member in tf: - basename = os.path.basename(member.path) - dirname = os.path.dirname(member.path) - if basename.startswith(".wh."): - # This is a whiteout. Delete the file / directory. - basename_target = basename[4:] - target = os.path.join(target_dir, dirname, basename_target) - if os.path.isdir(target): - shutil.rmtree(target) - elif os.path.exists(target): - os.unlink(target) - else: - # Object to be created. Make sure that a previously existing - # object is removed. This is important because the python tarfile - # "extractall" method fails to overwrite symbolic links with - # new links. - target = os.path.join(target_dir, member.path) - if os.path.lexists(target): - if os.path.islink(target): - os.unlink(target) - else: - was_dir = os.path.isdir(target) - should_be_dir = member.isdir() - if was_dir: - if not should_be_dir: - shutil.rmtree(target) - else: - if should_be_dir: - os.unlink(target) - tf.extract(member, target_dir, numeric_owner=True) - os.utime(target, (0, 0), follow_symlinks=False) diff --git a/ic-os/scripts/fetch-dfinity-binaries.sh b/ic-os/scripts/fetch-dfinity-binaries.sh deleted file mode 100755 index 33b8f961d30..00000000000 --- a/ic-os/scripts/fetch-dfinity-binaries.sh +++ /dev/null @@ -1,53 +0,0 @@ -#!/usr/bin/env bash - -REPO_ROOT=$(git rev-parse --show-toplevel) - -function error() { - echo "$1" - exit 1 -} - -if [[ -z "${GIT_REV:-}" ]]; then - echo "Please provide the GIT_REV as env. variable or the command line with --git-rev=" - exit 1 -fi - -function get_dfinity_binaries() { - - if [[ -n "$NNS_REPLICA" ]]; then - - echo "Downloading replica binary from NNS machine" - ic_version="0.8.0" - REPLICA_PATH="/var/lib/dfinity-node/replica_binaries/$ic_version/replica" - REPLICA_TARGET="rootfs/opt/ic/bin/replica" - REPLICA_DIR=$(dirname "$REPLICA_TARGET") - mkdir -p "$REPLICA_DIR" - - rsync --rsync-path="sudo rsync" "${NNS_REPLICA}:${REPLICA_PATH}" "$REPLICA_TARGET" - chmod a+x "$REPLICA_TARGET" - sha256sum "$REPLICA_TARGET" - - ORCHESTRATOR_PATH="/var/lib/dfinity-node/replica_binaries/$ic_version/orchestrator" - ORCHESTRATOR_TARGET="rootfs/opt/ic/bin/orchestrator" - ORCHESTRATOR_DIR=$(dirname "$ORCHESTRATOR_TARGET") - mkdir -p "$ORCHESTRATOR_DIR" - - rsync --rsync-path="sudo rsync" "${NNS_REPLICA}:${ORCHESTRATOR_PATH}" "$ORCHESTRATOR_TARGET" - chmod a+x "$ORCHESTRATOR_TARGET" - sha256sum "$ORCHESTRATOR_TARGET" - - else - echo "Downloading replica and orchestrator binaries" - - TARGET_DIR="$REPO_ROOT/ic-os/guestos/rootfs/opt/ic/bin" - - "${REPO_ROOT}"/gitlab-ci/src/artifacts/rclone_download.py \ - --git-rev "$GIT_REVISION" --remote-path=release --out="$TARGET_DIR" \ - --include "{replica,orchestrator}.gz" - - for f in replica orchestrator; do - gunzip -f "$TARGET_DIR/$f" - chmod +x "$TARGET_DIR/$f" - done - fi -} diff --git a/ic-os/scripts/fetch-nns-canisters.sh b/ic-os/scripts/fetch-nns-canisters.sh deleted file mode 100755 index 6f2a4ee6fa6..00000000000 --- a/ic-os/scripts/fetch-nns-canisters.sh +++ /dev/null @@ -1,24 +0,0 @@ -#!/usr/bin/env bash - -function error() { - echo $1 - exit 1 -} - -TMPDIR=$1 -GIT_REV=$(git rev-parse --verify master) -REPO_ROOT=$(git rev-parse --show-toplevel) - -[[ -d "$TMPDIR" ]] || error "Please specify temporary directory as first argument" - -function download_registry_canisters() { - "${REPO_ROOT}"/gitlab-ci/src/artifacts/rclone_download.py \ - --git-rev "$GIT_REVISION" --remote-path=release --out="$TMPDIR" \ - --include="{replica,orchestrator}.gz" - - for f in "${IC_PREP_DIR}"/*.gz; do - gunzip -f "$f" - done -} - -download_registry_canisters diff --git a/ic-os/scripts/get-artifact-version.sh b/ic-os/scripts/get-artifact-version.sh deleted file mode 100755 index cd5d6f7f717..00000000000 --- a/ic-os/scripts/get-artifact-version.sh +++ /dev/null @@ -1,30 +0,0 @@ -#!/usr/bin/env bash - -set -eo pipefail - -source $(dirname "${BASH_SOURCE[0]}")/artifact-utils.sh - -INPUT_FILE="$2" - -function usage() { - cat </dev/null || error "Could not reach replica to install NNS no" - -# We are deploying the NNS subnetwork -SUBNET_IDX=0 - -download_binaries - -download_registry_canisters - -#echo "Ensuring NNS is not yet installed" -#($TMPDIR/ic-admin --nns-url $NNS_URL get-subnet 0 2>&1 | grep "Canister rwlgt-iiaaa-aaaaa-aaaaa-cai not found" ) || error "NNS is already installed, aborting" - -echo "Installing NNS" -time $TMPDIR/ic-nns-init \ - --url $NNS_URL \ - --registry-local-store-dir $TMPDIR/ic_registry_local_store \ - --wasm-dir "$TMPDIR/canisters" - -echo "Test NNS is installed" -$TMPDIR/ic-admin --nns-url $NNS_URL get-subnet 0 diff --git a/ic-os/scripts/partitions.sh b/ic-os/scripts/partitions.sh deleted file mode 100755 index 8e218ec5b72..00000000000 --- a/ic-os/scripts/partitions.sh +++ /dev/null @@ -1,333 +0,0 @@ -# Tools for dealing with the partition table (defined in partitions.csv) -# and disk image building. -# -# NOTE: When sourcing, be sure to specify CSV dir, or "", otherwise, arguments -# to the parent script will be passed. -# -# Arguments: -# $1: The folder containing layout CSVs. - -if [ "$1" != "" ]; then - CSV_DIR="$1" -else - BASE_DIR=$(dirname "${BASH_SOURCE[0]}")/.. - CSV_DIR="${BASE_DIR}"/build -fi - -function prepare_disk_image() { - local DISK_IMAGE="$1" - local IMAGE_SIZE_BYTES="$2" - - truncate --size 0 "$DISK_IMAGE" - truncate --size "$IMAGE_SIZE_BYTES" "$DISK_IMAGE" - - generate_sfdisk_script | sfdisk "$DISK_IMAGE" -} - -# Clear any existing LVM mounts. -function clear_lvm_mounts() { - local OPEN_LVM=$(losetup -O BACK-FILE,NAME | grep lvm.img | tr -s ' ' | cut -d ' ' -f 2) - for LOOP in $OPEN_LVM; do - losetup -d $LOOP - done -} - -# Prepare an LVM PV with LVs set up as specified. -# -# Arguments: -# $1: The file where to generate the LVM PV in. -# $2: The size of the target file. -# $3: The name of the VG to create. -# $4: The UUID of the desired VG. -# $5: The UUID of the desired PV. -function prepare_lvm_image() { - local DISK_IMAGE="$1" - local IMAGE_SIZE_BYTES="$2" - local VOLUME_GROUP="$3" - local VG_UUID="$4" - local PV_UUID="$5" - - truncate --size 0 "$DISK_IMAGE" - truncate --size "$IMAGE_SIZE_BYTES" "$DISK_IMAGE" - - LOOP_NAME=$(losetup -P -f --show "$DISK_IMAGE") - trap "losetup -d $LOOP_NAME" EXIT - - pvcreate -f "$LOOP_NAME" -u "$PV_UUID" --norestorefile - - create_lvm_volumes "$VOLUME_GROUP" "$VG_UUID" "$PV_UUID" "$IMAGE_SIZE_BYTES" -} - -# Write a single partition image into a specific partition of the -# disk image. -# -# Arguments: -# $1: The disk image to write into. -# $2: The name of the partition that should be written. -# $3: The file with the contents of the partition to be written. -function write_single_partition() { - local DISK_IMAGE="$1" - local PART_NAME="$2" - local PART_IMAGE="$3" - - local FILE_SIZE=$(stat -c "%s" "$PART_IMAGE") - - local PART_START=${PARTITION_START_BY_NAME["$PART_NAME"]} - local PART_SIZE=${PARTITION_SIZE_BY_NAME["$PART_NAME"]} - local PART_SIZE_BYTES=$(("$PART_SIZE" * 512)) - - if [ "$FILE_SIZE" -gt "$PART_SIZE_BYTES" ]; then exit 1; fi - - dd if="$PART_IMAGE" of="$DISK_IMAGE" bs=512 seek="$PART_START" conv=sparse,notrunc -} - -# Write a single partition image into a specific volume of the -# lvm vg. -# -# Arguments: -# $1: The disk image to be read from. -# $2: The volume group to be read from. -# $3: The name of the volume that should be read. -# $4: The file to which the volume contents should be. -function write_single_lvm_volume() { - local DISK_IMAGE="$1" - local VOLUME_GROUP="$2" - local PART_NAME="$3" - local PART_IMAGE="$4" - - local FILE_SIZE=$(stat -c "%s" "$PART_IMAGE") - - local PART_SIZE=${VOLUME_SIZE_BY_NAME["$PART_NAME"]} - local PART_SIZE_BYTES=$(("$PART_SIZE" * 4194304)) - - local PART_OFFSET=$((${PARTITION_START_BY_NAME["$VOLUME_GROUP"]} * 512)) - local LVM_OFFSET=$((2048 * 512)) - local VOLUME_OFFSET=$((${VOLUME_START_BY_NAME["$PART_NAME"]} * 4194304)) - - local OFFSET=$((${PART_OFFSET} + ${LVM_OFFSET} + ${VOLUME_OFFSET})) - local OFFSET_BLOCKS=$((${OFFSET} / 4096)) - - if [ "$FILE_SIZE" -gt "$PART_SIZE_BYTES" ]; then exit 1; fi - - dd if="$PART_IMAGE" of="$DISK_IMAGE" bs=4096 seek="$OFFSET_BLOCKS" conv=sparse,notrunc -} - -# Extracts a single partition image from a disk image to a file. -# -# Arguments: -# $1: The disk image to be read from. -# $2: The name of the partition that should be read. -# $3: The file to which the partition contents should be. -function extract_single_partition() { - local DISK_IMAGE="$1" - local PART_NAME="$2" - local PART_IMAGE="$3" - - local PART_START=$((${PARTITION_START_BY_NAME["$PART_NAME"]} / 8)) - local PART_SIZE=$((${PARTITION_SIZE_BY_NAME["$PART_NAME"]} / 8)) - - dd if="$DISK_IMAGE" of="$PART_IMAGE" bs=4096 skip="$PART_START" count="$PART_SIZE" conv=sparse -} - -# Extracts a single volume from a disk image to a file. -# -# Arguments: -# $1: The disk image to be read from. -# $2: The volume group to be read from. -# $3: The name of the volume that should be read. -# $4: The file to which the volume contents should be. -function extract_single_volume() { - local DISK_IMAGE="$1" - local VOLUME_GROUP="$2" - local PART_NAME="$3" - local PART_IMAGE="$4" - - local PART_SIZE=$((${VOLUME_SIZE_BY_NAME["$PART_NAME"]} * 1024)) - - local PART_OFFSET=$((${PARTITION_START_BY_NAME["$VOLUME_GROUP"]} * 512)) - local LVM_OFFSET=$((2048 * 512)) - local VOLUME_OFFSET=$((${VOLUME_START_BY_NAME["$PART_NAME"]} * 4194304)) - - local OFFSET=$((${PART_OFFSET} + ${LVM_OFFSET} + ${VOLUME_OFFSET})) - local OFFSET_BLOCKS=$((${OFFSET} / 4096)) - - dd if="$DISK_IMAGE" of="$PART_IMAGE" bs=4096 skip="$OFFSET_BLOCKS" count="$PART_SIZE" conv=sparse -} - -# All of the below are helper functions -- should not be used directly. - -# Read partitions.csv in "canonical form" (i.e. remove all comments, -# strip whitespace from fields). -# Internal utility function. -function read_canonical_partitions_csv() { - sed -e '/^#/d' -e 's/ *, */,/g' <"${CSV_DIR}"/partitions.csv -} - -# Read volumes.csv in "canonical form" (i.e. remove all comments, -# strip whitespace from fields). -# Internal utility function. -function read_canonical_volumes_csv() { - sed -e '/^#/d' -e 's/ *, */,/g' <"${CSV_DIR}"/volumes.csv -} - -# Produce an sfdisk script as output to set up the partition table -function generate_sfdisk_script() { - echo "label: gpt" - echo "label-id: 2B110BB7-CDEC-7D41-B97E-893EDCBE5428" - read_canonical_partitions_csv \ - | while IFS=, read -r name start size type uuid comment; do - if [ "$type" == "L" ]; then - type=0FC63DAF-8483-4772-8E79-3D69D8477DE4 - elif [ "$type" == "U" ]; then - type=C12A7328-F81F-11D2-BA4B-00A0C93EC93B - fi - echo start=$start,size=$size,type=$type,uuid=$uuid - done -} - -# Build out LVM volumes for each partition defined in partitions CSV -function create_lvm_volumes() { - local VOLUME_GROUP="$1" - local VG_UUID="$2" - local PV_UUID="$3" - local SIZE="$4" - - local DEV_SIZE=$(("$SIZE" / 512)) - local PE_COUNT=$((("$DEV_SIZE" / 8192) - 1)) - - local out=backup - - # Create the header - cat >>$out <>$out <>$out <>$out <>$out <>$out <"$LOG_BOOT" - -echo "➡️ Preparing image to upgrade to (log at: $LOG_UPGRADE)" -( - "${BASE_DIR}"/scripts/build-ubuntu.sh -o /tmp/upgrade-image.tar - OUT=$(mktemp -d) - ( - cd $OUT - ls -anh /tmp/upgrade-image.tar - tar -tf /tmp/upgrade-image.tar - tar -xf /tmp/upgrade-image.tar - # Check current file number in image - echo "cat /opt/ic/share/version.txt" | debugfs root.img -f - - - echo "42" >version.txt - cat <"$LOG_UPGRADE" - -echo "➡️ Starting HTTP server for upgrading" -( - cd /tmp - killall --user $(whoami) python3 || true - python3 -m http.server 8000 --bind :: -) & -HTTP_PID=$! - -# Make sure HTTP server comes up. -# Not sure if we still need this. -sleep 10 -ss -plant | grep ':\<8000\>' - -echo "➡️ Booting image (log at: $LOG_QEMU)" -echo " SSH access: sshpass -p 'root' ssh root@::1 -p 22222 -o StrictHostKeyChecking=false -o UserKnownHostsFile=/dev/null" -echo " Log output: sshpass -p 'root' ssh root@::1 -p 22222 -o StrictHostKeyChecking=false -o UserKnownHostsFile=/dev/null journalctl -u dfinity -r" -( - qemu-system-x86_64 \ - -display none \ - -serial mon:stdio \ - -machine type=q35,accel=kvm \ - -enable-kvm \ - -m 2G \ - -bios /usr/share/OVMF/OVMF_CODE.fd \ - -device virtio-blk-pci,drive=drive0,addr=2.0 \ - -drive file=/tmp/disk.img,format=raw,id=drive0,if=none \ - \ - -device pcie-root-port,id=pcie.1,chassis=1 \ - -netdev user,id=enp1s0,hostfwd=tcp::${LOCAL_HTTP_PORT}-:8080,hostfwd=tcp::22222-:22 \ - -device virtio-net-pci,netdev=enp1s0,bus=pcie.1 \ - \ - -device qemu-xhci \ - -device usb-storage,drive=removable,removable=true \ - -drive file=vm.img,format=raw,id=removable,if=none -) &>"$LOG_QEMU" & -QEMU_PID=$! - -NUM=0 -echo -n "➡️ Waiting for HTTP server to come up " -while ! curl -s http://[::1]:${LOCAL_HTTP_PORT}; do - NUM=$(($NUM + 1)) - echo -n "." - - if [[ $NUM -gt 100 ]]; then - terminate - fi - - sleep 5 -done -echo "" -echo "Replica is up" - -echo "➡️ Installing NNS" -( - "${BASE_DIR}"/scripts/install-nns.sh "$TMPDIR" "http://[::1]:${LOCAL_HTTP_PORT}" -) &>"$LOG_NNS" - -echo "➡️ Testing Registry call" -"$TMPDIR"/ic-admin --nns-url http://[::1]:${LOCAL_HTTP_PORT} get-subnet 0 | grep "replica_version" - -echo "➡️ Triggering upgrade" -( - "${BASE_DIR}"/upgrade.sh \ - --nns-url=http://[::1]:${LOCAL_HTTP_PORT} \ - --upgrade-url=http://${HOST_IP_ADDR}:8000/upgrade-image.tar \ - --upgrade-image=/tmp/upgrade-image.tar \ - --version=42 -) 2>&1 | tee -a "$LOG_NNS" >/dev/null - -NUM=0 -echo -n "➡️ Waiting for Upgrade " -while ! grep "Restarting system" "$LOG_QEMU" &>/dev/null; do - NUM=$(($NUM + 1)) - echo -n "." - - if [[ $NUM -gt 100 ]]; then - terminate - fi - - sleep 5 -done -echo "" - -sleep 15 -grep "Welcome.*Ubuntu" "$LOG_QEMU" - -NUM=0 -echo "➡️ Waiting for version endpoint to change " -while ! curl -s http://[::1]:${LOCAL_HTTP_PORT}/api/v2/status --output - | grep -o "impl_version.[0-9]*" -a; do - NUM=$(($NUM + 1)) - - if [[ $NUM -gt 20 ]]; then - terminate - fi - - sleep 5 -done - -echo "✅ All done - shutting down" -terminate diff --git a/ic-os/setupos/Makefile b/ic-os/setupos/Makefile deleted file mode 100755 index 59ecb974719..00000000000 --- a/ic-os/setupos/Makefile +++ /dev/null @@ -1,8 +0,0 @@ -help: - @grep -E '^[a-zA-Z_-]+:.*?## .*$$' $(MAKEFILE_LIST) | sort | awk 'BEGIN {FS = ":.*?## "}; {printf "\033[36m%-30s\033[0m %s\n", $$1, $$2}' - -deps: ## Install build dependencies - sudo apt -y install ca-certificates curl git isolinux p7zip-full syslinux xorriso --no-install-recommends - -iso: ## Build SetupOS ISO image - ./scripts/build-iso.sh diff --git a/ic-os/setupos/README.md b/ic-os/setupos/README.md deleted file mode 100644 index e51c75fecdb..00000000000 --- a/ic-os/setupos/README.md +++ /dev/null @@ -1,79 +0,0 @@ -# Setup OS - -## Index - -* [About](#about) - * [Features](#features) -* [Build](#build) - * [Dependencies](#dependencies) -* [Usage](#usage) - * [ISO](#iso) - * [MaaS](#maas) -* [FAQ](#faq) -* [Appendix](#appendix) - -## About - -This folder holds all files to build the SetupOS ISO and MaaS image. - -### Features - -* Set firmware versions -* Apply UEFI configuration -* Purge existing partitions -* Create new partitions -* Install HostOS disk-image -* Install GuestOS disk-image -* Handle HSM and USB devices - -## Build - -### Dependencies - -To build the Ubuntu Server 20.04 LTS based images, the following dependencies -have to be met. Please note that the script currently only supports Ubuntu -Linux. - -* Operating System: Ubuntu 20.04.3 -* Packages: `ca-certificates`, `curl`, `git`, `isolinux`, `p7zip-full`, - `syslinux`, `xorriso` -* Connectivity: 443/tcp outbound - -## Usage - -Executing the Bash scripts in the _scripts_ folder, is enough to get the build -process started. - -### ISO - -Command to build the ISO image: -``` -./scripts/build-iso.sh -``` - -Once the build process has finished successfully, the SetupOS ISO image can be -found in the _./build-out/_ folder. - -For help and listing the available options, simply append the _--help_ flag: -``` -./scripts/build-iso.sh --help -``` - -### MaaS - -Command to build the MaaS image: -``` -./scripts/build-maas.sh -``` - -Once the build process has finished successfully, the SetupOS MaaS images can be -found in the _./build-out/_ folder. - -For help and listing the available options, simply append the _--help_ flag: -``` -./scripts/build-maas.sh --help -``` - -## FAQ - -## Appendix diff --git a/ic-os/setupos/scripts/build-iso.sh b/ic-os/setupos/scripts/build-iso.sh deleted file mode 100755 index e912eea4cac..00000000000 --- a/ic-os/setupos/scripts/build-iso.sh +++ /dev/null @@ -1,386 +0,0 @@ -#!/usr/bin/env bash - -# Build Ubuntu Server based ISO image containing setup files - -# Build Requirements: -# - Operating System: Ubuntu 20.04 -# - Packages: ca-certificates, curl, git, isolinux, p7zip-full, syslinux, xorriso -# - Connectivity: 443/tcp outbound - -set -o errexit -set -o pipefail -# NOTE: Validating inputs manually -#set -o nounset - -SHELL="/bin/bash" -PATH="/sbin:/bin:/usr/sbin:/usr/bin" - -BASE_DIR="$(dirname "${BASH_SOURCE[0]}")/.." -TMP_DIR="$(mktemp -d)" -ISO_DIR="${TMP_DIR}/iso" - -UBUNTU_VERSION="20.04.4" -UBUNTU_ISO="ubuntu-${UBUNTU_VERSION}-live-server-amd64.iso" -UBUNTU_URL="https://releases.ubuntu.com/${UBUNTU_VERSION}/${UBUNTU_ISO}" -UBUNTU_CHECKSUM="28ccdb56450e643bad03bb7bcf7507ce3d8d90e8bf09e38f6bd9ac298a98eaad" - -EFIBOOTMGR_URL="http://archive.ubuntu.com/ubuntu/pool/main/e/efibootmgr/efibootmgr_17-1_amd64.deb" -EFIBOOTMGR_CHECKSUM="0da33e43c97e5505d4d54e4145a72e76ce72278c3a9488792da86d9f30709d73" - -JQ_URL="http://archive.ubuntu.com/ubuntu/pool/universe/j/jq/jq_1.6-1ubuntu0.20.04.1_amd64.deb" -JQ_CHECKSUM="8e4c8223f6ec158dc6c2a0d065b76c337bb7664e35cbbecd2ad02142d3b83470" - -LIBJQ1_URL="http://archive.ubuntu.com/ubuntu/pool/universe/j/jq/libjq1_1.6-1ubuntu0.20.04.1_amd64.deb" -LIBJQ1_CHECKSUM="5aafb335442d3a694b28204e390c831de9efc3f3a18245328840d406edc8a163" - -LIBONIG5_URL="http://archive.ubuntu.com/ubuntu/pool/universe/libo/libonig/libonig5_6.9.4-1_amd64.deb" -LIBONIG5_CHECKSUM="041f5fb2dc781fcd1bcdc5a4115108a3ecca770c1cab69d5f25aafffe7842cf5" - -# Fixed timestamp for reproducible build -TOUCH_TIMESTAMP="200901031815.05" -XORRISO_TIMESTAMP="2009010318150500" -export SOURCE_DATE_EPOCH="1231006505" - -# Get keyword arguments -for argument in "${@}"; do - case ${argument} in - -c=* | --config=*) - CONFIG="${argument#*=}" - shift - ;; - -d=* | --deployment=*) - DEPLOYMENT="${argument#*=}" - shift - ;; - -h | --help) - echo 'Usage: -SetupOS Builder - -Arguments: - -c=, --config= specify the config.json configuration file (Default: ./src/nocloud/config.json) - -d=, --deployment= specify the deployment name (Default: mainnet) - --host-os= specify the HostOS disk-image file (Default: ./src/nocloud/host-os.img.tar.gz) - --host-ssh= specify a folder containing the accounts SSH public keys (Example: ./ssh_authorized_keys) - the folder is expected to contain files named after the built-in accounts (admin, backup, readonly) - --guest-os= specify the GuestOS disk-image file (Default: ./src/nocloud/guest-os.img.tar.gz) - --guest-ssh= specify a folder containing the accounts SSH public keys (Example: ./ssh_authorized_keys) - the folder is expected to contain files named after the built-in accounts (admin, backup, readonly) - -h, --help show this help message and exit - -k=, --key= specify the NNS public key (Default: ./src/nocloud/nns_public_key.pem) - -l=, --logging= specify the logging hosts/destination (Default: telemetry01.mainnet.dfinity.network telemetry02.mainnet.dfinity.network telemetry03.mainnet.dfinity.network) - -n=, --nns-url= specify the NNS URL for the GuestOS (Default: ) - -o=, --output= ISO output directory (Default: ./build-out/) - -u=, --ubuntu= specify a folder containing the Ubuntu Live Server ISO image (Example: ./ubuntu/) - --memory= specify the amount of memory in GiB (Gibibytes) for the GuestOS (Default: 490) -' - exit 1 - ;; - --host-os=*) - HOST_OS="${argument#*=}" - shift - ;; - --host-ssh=*) - HOST_SSH="${argument#*=}" - shift - ;; - --guest-os=*) - GUEST_OS="${argument#*=}" - shift - ;; - --guest-ssh=*) - GUEST_SSH="${argument#*=}" - shift - ;; - -k=* | --key=*) - KEY="${argument#*=}" - shift - ;; - -l=* | --logging=*) - LOGGING="${argument#*=}" - shift - ;; - -n=* | --nns-url=*) - NNS_URL="${argument#*=}" - shift - ;; - -o=* | --output=*) - OUTPUT="${argument#*=}" - shift - ;; - -u=* | --ubuntu=*) - UBUNTU="${argument#*=}" - shift - ;; - --memory=*) - MEMORY="${argument#*=}" - shift - ;; - *) - echo "Error: Argument is not supported: ${argument#*=}" - exit 1 - ;; - esac -done - -# Set arguments if undefined -CONFIG="${CONFIG:=${BASE_DIR}/src/nocloud/config.json}" -DEPLOYMENT="${DEPLOYMENT:=mainnet}" -HOST_OS="${HOST_OS:=${BASE_DIR}/src/nocloud/host-os.img.tar.gz}" -GUEST_OS="${GUEST_OS:=${BASE_DIR}/src/nocloud/guest-os.img.tar.gz}" -KEY="${KEY:=${BASE_DIR}/src/nocloud/nns_public_key.pem}" -LOGGING="${LOGGING:=elasticsearch-node-0.mercury.dfinity.systems:443 elasticsearch-node-1.mercury.dfinity.systems:443 elasticsearch-node-2.mercury.dfinity.systems:443 elasticsearch-node-3.mercury.dfinity.systems:443}" -MEMORY="${MEMORY:=490}" -NNS_URL="${NNS_URL:=http://[2600:c02:b002:15:5000:ceff:fecc:d5cd]:8080,http://[2604:3fc0:3002:0:5000:6bff:feb9:6baf]:8080,http://[2a00:fb01:400:100:5000:5bff:fe6b:75c6]:8080,http://[2604:3fc0:2001:0:5000:b0ff:fe7b:ff55]:8080,http://[2600:3000:6100:200:5000:cbff:fe4b:b207]:8080,http://[2604:3fc0:3002:0:5000:4eff:fec2:4806]:8080,http://[2001:920:401a:1708:5000:5fff:fec1:9ddb]:8080,http://[2001:920:401a:1706:5000:87ff:fe11:a9a0]:8080,http://[2401:3f00:1000:24:5000:deff:fed6:1d7]:8080,http://[2a00:fb01:400:100:5000:61ff:fe2c:14ac]:8080,http://[2a04:9dc0:0:108:5000:ccff:feb7:c03b]:8080,http://[2600:c02:b002:15:5000:53ff:fef7:d3c0]:8080,http://[2401:3f00:1000:22:5000:c3ff:fe44:36f4]:8080,http://[2607:f1d0:10:1:5000:a7ff:fe91:44e]:8080,http://[2a04:9dc0:0:108:5000:96ff:fe4a:be10]:8080,http://[2604:7e00:50:0:5000:20ff:fea7:efee]:8080,http://[2600:3004:1200:1200:5000:59ff:fe54:4c4b]:8080,http://[2a0f:cd00:2:1:5000:3fff:fe36:cab8]:8080,http://[2401:3f00:1000:23:5000:80ff:fe84:91ad]:8080,http://[2607:f758:c300:0:5000:72ff:fe35:3797]:8080,http://[2607:f758:1220:0:5000:12ff:fe0c:8a57]:8080,http://[2a01:138:900a:0:5000:2aff:fef4:c47e]:8080,http://[2a0f:cd00:2:1:5000:87ff:fe58:ceba]:8080,http://[2401:3f00:1000:24:5000:86ff:fea6:9bb5]:8080,http://[2600:2c01:21:0:5000:27ff:fe23:4839]:8080,http://[2a04:9dc0:0:108:5000:7cff:fece:97d]:8080,http://[2001:920:401a:1708:5000:4fff:fe92:48f1]:8080,http://[2604:3fc0:3002:0:5000:acff:fe31:12e8]:8080,http://[2a04:9dc0:0:108:5000:6bff:fe08:5f57]:8080,http://[2607:f758:c300:0:5000:3eff:fe6d:af08]:8080,http://[2607:f758:1220:0:5000:bfff:feb9:6794]:8080,http://[2607:f758:c300:0:5000:8eff:fe8b:d68]:8080,http://[2607:f758:1220:0:5000:3aff:fe16:7aec]:8080,http://[2a00:fb01:400:100:5000:ceff:fea2:bb0]:8080,http://[2a00:fa0:3:0:5000:5aff:fe89:b5fc]:8080,http://[2a00:fa0:3:0:5000:68ff:fece:922e]:8080,http://[2600:3000:6100:200:5000:c4ff:fe43:3d8a]:8080,http://[2001:920:401a:1710:5000:d7ff:fe6f:fde7]:8080,http://[2a01:138:900a:0:5000:5aff:fece:cf05]:8080,http://[2600:3006:1400:1500:5000:20ff:fe3f:3c98]:8080}" -OUTPUT="${OUTPUT:=${BASE_DIR}/build-out}" - -function validate_input() { - local variable="${1}" - local message="${2}" - - if [ -z ${variable} ]; then - echo "Missing Argument:" - echo " ${message}" - exit 1 - fi -} - -function log_and_exit_on_error() { - local exit_code="${1}" - local log_message="${2}" - - if [ "${exit_code}" -ne 0 ]; then - echo "${log_message}" - exit "${exit_code}" - fi -} - -function log_start() { - TIME_START=$(date '+%s') - - echo "SetupOS Builder - Start" - log_and_exit_on_error "${?}" "Unable to start SetupOS builder." -} - -function validate_guest_os() { - echo "* Validating GuestOS disk-image..." - if [ ! -r "${GUEST_OS}" ]; then - log_and_exit_on_error "1" "Unable to find or read GuestOS disk-image." - fi -} - -function validate_host_os() { - echo "* Validating HostOS disk-image..." - if [ ! -r "${HOST_OS}" ]; then - log_and_exit_on_error "1" "Unable to find or read HostOS disk-image." - fi -} - -function validate_ubuntu_path() { - if [ -z "${UBUNTU}" ]; then - echo "* No Ubuntu Live Server ISO image specified." - UBUNTU_ISO_PATH="${TMP_DIR}" - else - echo "* Existing Ubuntu Live Server ISO image specified: ${UBUNTU}" - UBUNTU_ISO_PATH="${UBUNTU}" - fi -} - -function prepare_build_directories() { - if [ ! -d "${OUTPUT}" ]; then - echo "* Creating build directories..." - mkdir -p "${OUTPUT}" - fi -} - -function download_ubuntu_packages() { - echo "* Downloading Ubuntu packages..." - - curl --output "${TMP_DIR}/efibootmgr.deb" --location "${EFIBOOTMGR_URL}" - curl --output "${TMP_DIR}/libonig5.deb" --location "${LIBONIG5_URL}" - curl --output "${TMP_DIR}/libjq1.deb" --location "${LIBJQ1_URL}" - curl --output "${TMP_DIR}/jq.deb" --location "${JQ_URL}" -} - -function verify_ubuntu_packages() { - echo "* Verifying checksum of Ubuntu packages..." - - cd "${TMP_DIR}" - echo "${EFIBOOTMGR_CHECKSUM} *efibootmgr.deb" | shasum --algorithm 256 --check - echo "${LIBONIG5_CHECKSUM} *libonig5.deb" | shasum --algorithm 256 --check - echo "${LIBJQ1_CHECKSUM} *libjq1.deb" | shasum --algorithm 256 --check - echo "${JQ_CHECKSUM} *jq.deb" | shasum --algorithm 256 --check - cd - -} - -function download_ubuntu_iso() { - if [ -z "${UBUNTU}" ]; then - echo "* Downloading Ubuntu Live Server ISO image..." - curl -L --output "${TMP_DIR}/${UBUNTU_ISO}" ${UBUNTU_URL} - fi -} - -function verify_ubuntu_iso() { - echo "* Verifying Ubuntu Live Server ISO image checksum..." - - cd "${UBUNTU_ISO_PATH}" - echo "${UBUNTU_CHECKSUM} *${UBUNTU_ISO}" | shasum --algorithm 256 --check - cd - -} - -function extract_ubuntu_iso() { - echo "* Extracting Ubuntu Live Server ISO image..." - - # Extract Ubuntu ISO image except BOOT directory - 7z x ${UBUNTU_ISO_PATH}/${UBUNTU_ISO} -x'![BOOT]' -o${ISO_DIR} -} - -function prepare_build() { - echo "* Preparing SetupOS build..." - - # Create nocloud directory - mkdir -p "${ISO_DIR}/nocloud" - - # Copy Ubuntu packages to ISO - cp --preserve=timestamp "${TMP_DIR}/libonig5.deb" "${ISO_DIR}/nocloud" - cp --preserve=timestamp "${TMP_DIR}/libjq1.deb" "${ISO_DIR}/nocloud" - cp --preserve=timestamp "${TMP_DIR}/jq.deb" "${ISO_DIR}/nocloud" - cp --preserve=timestamp "${TMP_DIR}/efibootmgr.deb" "${ISO_DIR}/nocloud" - - # Copy setup files to ISO - cp --preserve=timestamp "${BASE_DIR}/src/nocloud/meta-data" "${ISO_DIR}/nocloud" - cp --preserve=timestamp "${BASE_DIR}/src/nocloud/user-data" "${ISO_DIR}/nocloud" - - # Copy setup scripts to ISO - cp --preserve=timestamp "${BASE_DIR}/src/nocloud/00_common.sh" "${ISO_DIR}/nocloud" - cp --preserve=timestamp "${BASE_DIR}/src/nocloud/01_setupos.sh" "${ISO_DIR}/nocloud" - cp --preserve=timestamp "${BASE_DIR}/src/nocloud/02_hardware.sh" "${ISO_DIR}/nocloud" - cp --preserve=timestamp "${BASE_DIR}/src/nocloud/03_firmware.sh" "${ISO_DIR}/nocloud" - cp --preserve=timestamp "${BASE_DIR}/src/nocloud/04_uefi.sh" "${ISO_DIR}/nocloud" - cp --preserve=timestamp "${BASE_DIR}/src/nocloud/05_disk.sh" "${ISO_DIR}/nocloud" - cp --preserve=timestamp "${BASE_DIR}/src/nocloud/06_hostos.sh" "${ISO_DIR}/nocloud" - cp --preserve=timestamp "${BASE_DIR}/src/nocloud/07_guestos.sh" "${ISO_DIR}/nocloud" - cp --preserve=timestamp "${BASE_DIR}/src/nocloud/08_devices.sh" "${ISO_DIR}/nocloud" - cp --preserve=timestamp "${BASE_DIR}/src/nocloud/09_setupos.sh" "${ISO_DIR}/nocloud" - - # Copy config.json, deployment.json, nns_public_key.pem to ISO - cp --preserve=timestamp "${CONFIG}" "${ISO_DIR}/nocloud/config.json" - cp --preserve=timestamp "${BASE_DIR}/src/nocloud/deployment.json" "${ISO_DIR}/nocloud" - cp --preserve=timestamp "${KEY}" "${ISO_DIR}/nocloud/nns_public_key.pem" - - # Copy HostOS accounts SSH authorized keys - if [ ! -z "${HOST_SSH}" ]; then - echo "* Copying HostOS accounts SSH authorized keys..." - mkdir -p "${ISO_DIR}/nocloud/hostos_accounts_ssh_authorized_keys" - - for file in admin backup readonly; do - if [ -r "${HOST_SSH}/${file}" ]; then - echo "* Copying HostOS '${file}' SSH authorized keys..." - cp --preserve=timestamp "${HOST_SSH}/${file}" "${ISO_DIR}/nocloud/hostos_accounts_ssh_authorized_keys/" - fi - done - fi - - # Copy GuestOS accounts SSH authorized keys - if [ ! -z "${GUEST_SSH}" ]; then - echo "* Copying GuestOS accounts SSH authorized keys..." - mkdir -p "${ISO_DIR}/nocloud/guestos_accounts_ssh_authorized_keys" - - for file in admin backup readonly; do - if [ -r "${GUEST_SSH}/${file}" ]; then - echo "* Copying GuestOS '${file}' SSH authorized keys..." - cp --preserve=timestamp "${GUEST_SSH}/${file}" "${ISO_DIR}/nocloud/guestos_accounts_ssh_authorized_keys/" - fi - done - fi - - # Inject deployment configuration - sed -i "s@{{ nns_url }}@${NNS_URL}@g" "${ISO_DIR}/nocloud/deployment.json" - sed -i "s@{{ deployment_name }}@${DEPLOYMENT}@g" "${ISO_DIR}/nocloud/deployment.json" - sed -i "s@{{ logging_hosts }}@${LOGGING}@g" "${ISO_DIR}/nocloud/deployment.json" - sed -i "s@{{ resources_memory }}@${MEMORY}@g" "${ISO_DIR}/nocloud/deployment.json" - - # Copy disk-image files - cp --preserve=timestamp "${GUEST_OS}" "${ISO_DIR}/nocloud/guest-os.img.tar.gz" - cp --preserve=timestamp "${HOST_OS}" "${ISO_DIR}/nocloud/host-os.img.tar.gz" - - # Update boot flags with cloud-init autoinstall - sed -i 's|---|autoinstall ds=nocloud\\\;s=/cdrom/nocloud/ ---|g' ${ISO_DIR}/boot/grub/grub.cfg - sed -i 's|---|autoinstall ds=nocloud;s=/cdrom/nocloud/ ---|g' ${ISO_DIR}/isolinux/txt.cfg - - # Disable autoinstall - rm -f ${ISO_DIR}/casper/installer.squashfs - - # Disable md5 checksum on boot - md5sum ${ISO_DIR}/dists/focal/Release >${ISO_DIR}/md5sum.txt - sed -i "s@${ISO_DIR}/@./@g" ${ISO_DIR}/md5sum.txt - - # Fix timestamps for reproducible build - touch -t ${TOUCH_TIMESTAMP} ${ISO_DIR}/nocloud \ - ${ISO_DIR}/nocloud/deployment.json \ - ${ISO_DIR}/boot/grub \ - ${ISO_DIR}/boot/grub/grub.cfg \ - ${ISO_DIR}/isolinux/txt.cfg \ - ${ISO_DIR}/boot/grub \ - ${ISO_DIR}/boot/grub/grub.cfg \ - ${ISO_DIR}/isolinux/txt.cfg \ - ${ISO_DIR}/md5sum.txt \ - ${ISO_DIR}/casper \ - ${ISO_DIR}/isolinux \ - ${ISO_DIR} -} - -function build_iso() { - echo "* Building SetupOS ISO image..." - - # Create ISO image from extracted Ubuntu ISO - xorriso -as mkisofs -r \ - -o ${OUTPUT}/setup-os.iso \ - -J -l -b isolinux/isolinux.bin -c isolinux/boot.cat -no-emul-boot \ - -boot-load-size 4 -boot-info-table \ - -eltorito-alt-boot -e boot/grub/efi.img -no-emul-boot \ - -isohybrid-gpt-basdat -isohybrid-apm-hfsplus \ - -isohybrid-mbr /usr/lib/ISOLINUX/isohdpfx.bin \ - ${TMP_DIR}/iso/boot ${TMP_DIR}/iso \ - -- \ - -volume_date "c" "${XORRISO_TIMESTAMP}" \ - -volume_date "m" "${XORRISO_TIMESTAMP}" \ - -volume_date "x" "default" \ - -volume_date "f" "default" \ - -alter_date_r "b" "${XORRISO_TIMESTAMP}" / -- \ - -alter_date_r "c" "${XORRISO_TIMESTAMP}" / -- -} - -function remove_temporary_directory() { - echo "* Cleaning up build directories..." - - rm -rf ${TMP_DIR} -} - -function log_end() { - local time_end=$(date '+%s') - local time_exec=$(expr "${time_end}" - "${TIME_START}") - local time_hr=$(date -d "1970-01-01 ${time_exec} sec" '+%H:%M:%S') - - echo "SetupOS Builder - End (${time_hr})" - log_and_exit_on_error "${?}" "Unable to end SetupOS builder." -} - -# Establish run order -function main() { - log_start - validate_guest_os - validate_host_os - validate_ubuntu_path - prepare_build_directories - download_ubuntu_packages - verify_ubuntu_packages - download_ubuntu_iso - verify_ubuntu_iso - extract_ubuntu_iso - prepare_build - build_iso - remove_temporary_directory - log_end -} - -main diff --git a/ic-os/setupos/src/nocloud/00_common.sh b/ic-os/setupos/src/nocloud/00_common.sh deleted file mode 100755 index 96dfedd4fe9..00000000000 --- a/ic-os/setupos/src/nocloud/00_common.sh +++ /dev/null @@ -1,61 +0,0 @@ -#!/usr/bin/env bash - -set -o nounset -set -o pipefail - -SHELL="/bin/bash" -PATH="/sbin:/bin:/usr/sbin:/usr/bin" - -function log_and_reboot_on_error() { - local exit_code="${1}" - local log_message="${2}" - - if [ "${exit_code}" -ne 0 ]; then - echo " " - echo " " - echo " " - echo " " - echo "--------------------------------------------------------------------------------" - echo " INTERNET COMPUTER SETUP FAILED" - echo "--------------------------------------------------------------------------------" - echo " " - echo " " - echo " " - echo " " - echo " Please contact Internet Computer Association (ICA) support." - echo " " - echo " " - echo " " - echo " " - echo "--------------------------------------------------------------------------------" - echo " ERROR" - echo "--------------------------------------------------------------------------------" - echo " " - echo " " - echo "${log_message}" - echo " " - echo " " - echo "--------------------------------------------------------------------------------" - echo " ERROR" - echo "--------------------------------------------------------------------------------" - sleep 120 - shutdown -h now - fi -} - -function log_start() { - TIME_START=$(date '+%s') - - echo "SetupOS - Start" - log_and_reboot_on_error "${?}" "Unable to start SetupOS script." -} - -function log_end() { - local time_end=$(date '+%s') - local time_exec=$(expr "${time_end}" - "${TIME_START}") - local time_hr=$(date -d "1970-01-01 ${time_exec} sec" '+%H:%M:%S') - - echo "SetupOS - End (${time_hr})" - log_and_reboot_on_error "${?}" "Unable to end SetupOS script." - echo " " -} diff --git a/ic-os/setupos/src/nocloud/01_setupos.sh b/ic-os/setupos/src/nocloud/01_setupos.sh deleted file mode 100755 index e5bd5b225cf..00000000000 --- a/ic-os/setupos/src/nocloud/01_setupos.sh +++ /dev/null @@ -1,31 +0,0 @@ -#!/usr/bin/env bash - -set -o nounset -set -o pipefail - -SHELL="/bin/bash" -PATH="/sbin:/bin:/usr/sbin:/usr/bin" - -function install_ubuntu_packages() { - echo "* Installing Ubuntu packages..." - - apt install -y --no-install-recommends \ - /media/cdrom/nocloud/libonig5.deb \ - /media/cdrom/nocloud/libjq1.deb \ - /media/cdrom/nocloud/jq.deb >/dev/null 2>&1 - log_and_reboot_on_error "${?}" "Unable to install 'jq'." - - apt install -y --no-install-recommends \ - /media/cdrom/nocloud/efibootmgr.deb >/dev/null 2>&1 - log_and_reboot_on_error "${?}" "Unable to install 'efibootmgr'." -} - -# Establish run order -main() { - source /media/cdrom/nocloud/00_common.sh - log_start - install_ubuntu_packages - log_end -} - -main diff --git a/ic-os/setupos/src/nocloud/02_hardware.sh b/ic-os/setupos/src/nocloud/02_hardware.sh deleted file mode 100755 index a6edaa84478..00000000000 --- a/ic-os/setupos/src/nocloud/02_hardware.sh +++ /dev/null @@ -1,118 +0,0 @@ -#!/usr/bin/env bash - -set -o nounset -set -o pipefail - -SHELL="/bin/bash" -PATH="/sbin:/bin:/usr/sbin:/usr/bin" - -CPU_CAPABILITIES=("sev") -CPU_CORES=16 -CPU_SOCKETS=2 -CPU_THREADS=32 -CPU_MODEL="AMD EPYC 7302" - -# 510 GiB (Gibibyte) -MEMORY_SIZE=547608330240 - -DISK_NAME="nvme0n1" -# 2900 GiB (Gibibyte) -DISK_SIZE=3113851289600 - -function verify_cpu() { - echo "* Verifying CPU..." - - local cpu="$(lshw -quiet -class cpu -json)" - log_and_reboot_on_error "${?}" "Unable to fetch CPU information." - - local sockets=$(echo "${cpu}" | jq -r '.[].id' | wc -l) - log_and_reboot_on_error "${?}" "Unable to extract CPU sockets." - - if [ ${sockets} -eq ${CPU_SOCKETS} ]; then - echo "Number of sockets (${sockets}/${CPU_SOCKETS}) meets system requirements." - else - log_and_reboot_on_error "1" "Number of sockets (${sockets}/${CPU_SOCKETS}) does NOT meet system requirements." - fi - - for i in $(echo "${cpu}" | jq -r '.[].id'); do - unit=$(echo ${i} | awk -F ':' '{ print $2 }') - echo "* Verifying CPU socket ${unit}..." - - local model=$(echo "${cpu}" | jq -r --arg socket "${i}" '.[] | select(.id==$socket) | .product') - if [[ ${model} =~ .*${CPU_MODEL}.* ]]; then - echo "Model meets system requirements." - else - log_and_reboot_on_error "1" "Model does NOT meet system requirements.." - fi - - echo "* Verifying CPU capabilities..." - for c in ${CPU_CAPABILITIES[@]}; do - local capability=$(echo "${cpu}" | jq -r --arg socket "${i}" --arg capability "${c}" '.[] | select(.id==$socket) | .capabilities[$capability]') - log_and_reboot_on_error "$?" "Capability '${c}' does NOT meet system requirements.." - - if [[ ${capability} =~ .*true.* ]]; then - echo "Capability '${c}' meets system requirements." - else - log_and_reboot_on_error "$?" "Capability '${c}' does NOT meet system requirements.." - fi - done - - local cores=$(echo "${cpu}" | jq -r --arg socket "${i}" '.[] | select(.id==$socket) | .configuration.cores') - if [ ${cores} -eq ${CPU_CORES} ]; then - echo "Number of cores (${cores}/${CPU_CORES}) meets system requirements." - else - log_and_reboot_on_error "1" "Number of cores (${cores}/${CPU_CORES}) does NOT meet system requirements." - fi - - local threads=$(echo "${cpu}" | jq -r --arg socket "${i}" '.[] | select(.id==$socket) | .configuration.threads') - if [ ${threads} -eq ${CPU_THREADS} ]; then - echo "Number of threads (${threads}/${CPU_THREADS}) meets system requirements." - else - log_and_reboot_on_error "1" "Number of threads (${threads}/${CPU_THREADS}) does NOT meet system requirements." - fi - done -} - -function verify_memory() { - echo "* Verifying system memory..." - - local memory="$(lshw -quiet -class memory -json)" - log_and_reboot_on_error "${?}" "Unable to fetch memory information." - - local size=$(echo ${memory} | jq -r '.[] | select(.id=="memory") | .size') - log_and_reboot_on_error "${?}" "Unable to extract memory size." - - if [ "${size}" -gt "${MEMORY_SIZE}" ]; then - echo "Memory size (${size} bytes) meets system requirements." - else - log_and_reboot_on_error "1" "Memory size (${size} bytes) does NOT meet system requirements." - fi -} - -function verify_disk() { - echo "* Verifying system disk..." - - local disk="$(lsblk --bytes --json /dev/${DISK_NAME})" - log_and_reboot_on_error "${?}" "Unable to fetch disk information." - - local size=$(echo ${disk} | jq -r --arg logicalname "${DISK_NAME}" '.[][] | select(.name==$logicalname) | .size') - log_and_reboot_on_error "${?}" "Unable to extract disk size." - - if [ "${size}" -gt "${DISK_SIZE}" ]; then - echo "Disk size (${size} bytes) meets system requirements." - else - log_and_reboot_on_error "1" "Disk size (${size} bytes) does NOT meet system requirements." - fi -} - -# Establish run order -main() { - source /media/cdrom/nocloud/00_common.sh - log_start - verify_cpu - verify_disk - verify_memory - log_end -} - -main diff --git a/ic-os/setupos/src/nocloud/03_firmware.sh b/ic-os/setupos/src/nocloud/03_firmware.sh deleted file mode 100755 index 0ee290e5f3e..00000000000 --- a/ic-os/setupos/src/nocloud/03_firmware.sh +++ /dev/null @@ -1,56 +0,0 @@ -#!/usr/bin/env bash - -set -o nounset -set -o pipefail - -SHELL="/bin/bash" -PATH="/sbin:/bin:/usr/sbin:/usr/bin" - -function set_uefi() { - echo "* Setting UEFI version..." - - true - log_and_reboot_on_error "${?}" "Unable to set UEFI version." -} - -function set_idrac() { - echo "* Setting iDRAC version..." - - true - log_and_reboot_on_error "${?}" "Unable to set iDRAC version." -} - -function set_chipset() { - echo "* Setting chipset version..." - - true - log_and_reboot_on_error "${?}" "Unable to set chipset version." -} - -function set_psu() { - echo "* Setting PSU version..." - - true - log_and_reboot_on_error "${?}" "Unable to set PSU version." -} - -function set_nic() { - echo "* Setting NIC version..." - - true - log_and_reboot_on_error "${?}" "Unable to set NIC version." -} - -# Establish run order -main() { - source /media/cdrom/nocloud/00_common.sh - log_start - set_uefi - set_idrac - set_chipset - set_psu - set_nic - log_end -} - -main diff --git a/ic-os/setupos/src/nocloud/04_uefi.sh b/ic-os/setupos/src/nocloud/04_uefi.sh deleted file mode 100755 index 4f624c9f92b..00000000000 --- a/ic-os/setupos/src/nocloud/04_uefi.sh +++ /dev/null @@ -1,32 +0,0 @@ -#!/usr/bin/env bash - -set -o nounset -set -o pipefail - -SHELL="/bin/bash" -PATH="/sbin:/bin:/usr/sbin:/usr/bin" - -function apply_uefi_config() { - echo "* Applying UEFI configuration..." - - true - log_and_reboot_on_error "${?}" "Unable to apply UEFI configuration file." -} - -function verify_uefi_config() { - echo "* Verifying UEFI configuration..." - - true - log_and_reboot_on_error "${?}" "Unable to apply UEFI configuration file." -} - -# Establish run order -main() { - source /media/cdrom/nocloud/00_common.sh - log_start - apply_uefi_config - verify_uefi_config - log_end -} - -main diff --git a/ic-os/setupos/src/nocloud/05_disk.sh b/ic-os/setupos/src/nocloud/05_disk.sh deleted file mode 100755 index a18fb5c7986..00000000000 --- a/ic-os/setupos/src/nocloud/05_disk.sh +++ /dev/null @@ -1,53 +0,0 @@ -#!/usr/bin/env bash - -set -o pipefail - -SHELL="/bin/bash" -PATH="/sbin:/bin:/usr/sbin:/usr/bin" - -function purge_volume_groups() { - echo "* Purging volume groups..." - - vgcount=$(find /dev/mapper/ -type l | wc -l) - if [ ${vgcount} -gt 0 ]; then - vgs=$(find /dev/mapper/ -type l) - for vg in ${vgs}; do - echo ${vg} - dmsetup remove --force ${vg} >/dev/null 2>&1 - log_and_reboot_on_error "${?}" "Unable to purge volume groups." - done - fi -} - -function purge_partitions() { - echo "* Purging partitions..." - - # Destroy master boot record and partition table - nvme_drives=($(find /dev/ -type b -iname "nvme*n1" | sort)) - vda_drives=($(find /dev/ -type b -iname "vd*" | sort)) - - if [ ! -z "${nvme_drives}" ]; then - for drive in $(echo ${nvme_drives[@]}); do - wipefs --all --force ${drive} - log_and_reboot_on_error "${?}" "Unable to purge partitions on drive: ${drive}" - done - elif [ ! -z "${vda_drives}" ]; then - for drive in $(echo ${vda_drives[@]}); do - wipefs --all --force ${drive} - log_and_reboot_on_error "${?}" "Unable to purge partitions on drive: ${drive}" - done - else - log_and_reboot_on_error "1" "Unable to locate suitable system drive." - fi -} - -# Establish run order -main() { - source /media/cdrom/nocloud/00_common.sh - log_start - purge_volume_groups - purge_partitions - log_end -} - -main diff --git a/ic-os/setupos/src/nocloud/06_hostos.sh b/ic-os/setupos/src/nocloud/06_hostos.sh deleted file mode 100755 index 2879a0f776e..00000000000 --- a/ic-os/setupos/src/nocloud/06_hostos.sh +++ /dev/null @@ -1,63 +0,0 @@ -#!/usr/bin/env bash - -set -o pipefail - -SHELL="/bin/bash" -PATH="/sbin:/bin:/usr/sbin:/usr/bin" - -function install_hostos() { - echo "* Installing HostOS disk-image (can take up to 5 minutes)..." - - tar xzOf /media/cdrom/nocloud/host-os.img.tar.gz disk.img | dd of="/dev/nvme0n1" bs=10M - log_and_reboot_on_error "${?}" "Unable to install HostOS disk-image on drive: /dev/nvme0n1" - - sync - log_and_reboot_on_error "${?}" "Unable to synchronize cached writes to persistent storage." -} - -function configure_efi() { - echo "* Configuring EFI..." - - bootnum=$(efibootmgr --verbose | grep "IC-OS" | sed 's/Boot\([0-9A-F]*\).*/\1/') - for b in ${bootnum}; do - efibootmgr --delete-bootnum --bootnum ${b} >/dev/null 2>&1 - log_and_reboot_on_error "${?}" "Unable to delete existing 'IC-OS' boot entry." - done - - efibootmgr --create --gpt --disk "/dev/nvme0n1p1" --loader "\EFI\BOOT\BOOTX64.EFI" --label "IC-OS" >/dev/null 2>&1 - log_and_reboot_on_error "${?}" "Unable to create 'IC-OS' boot entry." - - efibootmgr --remove-dups >/dev/null 2>&1 - log_and_reboot_on_error "${?}" "Unable to remove duplicate boot order entries." - - efibootmgr --verbose | grep "IC-OS" | efibootmgr -o $(sed 's/Boot\([0-9A-F]*\).*/\1/') >/dev/null 2>&1 - log_and_reboot_on_error "${?}" "Unable to set EFI boot order." -} - -function resize_partition() { - echo "* Resizing partition..." - - sgdisk --move-second-header /dev/nvme0n1 >/dev/null 2>&1 - log_and_reboot_on_error "${?}" "Unable to extend GPT data structures: /dev/nvme0n1" - - parted -s --align optimal /dev/nvme0n1 "resizepart 3 100%" >/dev/null 2>&1 - log_and_reboot_on_error "${?}" "Unable to resize partition: /dev/nvme0n1p3" - - pvresize /dev/nvme0n1p3 >/dev/null 2>&1 - log_and_reboot_on_error "${?}" "Unable to resize physical volume: /dev/nvme0n1p3" - - lvextend -l +100%FREE /dev/hostlvm/guestos >/dev/null 2>&1 - log_and_reboot_on_error "${?}" "Unable to extend logical volume: /dev/hostlvm/guestos" -} - -# Establish run order -main() { - source /media/cdrom/nocloud/00_common.sh - log_start - install_hostos - configure_efi - resize_partition - log_end -} - -main diff --git a/ic-os/setupos/src/nocloud/07_guestos.sh b/ic-os/setupos/src/nocloud/07_guestos.sh deleted file mode 100755 index 27175f6cf26..00000000000 --- a/ic-os/setupos/src/nocloud/07_guestos.sh +++ /dev/null @@ -1,35 +0,0 @@ -#!/usr/bin/env bash - -set -o nounset -set -o pipefail - -SHELL="/bin/bash" -PATH="/sbin:/bin:/usr/sbin:/usr/bin" - -LV="/dev/mapper/hostlvm-guestos" - -function install_guestos() { - echo "* Installing GuestOS disk-image to ${LV} (can take up to 3 minutes)..." - - vgchange -ay hostlvm - log_and_reboot_on_error "${?}" "Unable to activate HostOS volume group." - - tar xzOf /media/cdrom/nocloud/guest-os.img.tar.gz disk.img | dd of=${LV} bs=10M - log_and_reboot_on_error "${?}" "Unable to install GuestOS disk-image." - - sync - log_and_reboot_on_error "${?}" "Unable to synchronize cached writes to persistent storage." - - vgchange -an hostlvm - log_and_reboot_on_error "${?}" "Unable to deactivate HostOS volume group." -} - -# Establish run order -main() { - source /media/cdrom/nocloud/00_common.sh - log_start - install_guestos - log_end -} - -main diff --git a/ic-os/setupos/src/nocloud/08_devices.sh b/ic-os/setupos/src/nocloud/08_devices.sh deleted file mode 100755 index b7c27cfe7aa..00000000000 --- a/ic-os/setupos/src/nocloud/08_devices.sh +++ /dev/null @@ -1,86 +0,0 @@ -#!/usr/bin/env bash - -set -o nounset -set -o pipefail - -SHELL="/bin/bash" -PATH="/sbin:/bin:/usr/sbin:/usr/bin" - -function mount_config_partition() { - echo "* Mounting config partition..." - - mkdir --parents /media/config - log_and_reboot_on_error "${?}" "Unable to create mount directory." - - vgchange -ay hostlvm - log_and_reboot_on_error "${?}" "Unable to activate config partition." - - mount /dev/mapper/hostlvm-config /media/config - log_and_reboot_on_error "${?}" "Unable to mount config partition." -} - -function copy_config_files() { - echo "* Copying config.json to config partition..." - cp /media/cdrom/nocloud/config.json /media/config/config.json - log_and_reboot_on_error "${?}" "Unable to copy config.json to config partition." - - echo "* Copying deployment.json to config partition..." - cp /media/cdrom/nocloud/deployment.json /media/config/deployment.json - log_and_reboot_on_error "${?}" "Unable to copy deployment.json to config partition." - - echo "* Copying NNS public key to config partition..." - cp /media/cdrom/nocloud/nns_public_key.pem /media/config/nns_public_key.pem - log_and_reboot_on_error "${?}" "Unable to copy NNS public key to config partition." - - if [ -d "/media/cdrom/nocloud/hostos_accounts_ssh_authorized_keys" ]; then - echo "* Copying HostOS accounts SSH authorized keys..." - cp -r /media/cdrom/nocloud/hostos_accounts_ssh_authorized_keys /media/config/ - log_and_reboot_on_error "${?}" "Unable to copy HostOS accounts SSH authorized keys to config partition." - fi - - if [ -d "/media/cdrom/nocloud/guestos_accounts_ssh_authorized_keys" ]; then - echo "* Copying GuestOS accounts SSH authorized keys..." - cp -r /media/cdrom/nocloud/guestos_accounts_ssh_authorized_keys /media/config/ - log_and_reboot_on_error "${?}" "Unable to copy GuestOS accounts SSH authorized keys to config partition." - fi -} - -function insert_hsm() { - retry=0 - while [ -z "$(lsusb | grep -E 'Nitro|Clay')" ]; do - let retry=retry+1 - if [ ${retry} -ge 3600 ]; then - log_and_reboot_on_error "1" "Nitrokey HSM USB device could not be detected, giving up." - break - else - echo "* Please insert Nitrokey HSM USB device..." - sleep 3 - fi - done -} - -function unmount_config_partition() { - echo "* Unmounting config partition..." - - sync - log_and_reboot_on_error "${?}" "Unable to synchronize cached writes to persistent storage." - - umount /media/config - log_and_reboot_on_error "${?}" "Unable to unmount config partition." - - vgchange -an hostlvm - log_and_reboot_on_error "${?}" "Unable to deactivate config partition." -} - -# Establish run order -main() { - source /media/cdrom/nocloud/00_common.sh - log_start - mount_config_partition - copy_config_files - insert_hsm - unmount_config_partition - log_end -} - -main diff --git a/ic-os/setupos/src/nocloud/09_setupos.sh b/ic-os/setupos/src/nocloud/09_setupos.sh deleted file mode 100755 index 3296f1def57..00000000000 --- a/ic-os/setupos/src/nocloud/09_setupos.sh +++ /dev/null @@ -1,48 +0,0 @@ -#!/usr/bin/env bash - -set -o nounset -set -o pipefail - -SHELL="/bin/bash" -PATH="/sbin:/bin:/usr/sbin:/usr/bin" - -function reboot_setupos() { - echo "* Rebooting SetupOS..." - echo " " - echo " " - echo " " - echo " " - echo "-------------------------------------------------------------------------------" - echo " INTERNET COMPUTER SETUP WAS SUCCESSFUL" - echo "-------------------------------------------------------------------------------" - echo " " - echo " " - echo " " - echo " " - echo " Please do NOT unplug the Nitrokey HSM USB device just yet." - echo " " - echo " Wait for the message after the first boot..." - echo " " - echo " " - echo " " - echo " " - echo "-------------------------------------------------------------------------------" - echo " INTERNET COMPUTER SETUP WAS SUCCESSFUL" - echo "-------------------------------------------------------------------------------" - echo " " - echo " " - echo " " - echo " " - sleep 15 - shutdown -r now -} - -# Establish run order -main() { - source /media/cdrom/nocloud/00_common.sh - log_start - reboot_setupos - log_end -} - -main diff --git a/ic-os/setupos/src/nocloud/config.json b/ic-os/setupos/src/nocloud/config.json deleted file mode 100644 index 2882a94a158..00000000000 --- a/ic-os/setupos/src/nocloud/config.json +++ /dev/null @@ -1,232 +0,0 @@ -{ - "network": { - "name_servers": "2606:4700:4700::1111 2606:4700:4700::1001 2001:4860:4860::8888 2001:4860:4860::8844", - "dcs": { - "0000000000000000000000000000000000000000000000000000000000000001": { - "ipv6_prefix": "2001:438:fffd:11c", - "ipv6_subnet": "/64", - "ipv6_gateway": "2001:438:fffd:11c::1" - }, - "0000000000000000000000000000000000000000000000000000000000000002": { - "ipv6_prefix": "2001:470:1:c76", - "ipv6_subnet": "/64", - "ipv6_gateway": "2001:470:1:c76::1" - }, - "0000000000000000000000000000000000000000000000000000000000000003": { - "ipv6_prefix": "2001:4d78:400:10a", - "ipv6_subnet": "/64", - "ipv6_gateway": "2001:4d78:400:10a::1" - }, - "0000000000000000000000000000000000000000000000000000000000000004": { - "ipv6_prefix": "2001:4d78:40d:0", - "ipv6_subnet": "/64", - "ipv6_gateway": "2001:4d78:40d::1" - }, - "0000000000000000000000000000000000000000000000000000000000000005": { - "ipv6_prefix": "2001:920:401a:1706", - "ipv6_subnet": "/64", - "ipv6_gateway": "2001:920:401a:1706::1" - }, - "0000000000000000000000000000000000000000000000000000000000000006": { - "ipv6_prefix": "2001:920:401a:1708", - "ipv6_subnet": "/64", - "ipv6_gateway": "2001:920:401a:1708::1" - }, - "0000000000000000000000000000000000000000000000000000000000000007": { - "ipv6_prefix": "2001:920:401a:1710", - "ipv6_subnet": "/64", - "ipv6_gateway": "2001:920:401a:1710::1" - }, - "0000000000000000000000000000000000000000000000000000000000000008": { - "ipv6_prefix": "2401:3f00:1000:22", - "ipv6_subnet": "/64", - "ipv6_gateway": "2401:3f00:1000:22::1" - }, - "0000000000000000000000000000000000000000000000000000000000000009": { - "ipv6_prefix": "2401:3f00:1000:23", - "ipv6_subnet": "/64", - "ipv6_gateway": "2401:3f00:1000:23::1" - }, - "0000000000000000000000000000000000000000000000000000000000000010": { - "ipv6_prefix": "2401:3f00:1000:24", - "ipv6_subnet": "/64", - "ipv6_gateway": "2401:3f00:1000:24::1" - }, - "0000000000000000000000000000000000000000000000000000000000000011": { - "ipv6_prefix": "2600:2c01:21:0", - "ipv6_subnet": "/64", - "ipv6_gateway": "2600:2c01:21::1" - }, - "0000000000000000000000000000000000000000000000000000000000000012": { - "ipv6_prefix": "2600:3000:1300:1300", - "ipv6_subnet": "/64", - "ipv6_gateway": "2600:3000:1300:1300::1" - }, - "0000000000000000000000000000000000000000000000000000000000000013": { - "ipv6_prefix": "2600:3000:6100:200", - "ipv6_subnet": "/64", - "ipv6_gateway": "2600:3000:6100:200::1" - }, - "0000000000000000000000000000000000000000000000000000000000000014": { - "ipv6_prefix": "2600:3004:1200:1200", - "ipv6_subnet": "/64", - "ipv6_gateway": "2600:3004:1200:1200::1" - }, - "0000000000000000000000000000000000000000000000000000000000000015": { - "ipv6_prefix": "2600:3006:1400:1500", - "ipv6_subnet": "/64", - "ipv6_gateway": "2600:3006:1400:1500::1" - }, - "0000000000000000000000000000000000000000000000000000000000000016": { - "ipv6_prefix": "2600:c02:b002:15", - "ipv6_subnet": "/64", - "ipv6_gateway": "2600:c02:b002:15::1" - }, - "0000000000000000000000000000000000000000000000000000000000000017": { - "ipv6_prefix": "2600:c0d:3002:4", - "ipv6_subnet": "/64", - "ipv6_gateway": "2600:c0d:3002:4::1" - }, - "0000000000000000000000000000000000000000000000000000000000000018": { - "ipv6_prefix": "2604:3fc0:2001:0", - "ipv6_subnet": "/64", - "ipv6_gateway": "2604:3fc0:2001:0::1" - }, - "0000000000000000000000000000000000000000000000000000000000000019": { - "ipv6_prefix": "2604:3fc0:3002:0", - "ipv6_subnet": "/64", - "ipv6_gateway": "2604:3fc0:3002:0::1" - }, - "0000000000000000000000000000000000000000000000000000000000000020": { - "ipv6_prefix": "2604:6800:258:1", - "ipv6_subnet": "/64", - "ipv6_gateway": "2604:6800:258:1::1" - }, - "0000000000000000000000000000000000000000000000000000000000000021": { - "ipv6_prefix": "2604:7e00:30:3", - "ipv6_subnet": "/64", - "ipv6_gateway": "2604:7e00:30:3::1" - }, - "0000000000000000000000000000000000000000000000000000000000000022": { - "ipv6_prefix": "2604:7e00:50:0", - "ipv6_subnet": "/64", - "ipv6_gateway": "2604:7e00:50::1" - }, - "0000000000000000000000000000000000000000000000000000000000000023": { - "ipv6_prefix": "2604:b900:4001:76", - "ipv6_subnet": "/64", - "ipv6_gateway": "2604:b900:4001:76::1" - }, - "0000000000000000000000000000000000000000000000000000000000000024": { - "ipv6_prefix": "2607:f1d0:10:1", - "ipv6_subnet": "/64", - "ipv6_gateway": "2607:f1d0:10:1::1" - }, - "0000000000000000000000000000000000000000000000000000000000000025": { - "ipv6_prefix": "2607:f6f0:3004:1", - "ipv6_subnet": "/64", - "ipv6_gateway": "2607:f6f0:3004:1::1" - }, - "0000000000000000000000000000000000000000000000000000000000000026": { - "ipv6_prefix": "2607:f758:1220:0", - "ipv6_subnet": "/64", - "ipv6_gateway": "2607:f758:1120::1" - }, - "0000000000000000000000000000000000000000000000000000000000000027": { - "ipv6_prefix": "2607:f758:c300:0", - "ipv6_subnet": "/64", - "ipv6_gateway": "2607:f758:c300::1" - }, - "0000000000000000000000000000000000000000000000000000000000000028": { - "ipv6_prefix": "2607:fb58:9005:42", - "ipv6_subnet": "/64", - "ipv6_gateway": "2607:fb58:9005:42::1" - }, - "0000000000000000000000000000000000000000000000000000000000000029": { - "ipv6_prefix": "2607:ff70:3:2", - "ipv6_subnet": "/64", - "ipv6_gateway": "2607:ff70:3:2::1" - }, - "0000000000000000000000000000000000000000000000000000000000000030": { - "ipv6_prefix": "2610:190:6000:1", - "ipv6_subnet": "/64", - "ipv6_gateway": "2610:190:6000:1::1" - }, - "0000000000000000000000000000000000000000000000000000000000000031": { - "ipv6_prefix": "2610:190:df01:5", - "ipv6_subnet": "/64", - "ipv6_gateway": "2610:190:df01:5::1" - }, - "0000000000000000000000000000000000000000000000000000000000000032": { - "ipv6_prefix": "2a00:fa0:3:0", - "ipv6_subnet": "/64", - "ipv6_gateway": "2a00:fa0:3:0::1" - }, - "503513fe9bf162a8e59c838659da7005878f1dbdcc62cedec8c4f64d17231de5": { - "ipv6_prefix": "2a00:fb01:400:100", - "ipv6_subnet": "/64", - "ipv6_gateway": "2a00:fb01:400:100::1" - }, - "fc3f5ea0b55507a94c1d8573c408fe7c0472f93ba241fa9a6e8c578bcd7a4645": { - "ipv6_prefix": "2a00:fb01:400:42", - "ipv6_subnet": "/64", - "ipv6_gateway": "2a00:fb01:400:42::1" - }, - "0000000000000000000000000000000000000000000000000000000000000035": { - "ipv6_prefix": "2a00:fc0:5000:300", - "ipv6_subnet": "/64", - "ipv6_gateway": "2a00:fc0:5000:300::1" - }, - "0000000000000000000000000000000000000000000000000000000000000036": { - "ipv6_prefix": "2a01:138:900a:0", - "ipv6_subnet": "/64", - "ipv6_gateway": "2a01:138:900a:0::1" - }, - "0000000000000000000000000000000000000000000000000000000000000037": { - "ipv6_prefix": "2a01:2a8:a13c:1", - "ipv6_subnet": "/64", - "ipv6_gateway": "2a01:2a8:a13c:1::1" - }, - "0000000000000000000000000000000000000000000000000000000000000038": { - "ipv6_prefix": "2a01:2a8:a13d:1", - "ipv6_subnet": "/64", - "ipv6_gateway": "2a01:2a8:a13d:1::1" - }, - "0000000000000000000000000000000000000000000000000000000000000039": { - "ipv6_prefix": "2a01:2a8:a13e:1", - "ipv6_subnet": "/64", - "ipv6_gateway": "2a01:2a8:a13e:1::1" - }, - "0000000000000000000000000000000000000000000000000000000000000040": { - "ipv6_prefix": "2a02:418:3002:0", - "ipv6_subnet": "/64", - "ipv6_gateway": "2a02:418:3002:0::1" - }, - "92b004d5fcc11911249b23460f57d1f74a460c7cba3e3dd738e3a76c0e25b50a": { - "ipv6_prefix": "2a02:41b:300e:0", - "ipv6_subnet": "/64", - "ipv6_gateway": "2a02:41b:300e::1" - }, - "0000000000000000000000000000000000000000000000000000000000000042": { - "ipv6_prefix": "2a02:800:2:2003", - "ipv6_subnet": "/64", - "ipv6_gateway": "2a02:800:2:2003::1" - }, - "0000000000000000000000000000000000000000000000000000000000000043": { - "ipv6_prefix": "2a04:9dc0:0:108", - "ipv6_subnet": "/64", - "ipv6_gateway": "2a04:9dc0:0:108::1" - }, - "0000000000000000000000000000000000000000000000000000000000000044": { - "ipv6_prefix": "2a0b:21c0:b002:2", - "ipv6_subnet": "/64", - "ipv6_gateway": "2a0b:21c0:b002:2::1" - }, - "0000000000000000000000000000000000000000000000000000000000000045": { - "ipv6_prefix": "2a0f:cd00:2:1", - "ipv6_subnet": "/64", - "ipv6_gateway": "2a0f:cd00:2:1::1" - } - } - } -} diff --git a/ic-os/setupos/src/nocloud/deployment.json b/ic-os/setupos/src/nocloud/deployment.json deleted file mode 100644 index 99177b71701..00000000000 --- a/ic-os/setupos/src/nocloud/deployment.json +++ /dev/null @@ -1,14 +0,0 @@ -{ - "deployment": { - "name": "{{ deployment_name }}" - }, - "logging": { - "hosts": "{{ logging_hosts }}" - }, - "nns": { - "url": "{{ nns_url }}" - }, - "resources": { - "memory": "{{ resources_memory }}" - } -} diff --git a/ic-os/setupos/src/nocloud/meta-data b/ic-os/setupos/src/nocloud/meta-data deleted file mode 100644 index e69de29bb2d..00000000000 diff --git a/ic-os/setupos/src/nocloud/nns_public_key.pem b/ic-os/setupos/src/nocloud/nns_public_key.pem deleted file mode 100644 index 21ccf24074f..00000000000 --- a/ic-os/setupos/src/nocloud/nns_public_key.pem +++ /dev/null @@ -1,5 +0,0 @@ ------BEGIN PUBLIC KEY----- -MIGCMB0GDSsGAQQBgtx8BQMBAgEGDCsGAQQBgtx8BQMCAQNhAIFMDm7HH6tYOwi9 -gTc8JVw8NxsuhIY8mKTx4It0I10U+12cDNVG2WhfkToMCyzFNBWDv0tDkuRn25bW -W5u0y3FxEvhHLg1aTRRQX/10hLASkQkcX4e5iINGP5gJGguqrg== ------END PUBLIC KEY----- diff --git a/ic-os/setupos/src/nocloud/user-data b/ic-os/setupos/src/nocloud/user-data deleted file mode 100644 index e1b347b9976..00000000000 --- a/ic-os/setupos/src/nocloud/user-data +++ /dev/null @@ -1,26 +0,0 @@ -#cloud-config - -# Do not print SSH fingerprints to the console -no_ssh_fingerprints: false - -# Do not print SSH host keys to the console -ssh: - emit_keys_to_console: false - -# Do not configure network -network: - config: disabled -disable_network_activation: true - -runcmd: -- bash /media/cdrom/nocloud/01_setupos.sh -- bash /media/cdrom/nocloud/02_hardware.sh -# NOTE: Firmware up-/downgrades are currently applied manually -#- bash /media/cdrom/nocloud/03_firmware.sh -# NOTE: UEFI settings are currently applied manually -#- bash /media/cdrom/nocloud/04_uefi.sh -- bash /media/cdrom/nocloud/05_disk.sh -- bash /media/cdrom/nocloud/06_hostos.sh -- bash /media/cdrom/nocloud/07_guestos.sh -- bash /media/cdrom/nocloud/08_devices.sh -- bash /media/cdrom/nocloud/09_setupos.sh diff --git a/rs/guestos_vsock_agent/README.md b/rs/guestos_vsock_agent/README.md index 47844909a2d..2d289462187 100644 --- a/rs/guestos_vsock_agent/README.md +++ b/rs/guestos_vsock_agent/README.md @@ -3,10 +3,4 @@ The vsock_agent runs in the guest VM and sends messages to the host (hypervisor) over the vsock channel. -At the moment the following commands are supported: - -- `attach-hsm` - Request to connect the HSM via virtual USB to this VM. -- `detach-hsm` - Request to disconnect the HSM from this VM. -- `upgrade` - Request that the HostOS applies the given update. -- `set-node-id` - Request that the host add node information to hostname. -- `join-success` - Request that the HostOS notifies operator of a successful network join. +At the moment only the "attach-hsm" and "detach-hsm" commands are supported. diff --git a/rs/guestos_vsock_agent/src/agent.rs b/rs/guestos_vsock_agent/src/agent.rs index 265a5cbfd0a..b1dd65718ba 100644 --- a/rs/guestos_vsock_agent/src/agent.rs +++ b/rs/guestos_vsock_agent/src/agent.rs @@ -93,25 +93,6 @@ fn main() -> Result<(), Error> { .long("detach-hsm") .help("Request the HSM device to be detached"), ) - .arg( - Arg::with_name("set-node-id") - .long("set-node-id") - .value_name("node_id") - .help("Set the node ID on the host.") - .takes_value(true), - ) - .arg( - Arg::with_name("join-success") - .long("join-success") - .help("Notify the host of a successful join request"), - ) - .arg( - Arg::with_name("upgrade") - .long("upgrade") - .value_name("info") - .help("Request the HostOS to apply upgrade") - .takes_value(true), - ) .arg( Arg::with_name("port") .long("port") @@ -132,19 +113,5 @@ fn main() -> Result<(), Error> { return send_msg_to_host("detach-hsm", port); } - if let Some(node_id) = matches.value_of("set-node-id") { - return send_msg_to_host(&format!("set-node-id[{}]", node_id), port); - } - - if matches.is_present("join-success") { - return send_msg_to_host("join-success", port); - } - - // TODO: Currently `info` is a string of the form `"url sha"`. Instead, we - // should use `clap` to present this better. - if let Some(info) = matches.value_of("upgrade") { - return send_msg_to_host(&format!("upgrade[{}]", info), port); - } - Ok(()) } diff --git a/rs/orchestrator/src/registration.rs b/rs/orchestrator/src/registration.rs index b0d56c545d5..becbd08672c 100644 --- a/rs/orchestrator/src/registration.rs +++ b/rs/orchestrator/src/registration.rs @@ -138,8 +138,6 @@ impl NodeRegistration { }; tokio::time::sleep(Duration::from_secs(2)).await; } - - UtilityCommand::notify_host_success(); } fn assemble_add_node_message(&self) -> AddNodePayload { diff --git a/rs/sys/src/utility_command.rs b/rs/sys/src/utility_command.rs index c67eee329df..7c8036a0f20 100644 --- a/rs/sys/src/utility_command.rs +++ b/rs/sys/src/utility_command.rs @@ -174,22 +174,6 @@ impl UtilityCommand { } } } - - /// Notify the host that we have successfully made a join request, if the - /// VSOCK_AGENT_PATH binary exists. Ignore any errors in the execution. - pub fn notify_host_success() { - if let Ok(metadata) = std::fs::metadata(VSOCK_AGENT_PATH) { - let permissions = metadata.permissions(); - if permissions.mode() & 0o111 != 0 { - // Executable exists. We will run it, without checking the result. - // Once we finish migration to the Ubuntu-based IC-OS and the Vsock-based HSM - // sharing, we'll want to know if this command failed. - let _ = StdCommand::new(VSOCK_AGENT_PATH) - .arg("--join-success".to_string()) - .status(); - } - } - } } impl std::fmt::Display for UtilityCommand {