From 12acd3f13444ebd2fdb50e9a6eea57d404fe76d0 Mon Sep 17 00:00:00 2001 From: craigcomstock <2554776+craigcomstock@users.noreply.github.com> Date: Mon, 24 Aug 2026 16:41:47 +0000 Subject: [PATCH] Mirrored ci/ from master (3.24.x) Signed-off-by: github-actions[bot] <41898282+github-actions[bot]@users.noreply.github.com> --- ci/Dockerfile-cfengine-build-package | 10 -- ci/Dockerfile-cfengine-deployment-tests | 3 - ci/README | 73 ---------- ci/README.md | 4 + ci/build.sh | 43 ------ ...ine-masterfiles-3.21.4-1.pkg.tar.gz.sha256 | 1 - ...ine-masterfiles-3.21.5-1.pkg.tar.gz.sha256 | 1 - ci/clean-build-package.sh | 14 -- ci/clean-deployment-tests.sh | 6 - ci/deployment-tests.sh | 63 --------- ci/docker-build-package.sh | 63 --------- ci/docker-deployment-tests.sh | 28 ---- ci/docker.sh | 1 - ci/fix-buildhost.sh | 62 +++++++-- ci/initialize-build-host.sh | 18 ++- ci/known_hosts | 16 +++ ci/linux-install-groovy.sh | 4 +- ci/linux-install-jdk.sh | 6 +- ci/linux-install-jdk21.sh | 20 --- ci/setup-cfengine-build-host.sh | 61 ++++++--- ci/setup-ci-host.sh | 127 +++++++++++++++--- ci/setup-projects.sh | 60 --------- ci/setup.sh | 44 ------ ci/shell.sh | 2 - 24 files changed, 248 insertions(+), 482 deletions(-) delete mode 100644 ci/Dockerfile-cfengine-build-package delete mode 100644 ci/Dockerfile-cfengine-deployment-tests delete mode 100644 ci/README create mode 100644 ci/README.md delete mode 100755 ci/build.sh delete mode 100644 ci/cfengine-masterfiles-3.21.4-1.pkg.tar.gz.sha256 delete mode 100644 ci/cfengine-masterfiles-3.21.5-1.pkg.tar.gz.sha256 delete mode 100755 ci/clean-build-package.sh delete mode 100755 ci/clean-deployment-tests.sh delete mode 100755 ci/deployment-tests.sh delete mode 100755 ci/docker-build-package.sh delete mode 100755 ci/docker-deployment-tests.sh delete mode 120000 ci/docker.sh create mode 100644 ci/known_hosts delete mode 100755 ci/linux-install-jdk21.sh delete mode 100755 ci/setup-projects.sh delete mode 100755 ci/setup.sh delete mode 100755 ci/shell.sh diff --git a/ci/Dockerfile-cfengine-build-package b/ci/Dockerfile-cfengine-build-package deleted file mode 100644 index d20c1a5d9..000000000 --- a/ci/Dockerfile-cfengine-build-package +++ /dev/null @@ -1,10 +0,0 @@ -FROM ubuntu:20.04 -RUN cat /etc/resolv.conf -RUN bash -c 'echo "test" >/dev/tcp/archive.ubuntu.com/80' -RUN apt-get update -y && apt-get install -y systemd wget sudo -# some ways of debugging update problems below, uncomment to try, see ENT-11871 for archive.ubuntu.com flakes -#RUN apt-get update -y -o Debug::Acquire::http=true -#RUN apt-get install -y -o Debug::Acquire::http=true systemd wget sudo -ADD setup.sh / -RUN /bin/bash -c '/setup.sh 2>&1 > setup.log' -CMD [ "/lib/systemd/systemd" ] diff --git a/ci/Dockerfile-cfengine-deployment-tests b/ci/Dockerfile-cfengine-deployment-tests deleted file mode 100644 index 3cc511d1c..000000000 --- a/ci/Dockerfile-cfengine-deployment-tests +++ /dev/null @@ -1,3 +0,0 @@ -FROM ubuntu:20.04 -RUN apt-get update -y && apt-get install -y systemd sudo -CMD [ "/lib/systemd/systemd" ] diff --git a/ci/README b/ci/README deleted file mode 100644 index ba9ebad15..000000000 --- a/ci/README +++ /dev/null @@ -1,73 +0,0 @@ -In this 'buildscripts/ci' directory you will find the means to build cfengine packages. -Note that you should ensure that the various projects are all on the same version: core, enterprise, masterfiles, nova, mission-portal all should be on say 3.21.x or 3.18.x or master. - -Currently a full build with no dependencies cached takes around 53 minutes with deps and packaging. - -Two options: containerize build or "normal" machine (such as virtual machine or actual hardware). - -The build is designed for ubuntu-20.04 but could be adjusted in various shell scripts for other platforms. (TODO: do this!) - -# containerized build -./clean.sh # cleans any leftover docker bits -./run.sh # builds a docker image, sets it up, runs it in the background, copies local cache into container, runs the build and saves the results -./shell.sh # runs bash in the container for debugging - -See /data/buildscripts/ci/build.sh for required environment variables and steps to try manually - -# virtual or real machine - -For virtual machine such as with vagrant, at $NTECH_ROOT (aka top-level directory containing all CFEngine repositories), init an ubuntu-20.04 vagrant machine so it has access to all your repositories. - -vagrant init ubuntu/focal64 -vagrant ssh - -# note however, that currently you will need to copy /vagrant to a non shared filesystem most likely as vboxsf type doesn't support required hard and soft links for packaging :( -set -ex -repos="\ -buildscripts \ -core \ -enterprise \ -masterfiles \ -mission-portal \ -nova \ -" - -mkdir -p $HOME/workspace -pwd -for repo in $repos; do - pwd - cp -R "$repo" $HOME/workspace -done - -# always be careful of trailing slashes with rsync, check it again if you are typing! -rsync -avz /vagrant/cache/ $HOME/.cache/ - - -And then do the following as you would on a real machine: - -cd $HOME/workspace -./buildscripts/ci/setup.sh # install needed dependencies/packages/etc -./buildscripts/ci/setup-projects.sh # items which must be done AFTER the container is created with setup.sh, in non-container case must be executed second -./buildscripts/ci/build.sh # run the build, should generate a package - -don't use ./clean.sh ./run.sh or ./shell.sh those are specifically for containerized/docker build - -If you are running selenium tests in mission-portal, you might need to do a `make -C mission-portal clean` before creating packages as the selenium tests copy some things from the distribution into the repository directory that cause problems with packaging, such as the api directory from nova. - -# manual debugging on-host - -cat buildscripts/ci/build.sh -# now export the environment variables there (and adjust as needed) -export BUILD_TYPE=DEBUG -export ESCAPETEST=yes -export TEST_MACHINE=chroot - -then take each step one-at-a-time or re-run as needed - -./buildscripts/build-scripts/install-dependencies - -Note that you can provide an argument to install-dependencies to just build ONE dependency, such as - -./buildscripts/build-scripts/install-dependencies lmdb - -If you change the version of a dependency the cache for that should be skipped and the dep rebuilt from scratch. diff --git a/ci/README.md b/ci/README.md new file mode 100644 index 000000000..7a6d05907 --- /dev/null +++ b/ci/README.md @@ -0,0 +1,4 @@ +buildscripts/ci directory contains scripts used by continuous integration + +Make changes in this directory in the master branch and then a workflow at .github/workflows/mirror-ci.yml will create pull requests to mirror the changes to active LTS branches (specified in that yml file). + diff --git a/ci/build.sh b/ci/build.sh deleted file mode 100755 index b6feafec1..000000000 --- a/ci/build.sh +++ /dev/null @@ -1,43 +0,0 @@ -#!/usr/bin/env bash -# build cfengine hub package -set -ex -export PROJECT=nova -export NO_CONFIGURE=1 -export BUILD_TYPE=DEBUG -export ESCAPETEST=yes -export EXPLICIT_ROLE=hub -export TEST_MACHINE=chroot - -set +x # hide secrets -eval $(ssh-agent -s) -if [ -z "$SECRET" ]; then - echo "Need sftp cache ssh secret key. Provide with SECRET env variable" - exit 1 -else - echo "$SECRET" | ssh-add - -fi -ssh-add -l -set -x # stop hiding secrets - -time ./buildscripts/build-scripts/build-environment-check -time ./buildscripts/build-scripts/install-dependencies -time ./buildscripts/build-scripts/configure # 3 minutes locally -time ./buildscripts/build-scripts/generate-source-tarballs # 1m49 -time ./buildscripts/build-scripts/compile -time sudo apt remove -y 'cfbuild*' || true -time sudo apt remove -y 'cfengine-*' || true -time sudo rm -rf /var/cfengine -time sudo rm -rf /opt/cfengine -time ./buildscripts/build-scripts/install-dependencies -time ./buildscripts/build-scripts/package -sudo mkdir -p packages -sudo cp cfengine-nova-hub/*.deb packages/ || true -sudo cp cfengine-nova-hub/*.rpm packages/ || true - -# todo maybe save the cache cp -R ~/.cache buildscripts/ci/cache - -# clean up -time sudo apt remove -y 'cfbuild*' || true -time sudo apt remove -y 'cfengine-*' || true -time sudo rm -rf /var/cfengine -time sudo rm -rf /opt/cfengine diff --git a/ci/cfengine-masterfiles-3.21.4-1.pkg.tar.gz.sha256 b/ci/cfengine-masterfiles-3.21.4-1.pkg.tar.gz.sha256 deleted file mode 100644 index af35cc9a4..000000000 --- a/ci/cfengine-masterfiles-3.21.4-1.pkg.tar.gz.sha256 +++ /dev/null @@ -1 +0,0 @@ -a4b35ad85ec14dda49b93c1c91a93e09f4336d9ee88cd6a3b27d323c90a279ca cfengine-masterfiles-3.21.4-1.pkg.tar.gz diff --git a/ci/cfengine-masterfiles-3.21.5-1.pkg.tar.gz.sha256 b/ci/cfengine-masterfiles-3.21.5-1.pkg.tar.gz.sha256 deleted file mode 100644 index 887c16dba..000000000 --- a/ci/cfengine-masterfiles-3.21.5-1.pkg.tar.gz.sha256 +++ /dev/null @@ -1 +0,0 @@ -31d026f6583cc820add6f8cafc390115ced400c3b1d49992ced52cd1c6073a49 cfengine-masterfiles-3.21.5-1.pkg.tar.gz diff --git a/ci/clean-build-package.sh b/ci/clean-build-package.sh deleted file mode 100755 index 43988ccdb..000000000 --- a/ci/clean-build-package.sh +++ /dev/null @@ -1,14 +0,0 @@ -#!/usr/bin/env bash -set -ex -# clean up docker stuff -name=cfengine-build-package -# TODO: a softer clean might get into the container and run ./buildscripts/build-scripts/clean-buildmachine -if docker ps | grep $name; then - docker stop $name -fi -if docker ps -a | grep $name; then - docker rm $name -fi -if docker images | grep $name; then - docker rmi -f $name -fi diff --git a/ci/clean-deployment-tests.sh b/ci/clean-deployment-tests.sh deleted file mode 100755 index 30baf84d1..000000000 --- a/ci/clean-deployment-tests.sh +++ /dev/null @@ -1,6 +0,0 @@ -# clean up docker stuff -name=cfengine-deployment-tests -# TODO: a softer clean might get into the container and run ./buildscripts/build-scripts/clean-buildmachine -docker stop $name -docker rm $name -docker rmi $name diff --git a/ci/deployment-tests.sh b/ci/deployment-tests.sh deleted file mode 100755 index 8efedc28d..000000000 --- a/ci/deployment-tests.sh +++ /dev/null @@ -1,63 +0,0 @@ -#!/usr/bin/env bash -# shellcheck disable=SC2024 -# I am redirecting many sudo run commands to logfiles which can be owned by the non-priv user -# copied from mission-portal/ci/run.sh for selenium tests -# todo refactor to share some of this instead of copy/pasting -set -ex - -# find the dir one level up from here, home of all the repositories -COMPUTED_ROOT="$(readlink -e "$(dirname "$0")/../../")" -# NTECH_ROOT should be the same, but if available use it so user can do their own thing. -NTECH_ROOT=${NTECH_ROOT:-$COMPUTED_ROOT} -USER=${USER:-$(whoami)} - -# prepare artifacts dir -sudo mkdir -p "${NTECH_ROOT}/artifacts" -sudo chown "$USER" "${NTECH_ROOT}/artifacts" - -trap failure ERR -function failure() { - cd "${NTECH_ROOT}/artifacts" - if command cf-support; then - sudo cf-support --yes > $$.cfsupportlog 2>&1 || cat $$.cfsupportlog - else - cp /var/log/CFEngine-Install* . # ${NTECH_ROOT}/artifacts cd previously - fi - rm $$.cfsupportlog -} - -if [ ! -d /var/cfengine ]; then - # ci and local buildscripts should place built packages in $NTECH_ROOT/packages - sudo dpkg -i "$NTECH_ROOT"/packages/cfengine-nova-hub*deb -fi - - - -AGENT_LOG="${NTECH_ROOT}/artifacts/agent.log" -if [ -f "$AGENT_LOG" ]; then - mv "$AGENT_LOG" "${AGENT_LOG}.$(date +%s)" -fi -mkdir -p "${NTECH_ROOT}/artifacts" -touch "$AGENT_LOG" -if [ ! -f /var/cfengine/policy_server.dat ]; then - sudo /var/cfengine/bin/cf-agent -B "$(hostname -I | awk ' {print $1}')" >>"$AGENT_LOG" 2>&1 -fi - -# make artifacts directory to be slurped by CI (jenkins, github, ...) -mkdir -p "${NTECH_ROOT}/artifacts" - -{ - sudo /var/cfengine/bin/cf-agent -KIf update.cf - sudo /var/cfengine/bin/cf-agent -KI - sudo /var/cfengine/bin/cf-agent -KI -} >>"$AGENT_LOG" 2>&1 - -if grep -i error "$AGENT_LOG" >/dev/null; then - echo "FAIL test, errors in $AGENT_LOG" - grep -i error "$AGENT_LOG" -fi - -apt-get -y install python3-psycopg2 -export REPORTING_TEST_DELAY=5 -cd "${NTECH_ROOT}/nova/tests/reporting" -python3 deployment_test.py diff --git a/ci/docker-build-package.sh b/ci/docker-build-package.sh deleted file mode 100755 index 908b171dd..000000000 --- a/ci/docker-build-package.sh +++ /dev/null @@ -1,63 +0,0 @@ -#!/usr/bin/env bash -# run the build in a docker container -set -ex - -# find the dir two levels up from here, home of all the repositories -COMPUTED_ROOT="$(readlink -e "$(dirname "$0")/../../")" -# NTECH_ROOT should be the same, but if available use it so user can do their own thing. -NTECH_ROOT=${NTECH_ROOT:-$COMPUTED_ROOT} - -name=cfengine-build-package -label=PACKAGES_HUB_x86_64_linux_ubuntu_20 -export JOB_BASE_NAME=label=$label - - -docker build -t $name -f "${NTECH_ROOT}/buildscripts/ci/Dockerfile-$name" "${NTECH_ROOT}/buildscripts/ci" - -# add secret key to enable push up to sftp cache -set +x # hide secrets -if [ -n "$GH_ACTIONS_SSH_KEY_BUILD_ARTIFACTS_CACHE" ]; then - export SECRET="$GH_ACTIONS_SSH_KEY_BUILD_ARTIFACTS_CACHE" -else - if ! export SECRET="$(pass mystiko/developers/CFEngine/jenkins/sftp-cache.sec)"; then - echo "The sftp cache ssh secret key must be provided, either with environment variable GH_ACTIONS_SSH_KEY_BUILD_ARTIFACTS_CACHE or access to mystiko path developers/CFEngine/jenkins/sftp-cache.sec" - exit 1 - fi -fi -set -x # done hiding secrets -# send in JOB_BASE_NAME to enable use of retrieved or generated deps cache -docker run -d --env SECRET --env JOB_BASE_NAME --privileged -v "${NTECH_ROOT}":/data --name $name $name - -# copy local caches to docker container -mkdir -p "${NTECH_ROOT}/packages" -mkdir -p "${NTECH_ROOT}/cache" - -# setup host key trust -pubkey="build-artifacts-cache.cloud.cfengine.com,138.68.18.72 ecdsa-sha2-nistp256 AAAAE2VjZHNhLXNoYTItbmlzdHAyNTYAAAAIbmlzdHAyNTYAAABBBJhnAXjI9PMuRM3s0isYFH4SNZjKwq0E3VK+7YQKcL6aIxNhXjdJnNKAkh4MNlzZkLpFTYputUxKa1yPPrb5G/Y=" - -# ending with /. in srcpath copies contents to destpath -docker cp "${NTECH_ROOT}/cache/." $name:/root/.cache - -# in order for build-scripts/autogen to generate a revision file: -for i in core buildscripts buildscripts/deps-packaging enterprise nova masterfiles -do - docker exec -i $name bash -c "git config --global --add safe.directory /data/$i" -done - -# add build artifacts host public keys to container for use there -docker exec -i $name bash -c "mkdir -p ~/.ssh" -docker exec -i $name bash -c "echo $pubkey >> ~/.ssh/known_hosts" - -docker exec -i $name bash -c 'cd /data; ./buildscripts/ci/setup-projects.sh' -docker exec -i $name bash -c 'cd /data; ./buildscripts/ci/build.sh' - -# save back cache and packages to host for handling by CI and such -docker cp $name:/root/.cache/. "${NTECH_ROOT}/cache/" -docker cp $name:/data/packages/. "${NTECH_ROOT}/packages/" - -rc=1 # if we find no packages, fail -for f in packages/*.deb; do - [ -f "$f" ] && rc=0 - break -done -exit $rc diff --git a/ci/docker-deployment-tests.sh b/ci/docker-deployment-tests.sh deleted file mode 100755 index 35b9060d3..000000000 --- a/ci/docker-deployment-tests.sh +++ /dev/null @@ -1,28 +0,0 @@ -#!/usr/bin/env bash -# run the build in a docker container -set -ex - -# find the dir two levels up from here, home of all the repositories -COMPUTED_ROOT="$(readlink -e "$(dirname "$0")/../../")" -# NTECH_ROOT should be the same, but if available use it so user can do their own thing. -NTECH_ROOT=${NTECH_ROOT:-$COMPUTED_ROOT} - -name=cfengine-deployment-tests -# todo, check the image against the Dockerfile for up-to-date ness? -if ! docker images | grep $name; then - docker build -t $name -f "${NTECH_ROOT}/buildscripts/ci/Dockerfile-$name" . || true -fi - -# todo, check if already running and up-to-date? -# we want a fresh container, stop and remove any that exist by this $name -if docker ps -a | grep $name; then - docker ps -a | grep $name | awk '{print $1}' | xargs docker stop - docker ps -a | grep $name | awk '{print $1}' | xargs docker rm -fi -docker run -d --privileged -v "${NTECH_ROOT}":/data --name $name $name || true - -if [ ! -d "${NTECH_ROOT}/packages" ]; then - echo "${NTECH_ROOT}/packages directory should exist and have a cfengine-nova-hub package there" - exit 1 -fi -docker exec -i $name bash -c 'cd /data; ./buildscripts/ci/deployment-tests.sh' diff --git a/ci/docker.sh b/ci/docker.sh deleted file mode 120000 index 04af95afb..000000000 --- a/ci/docker.sh +++ /dev/null @@ -1 +0,0 @@ -docker-build-package.sh \ No newline at end of file diff --git a/ci/fix-buildhost.sh b/ci/fix-buildhost.sh index 520dd19fb..bd0c965dc 100755 --- a/ci/fix-buildhost.sh +++ b/ci/fix-buildhost.sh @@ -2,17 +2,19 @@ # it is expected that this file is sourced, not executed directly set -ex +# Resolve our own directory up front: the ci/ scripts sourced and run below live +# next to this file. Previously this was only computed in the centos-7 branch, +# leaving $my_dir empty for the linux-install-* calls further down. This file is +# sourced rather than executed, so BASH_SOURCE names it where $0 names the caller. +my_dir="$(dirname "${BASH_SOURCE[0]}")" +if command -v realpath >/dev/null; then + my_dir="$(realpath "$my_dir")" +fi + if [ -f /etc/os-release ]; then source /etc/os-release if [ "$ID" = "centos" ] && [ "$VERSION_ID" = "7" ]; then - if command -v realpath >/dev/null; then - my_path="$(realpath "${BASH_SOURCE[0]}")" - my_dir="$(dirname "$my_path")" - source "$my_dir"/centos-7-setup-devtoolset-11.sh - else - echo "FAIL: could not find realpath command on rhel/centos-7 to source needed centos-7-setup-devtoolset-11.sh" - exit 1 - fi + source "$my_dir"/centos-7-setup-devtoolset-11.sh fi fi @@ -23,8 +25,20 @@ if [ "$(uname)" = "HP-UX" ]; then export VUE fi +if [ -f /etc/profile ]; then + # running on the proxied host or not we want to make sure local customizations are taken + # e.g. ent-14014: custom build of ssh needed for build-artifacts-cache needed and /etc/profile has PATH=/opt/craig/bin:$PATH + . /etc/profile +fi + mkdir -p ~/.ssh -echo "build-artifacts-cache.cloud.cfengine.com ssh-ed25519 AAAAC3NzaC1lZDI1NTE5AAAAIGahpsY8Phk2+isBmuJQjjQVlh6BNL/Qetc14g26gowV" >> ~/.ssh/known_hosts +touch ~/.ssh/known_hosts +# Only the cache host is needed here; github.com is not contacted from a build +# host. Which key type gets used depends on the client, so pin all of them. +# Added one at a time, since this runs for every build on a reused host. +grep '^build-artifacts-cache' "$my_dir"/known_hosts | while read -r key; do + grep -qF "$key" ~/.ssh/known_hosts || echo "$key" >> ~/.ssh/known_hosts +done # /etc/profile can contain tricky things, on suse for example it includes a call to tty which will fail in CI # so only source /etc/profile where we absolutely need it. @@ -43,6 +57,36 @@ if command -v yum >/dev/null 2>/dev/null; then sudo yum erase -y openssl-devel || true fi +# leech2 build toolchain: rust + protoc. The build-host-setup policy installs +# these when a VM is imaged; install them here too so testing-pr builds on +# not-yet-reimaged hosts (and branches that change these deps) get what they +# need without a reimage. Each call is guarded by an already-installed check, +# and gated to the same platforms as the policy (ubuntu>=20, debian>=12, +# rhel/centos>=7). +if [ -f /etc/os-release ]; then + . /etc/os-release + os_major="${VERSION_ID%%.*}" + case "$ID" in + ubuntu) min_major=20 ;; + debian) min_major=12 ;; + rhel | centos) min_major=7 ;; + *) min_major="" ;; + esac + if [ -n "$min_major" ] && [ "${os_major:-0}" -ge "$min_major" ]; then + if [ ! -x /usr/local/bin/protoc ]; then + sh "$my_dir"/linux-install-protobuf.sh + fi + if [ ! -x /opt/rust/bin/rustc ]; then + # MinGW hosts also need the Windows cross-compilation target. + if [ -f /etc/cfengine-mingw-build-host.flag ]; then + sh "$my_dir"/linux-install-rust.sh x86_64-pc-windows-gnu + else + sh "$my_dir"/linux-install-rust.sh + fi + fi + fi +fi + # MinGW hosts build the MSI with wixl (build-scripts/package-msi) and inspect it # with msiinfo (msitools). uuidgen (uuid-runtime) derives deterministic MSI # GUIDs for reproducible builds (ENT-13792). Installed by the build-host-setup diff --git a/ci/initialize-build-host.sh b/ci/initialize-build-host.sh index 65c3e53bf..2bf81a3ef 100644 --- a/ci/initialize-build-host.sh +++ b/ci/initialize-build-host.sh @@ -371,8 +371,7 @@ then $RSYNC -e "$RSH" $HOME/buildscripts $login:. fi - # Copy the workspace. If there is no workspace defined, we are not in the - # job section yet. + echo Copy the workspace. If there is no workspace defined, we are not in the job section yet. if [ -n "$WORKSPACE" ] then $RSH $login rm -rf "$WORKSPACE_REMOTE" || true @@ -383,7 +382,17 @@ then exit 2 fi $RSH $login mkdir -p "$WORKSPACE_REMOTE" - $RSYNC -e "$RSH" "$WORKSPACE"/ $login:"$WORKSPACE_REMOTE"/ + echo "Copying the workspace to the build host" + start_spinner 600 + if $RSYNC -e "$RSH" "$WORKSPACE"/ $login:"$WORKSPACE_REMOTE"/; then + stop_spinner + echo "Finished copying the workspace to the build host" + else + EXIT_CODE=$? + echo "error: Failed to copy the workspace to the build host" + stop_spinner + exit $EXIT_CODE + fi fi # -------------------------------------------------------------------------- @@ -399,11 +408,12 @@ then # -------------------------------------------------------------------------- # Collect artifacts and cleanup. # -------------------------------------------------------------------------- - # Copy the workspace back after job has ended. + echo Copy the workspace back after job has ended. if [ -n "$WORKSPACE" ] then # This can take a very long time. So we need to prevent timeouts start_spinner 600 + echo "Copying the workspace back after job has ended" if $RSYNC -e "$RSH" $login:"$WORKSPACE_REMOTE"/ "$WORKSPACE"/; then stop_spinner echo "Finished copying the workspace back after job has ended" diff --git a/ci/known_hosts b/ci/known_hosts new file mode 100644 index 000000000..199c97d03 --- /dev/null +++ b/ci/known_hosts @@ -0,0 +1,16 @@ +# Pinned SSH host keys for the hosts CI connects to. Consumers grep out the +# host they need: github.com for source checkouts on an agent, and +# build-artifacts-cache for the dependency cache (used inside the build +# container and by ci/fix-buildhost.sh on the build hosts). +# +# All key types each host offers are listed, since which one is used depends on +# the client's HostKeyAlgorithms preference. +# +# ci/cfengine-build-host-setup.cf holds its own inline copy. That policy is being +# replaced by these scripts (ENT-14330), so it is not worth coupling to. +github.com ssh-ed25519 AAAAC3NzaC1lZDI1NTE5AAAAIOMqqnkVzrm0SdG6UOoqKLsabgH5C9okWi0dh2l9GKJl +github.com ecdsa-sha2-nistp256 AAAAE2VjZHNhLXNoYTItbmlzdHAyNTYAAAAIbmlzdHAyNTYAAABBBEmKSENjQEezOmxkZMy7opKgwFB9nkt5YRrYMjNuG5N87uRgg6CLrbo5wAdT/y6v0mKV0U2w0WZ2YB/++Tpockg= +github.com ssh-rsa AAAAB3NzaC1yc2EAAAADAQABAAABgQCj7ndNxQowgcQnjshcLrqPEiiphnt+VTTvDP6mHBL9j1aNUkY4Ue1gvwnGLVlOhGeYrnZaMgRK6+PKCUXaDbC7qtbW8gIkhL7aGCsOr/C56SJMy/BCZfxd1nWzAOxSDPgVsmerOBYfNqltV9/hWCqBywINIR+5dIg6JTJ72pcEpEjcYgXkE2YEFXV1JHnsKgbLWNlhScqb2UmyRkQyytRLtL+38TGxkxCflmO+5Z8CSSNY7GidjMIZ7Q4zMjA2n1nGrlTDkzwDCsw+wqFPGQA179cnfGWOWRVruj16z6XyvxvjJwbz0wQZ75XK5tKSb7FNyeIEs4TT4jk+S4dhPeAUC5y+bDYirYgM4GC7uEnztnZyaVWQ7B381AK4Qdrwt51ZqExKbQpTUNn+EjqoTwvqNj4kqx5QUCI0ThS/YkOxJCXmPUWZbhjpCg56i+2aB6CmK2JGhn57K5mj0MNdBXA4/WnwH6XoPWJzK5Nyu2zB3nAZp+S5hpQs+p1vN1/wsjk= +build-artifacts-cache.cloud.cfengine.com ssh-ed25519 AAAAC3NzaC1lZDI1NTE5AAAAIGahpsY8Phk2+isBmuJQjjQVlh6BNL/Qetc14g26gowV +build-artifacts-cache.cloud.cfengine.com ssh-rsa AAAAB3NzaC1yc2EAAAADAQABAAABgQCdv55BmDmwEjN3izaL8intrSRJQglkv++TaQppopKCh5VkYuSpNj/W+x0vjxwL3+NNp4CAhOLYuGTFuUL8zz/H0kwWE06c3WjghpHS3NS1usiamVZN6uaJMGwDaq8fPB3WiiI/L5lLM8/ubXxfmta0UlVufHCiBH8pBQarAY5rdPDtITXzu56qIa3k9Ou7Si2r/1n37espzwsPxoBqVJg7BvzMV28MzxdmQpGP6puuPfi9tvYbtnF788le3jvGOc+3GOiwtXsv44y/PCJNhi7sFeUfxocuNbWXZ3x/UEfbN8IiUVZsUAuLQFeqr3pv4w28D+SvJHBMCFudygenmLc3th+typiFRmqam7UQif9Pa3e2FxX4ghTp1KNXBoCQluIk2j7wX9zXppSyUG6d7tPDzfu81lImuW34+bsZvYq+s+25vbAhSDdQe1lqG0Fdvvi+zbqrMYQuMfnInDrK52xNSZcfATWjudhmY6wiwdSS0XsBADmZsy3qf3ErdEabqQk= +build-artifacts-cache.cloud.cfengine.com ecdsa-sha2-nistp256 AAAAE2VjZHNhLXNoYTItbmlzdHAyNTYAAAAIbmlzdHAyNTYAAABBBIzU5+SoC4gbtV3Wfw4oB6oMs5RYKGFCiS0lVeN4XQlAM8UjvyUUSflytf/vQEANv1OJs5vicslRn/iPlrvF8Mk= diff --git a/ci/linux-install-groovy.sh b/ci/linux-install-groovy.sh index 3858c76d0..5cedb0dfb 100755 --- a/ci/linux-install-groovy.sh +++ b/ci/linux-install-groovy.sh @@ -3,10 +3,10 @@ groovy_version=5.0.3 groovy_zip="apache-groovy-binary-$groovy_version.zip" cd /opt rm -rf apache-groovy-binary*zip -wget https://groovy.jfrog.io/artifactory/dist-release-local/groovy-zips/"$groovy_zip" +wget --quiet https://groovy.jfrog.io/artifactory/dist-release-local/groovy-zips/"$groovy_zip" echo "9d711dcb1dea94df9119558365beb6ac2909a22e30b58ae31de8bcb0dcf33698" "$groovy_zip" > "$groovy_zip".sha256 sha256sum -c "$groovy_zip".sha256 -unzip -o "$groovy_zip" +unzip -q -o "$groovy_zip" ln -sf /opt/groovy-"$groovy_version"/bin/groovy /usr/bin/ echo "export JAVA_HOME=/usr" >> /etc/profile . /etc/profile diff --git a/ci/linux-install-jdk.sh b/ci/linux-install-jdk.sh index 849afd737..1c714eab5 100755 --- a/ci/linux-install-jdk.sh +++ b/ci/linux-install-jdk.sh @@ -9,15 +9,15 @@ install_jdk() { baseurl=https://download.oracle.com/java/21/archive/ major_version=21 baseurl="https://download.oracle.com/java/${major_version}/archive/" - version=21.0.11 + version=21.0.12 if uname -m | grep aarch64; then tarball=jdk-${version}_linux-aarch64_bin.tar.gz # checksum from https://download.oracle.com/java/${major_version}/archive/jdk-${version}_linux-aarch64_bin.tar.gz.sha256 - sha=2ebe89cad767abba83fb0b8cedd2d2d9bcbf947315fde78f7263a57a24f43b96 + sha=a666a601e229215642e8dbd060d866d4925b58b68c0f7f1bd475765bab94e193 else tarball=jdk-${version}_linux-x64_bin.tar.gz # checksum from https://download.oracle.com/java/${major_version}/latest/jdk-${version}_linux-x64_bin.tar.gz.sha256 - sha=e1c25a83f9e2e374c93e0c29cc3d98a947621ae0fefa4a8d932951eb160c47c3 + sha=33cc8a4ba4163b003bbf3516824861ee49e7295e6a2879ec91316c2aead78b80 fi wget --quiet "$baseurl$tarball" echo "$sha $tarball" | sha256sum --check - diff --git a/ci/linux-install-jdk21.sh b/ci/linux-install-jdk21.sh deleted file mode 100755 index ede0d5cf8..000000000 --- a/ci/linux-install-jdk21.sh +++ /dev/null @@ -1,20 +0,0 @@ -#!/usr/bin/env bash -set -e -# install jdk "manually" -# depending on os, might want to do something like `apt remove default-jre openjdk-*-jre-*` -cd /opt -wget https://download.java.net/java/GA/jdk21.0.1/415e3f918a1f4062a0074a2794853d0d/12/GPL/openjdk-21.0.1_linux-x64_bin.tar.gz -echo "7e80146b2c3f719bf7f56992eb268ad466f8854d5d6ae11805784608e458343f openjdk-21.0.1_linux-x64_bin.tar.gz" | sha256sum --check - -sudo tar xf openjdk-21.0.1_linux-x64_bin.tar.gz -sudo tee /etc/profile.d/jdk.sh << EOF -export JAVA_HOME=/opt/jdk-21.0.1 -export PATH=\$PATH:\$JAVA_HOME/bin -EOF -sudo chown -R root:jenkins /opt/jdk-21.0.1 -sudo chmod -R g+rx /opt/jdk-21.0.1 -if command -v update-alternatives; then - sudo update-alternatives --install /usr/bin/java java /opt/jdk-21.0.1/bin/java 9999 -else - sudo ln -s /opt/jdk-21.0.1/bin/java /usr/bin/java -fi -cd - diff --git a/ci/setup-cfengine-build-host.sh b/ci/setup-cfengine-build-host.sh index 57ce89c9c..9bf06059c 100755 --- a/ci/setup-cfengine-build-host.sh +++ b/ci/setup-cfengine-build-host.sh @@ -1,6 +1,7 @@ #!/usr/bin/env bash shopt -s expand_aliases -thisdir="$(dirname "$0")" +# absolute because this script changes directory below +thisdir="$(cd "$(dirname "$0")" && pwd)" # handle env cfengine_role if [ -n "$cfengine_role" ]; then @@ -14,12 +15,34 @@ if [ "$(id -u)" != "0" ]; then exit 1 fi +# Fixes and names just the root owned files. chown -R over the whole tree clears +# setuid bits, which stripped /usr/bin/sudo inside every image in the rootless +# container store under /home/jenkins. +# +# chown -h: to avoid following symlinks +# -path /home/jenkins/testmachine-chroot --prune: do not touch this directory +function chown-root-owned-to-jenkins() { + root_owned=$(find /home/jenkins -path /home/jenkins/testmachine-chroot -prune -o -user root -print 2>/dev/null | head -n 20) + if [ -n "$root_owned" ]; then + echo "Root owned files in /home/jenkins (first 20), chowning all to jenkins:" + echo "$root_owned" + find /home/jenkins -path /home/jenkins/testmachine-chroot -prune -o -user root -exec chown -h jenkins {} \; + fi +} + ls -la /home/ if ! id -u jenkins; then useradd jenkins -p jenkins fi mkdir -p /home/jenkins +# Work where root owns the directory. Called from the jenkins home, this script +# used to leave the masterfiles tarball, an extracted masterfiles/, a core clone +# and promises.log there owned by root, which is what the chown -R was for. +setupdir=/var/tmp/cfengine-build-host-setup +mkdir -p "$setupdir" +cd "$setupdir" + # The following is copied from prepare-testmachine-chroot CHROOT_ROOT=/home/jenkins/testmachine-chroot/ fuser -k "$CHROOT_ROOT" >/dev/null 2>&1 || true @@ -27,8 +50,8 @@ fuser -k "$CHROOT_ROOT" >/dev/null 2>&1 || true umount "${CHROOT_ROOT}proc" >/dev/null 2>&1 || true # ENT-14386 often it seems we are experiencing a race condition with this script and something else causing trouble -if ! chown -R jenkins /home/jenkins; then - echo "ENT-14386 some trouble chown -R jenkins /home/jenkins, current processes are:" +if ! chown-root-owned-to-jenkins; then + echo "ENT-14386 some trouble chowning /home/jenkins, current processes are:" ps -efl fi @@ -78,7 +101,7 @@ function cleanup() { ps -efl | grep cf fi ls -l /home - chown -R jenkins /home/jenkins + chown-root-owned-to-jenkins echo "Done with cleanup()" } @@ -110,16 +133,21 @@ if [ -f /etc/os-release ]; then alias software='yum install --assumeyes' alias erase-packages='yum erase --assumeyes' elif grep -q debian /etc/os-release; then - DEBIAN_FRONTEND=noninteractive apt update + # Acquire::Retries because the archive mirrors sometimes return transient 503s + DEBIAN_FRONTEND=noninteractive apt -o Acquire::Retries=3 update --yes --quiet # sometimes the /boot partition is too small to handle kernel upgrade regenerations of initrd and related files on ubuntu, so allow failure first - DEBIAN_FRONTEND=noninteractive apt upgrade --yes || true + DEBIAN_FRONTEND=noninteractive apt -o Acquire::Retries=3 upgrade --yes --quiet || true DEBIAN_FRONTEND=noninteractive apt autoremove --yes # and now perform the upgrade a second time after hopefully autoremove cleans up /boot partition of kernel files that cause failure - DEBIAN_FRONTEND=noninteractive apt upgrade --yes + DEBIAN_FRONTEND=noninteractive apt -o Acquire::Retries=3 upgrade --yes DEBIAN_FRONTEND=noninteractive apt autoremove --yes - alias software='DEBIAN_FRONTEND=noninteractive apt install --yes' + + echo "remove unattended-upgrades to increase reliability of apt operations in scripts" + DEBIAN_FRONTEND=noninteractive apt purge --yes unattended-upgrades + + alias software='DEBIAN_FRONTEND=noninteractive apt -o Acquire::Retries=3 install --yes' alias erase-packages='DEBIAN_FRONTEND=noninteractive apt purge --yes' elif grep -q suse /etc/os-release; then zypper -n update @@ -171,7 +199,7 @@ if [ -f /etc/cfengine-bootstrap-pr-host.flag ]; then exit fi -if [ -f /etc/cfengine-containers-host.flag ]; then +if [ -f /etc/cfengine-containers-host.flag ] || [ -f /etc/cfengine-docker-host.flag ]; then "$thisdir"/setup-ci-host.sh exit fi @@ -297,16 +325,17 @@ cp -a masterfiles/* /var/cfengine/inputs/ ( cd "$thisdir" policy=./cfengine-build-host-setup.cf + promises="$setupdir"/promises.log # just to be sure, make policy read/write for our user only to avoid errors when running chmod 600 "$policy" - /var/cfengine/bin/cf-agent -KIf "$policy" -b cfengine_build_host_setup | tee promises.log - grep -i error: promises.log && exit 1 - /var/cfengine/bin/cf-agent -KIf "$policy" -b cfengine_build_host_setup | tee -a promises.log - grep -i error: promises.log && exit 1 - /var/cfengine/bin/cf-agent -KIf "$policy" -b cfengine_build_host_setup | tee -a promises.log - grep -i error: promises.log && exit 1 + /var/cfengine/bin/cf-agent -KIf "$policy" -b cfengine_build_host_setup | tee "$promises" + grep -i error: "$promises" && exit 1 + /var/cfengine/bin/cf-agent -KIf "$policy" -b cfengine_build_host_setup | tee -a "$promises" + grep -i error: "$promises" && exit 1 + /var/cfengine/bin/cf-agent -KIf "$policy" -b cfengine_build_host_setup | tee -a "$promises" + grep -i error: "$promises" && exit 1 echo "Done evaluating policy. End of promises.log:" - tail promises.log + tail "$promises" ) cleanup diff --git a/ci/setup-ci-host.sh b/ci/setup-ci-host.sh index c88f5d7a3..b646fb9d5 100755 --- a/ci/setup-ci-host.sh +++ b/ci/setup-ci-host.sh @@ -1,13 +1,43 @@ #!/usr/bin/env bash set -e -shopt -s expand_aliases thisdir="$(dirname "$0")" -packages="" # a space separated list of packages to install +_packages="" # a space separated list of packages to install function add-pkg() { - packages+=" $*" + _packages+=" $*" } +function install-packages() { + # note that "packages" is a function defined later during OS/distribution discovery + # shellcheck disable=SC2086 + packages $_packages +} + +function file-line() +{ + file=$1 + line=$2 + + touch "$file" + if ! grep -q "$line" "$file"; then + echo "Adding $line to $file" + echo "$line" >> "$file" + fi +} + +function github-known-hosts() +{ + echo "ensuring github hostkeys are added to /home/jenkins/.ssh/known_hosts" + grep '^github.com' "$thisdir"/known_hosts | while read -r key; do + file-line /home/jenkins/.ssh/known_hosts "$key" + done + chown jenkins /home/jenkins/.ssh/known_hosts + chmod 0600 /home/jenkins/.ssh/known_hosts +} + +echo "ensuring that github.com hostkeys are in ~/.ssh/known_hosts" +github-known-hosts + # we setup some vars for platform versions to make it easier to make choice later # default version is 0 so that a check can be [ "$debian" -gt "12" ] and that will skip non-debians and such redhat=0 @@ -25,13 +55,13 @@ if [ -f /etc/os-release ]; then source /etc/os-release if grep -q rhel /etc/os-release; then yum update --assumeyes - alias packages='yum install --assumeyes' + function packages() { yum install --assumeyes "$@"; } redhat="$VERSION_ID" elif grep -q debian /etc/os-release; then - alias packages='DEBIAN_FRONTEND=noninteractive apt install --yes' + function packages() { DEBIAN_FRONTEND=noninteractive apt install --quiet --yes "$@"; } debian="$VERSION_ID" elif grep -q suse /etc/os-release; then - alias packages='zypper install -y' + function packages() { zypper install -y "$@"; } # shellcheck disable=SC2034 suse="$VERSION_ID" else @@ -39,7 +69,7 @@ if [ -f /etc/os-release ]; then exit 1 fi elif [ -f /etc/redhat-release ]; then - alias packages='yum install --assumeyes' + function packages() { yum install --assumeyes "$@"; } # shellcheck disable=SC1091 source /etc/redhat-release redhat="$VERSION_ID" @@ -57,6 +87,9 @@ if [ -f /etc/cfengine-containers-host.flag ]; then add-pkg make add-pkg parallel add-pkg podman + + install-packages + if ! command -v groovy; then bash "$thisdir"/linux-install-groovy.sh fi @@ -75,6 +108,51 @@ EOF chmod 400 /etc/sudoers.d/999-local chown root:root /etc/sudoers.d/999-local fi + exit 0 +fi + +# Hosts for the build-in-container job (ENT-14361). They only run containers: +# the target platform comes from the image, so none of the native build +# toolchain below is wanted here. +if [ -f /etc/cfengine-docker-host.flag ]; then + case "$ID" in + debian | ubuntu) ;; + *) + echo "docker host setup supports debian and ubuntu, not $ID" + exit 1 + ;; + esac + + # Docker CE from upstream rather than the distribution's docker.io, since + # build-in-container.py passes --build-context and so needs BuildKit. + # Follows https://docs.docker.com/engine/install/ubuntu/ ("Install using the + # apt repository"); the debian page has the same steps with the other URI. + # Installed here rather than with add-pkg: curl is needed just below, and the + # repository has to exist before install-packages runs. + packages ca-certificates curl + install -m 0755 -d /etc/apt/keyrings + curl -fsSL "https://download.docker.com/linux/$ID/gpg" -o /etc/apt/keyrings/docker.asc + chmod a+r /etc/apt/keyrings/docker.asc + tee /etc/apt/sources.list.d/docker.sources << EOF +Types: deb +URIs: https://download.docker.com/linux/$ID +Suites: ${UBUNTU_CODENAME:-$VERSION_CODENAME} +Components: stable +Architectures: $(dpkg --print-architecture) +Signed-By: /etc/apt/keyrings/docker.asc +EOF + apt-get -qy update + + # docker-compose-plugin, the fifth package the documented command installs, + # is deliberately left out: nothing we run calls docker compose. + add-pkg containerd.io + add-pkg docker-buildx-plugin + add-pkg docker-ce + add-pkg docker-ce-cli + add-pkg git # the pipeline checks the source repos out on the agent + add-pkg jq + add-pkg python3 # runs build-in-container.py + add-pkg rsync fi if [ "$redhat" != 0 ]; then @@ -165,12 +243,9 @@ if [ "$redhat" != 0 ]; then fi -# packages is a dynamic alias set near the top of this script -# ^^^ we want space separated package names as separate args, not one arg with the space separated list whoami set -x -# shellcheck disable=SC2086 -packages $packages +install-packages set +x if mount | grep '/tmp'; then @@ -187,11 +262,31 @@ fi "$thisdir"/linux-install-jdk.sh # the script should skip if sufficient java is already installed -# leech2 build toolchain host -if [ "$ubuntu" -ge 20 ] || [ "$debian" -ge 12 ] || [ "$redhat" -ge 7 ]; then - "$thisdir"/linux-install-protobuf.sh - # TODO if mingw then pass along x86_64-pc-windows-gnu as an arg to install rust - "$thisdir"/linux-install-rust.sh +if [ -f /etc/cfengine-docker-host.flag ]; then + systemctl enable --now docker + + # Give jenkins access to the docker socket, per + # https://docs.docker.com/engine/install/linux-postinstall/. + groupadd -f docker + usermod -aG docker jenkins + + # Dependency cache root for build-in-container.py's --cache-dir. Outside any + # workspace so that cleanWs() cannot wipe it between builds. + install -d -o jenkins -g jenkins /home/jenkins/cfengine-build-cache + + docker --version + docker buildx version + sudo -u jenkins docker info +fi + +# leech2 build toolchain host. Not on a docker host, where the toolchain belongs +# in the build images. +if [ ! -f /etc/cfengine-docker-host.flag ]; then + if [ "$ubuntu" -ge 20 ] || [ "$debian" -ge 12 ] || [ "$redhat" -ge 7 ]; then + "$thisdir"/linux-install-protobuf.sh + # TODO if mingw then pass along x86_64-pc-windows-gnu as an arg to install rust + "$thisdir"/linux-install-rust.sh + fi fi if [ "$redhat" -ge 7 ]; then diff --git a/ci/setup-projects.sh b/ci/setup-projects.sh deleted file mode 100755 index 10bbec198..000000000 --- a/ci/setup-projects.sh +++ /dev/null @@ -1,60 +0,0 @@ -#!/usr/bin/env bash - -echo "=== tool versions (npm, node, composer) ===" -which npm -npm --version -which node -node --version -which composer -composer --version - -set -ex -( -if test -f "mission-portal/public/scripts/package.json"; then - cd mission-portal/public/scripts - # install dependencies from npmjs - npm ci - # build react components - npm run build - # remove the packages specified in devDependencies - npm prune --omit=dev -fi -) - -# install composer and friends -( -if test -f "mission-portal/composer.json"; then - cd mission-portal - # install PHP dependencies from composer - composer install --no-dev -fi -) - -( -if test -f "nova/api/http/composer.json"; then - cd nova/api/http/ - # install PHP dependencies from composer - composer install --ignore-platform-reqs --no-dev -fi -) - -( -if test -f "mission-portal/public/themes/default/bootstrap/cfengine_theme.less"; then - cd mission-portal/public/themes/default/bootstrap - npx -p less lessc --compress ./cfengine_theme.less ./compiled/css/cfengine.less.css -fi -) - -( -if test -f "mission-portal/ldap/composer.json"; then - cd mission-portal/ldap - # install PHP dependencies from composer - composer install --no-dev -fi -) - -# packages needed for autogen are installed in setup.sh -NO_CONFIGURE=1 PROJECT=nova ./buildscripts/build-scripts/autogen - -# remove unwanted dependencies -sudo apt-get -qy purge libltdl-dev libltdl7 #libtool diff --git a/ci/setup.sh b/ci/setup.sh deleted file mode 100755 index 6d52e31fd..000000000 --- a/ci/setup.sh +++ /dev/null @@ -1,44 +0,0 @@ -# setup build host on ubuntu 20 -set -ex -PREFIX=/var/cfengine - -# Github Actions provides machines with various packages installed, -# what confuses our build system into thinking that it's an RPM distro. -sudo rm -f /bin/rpm - -# Install dependencies -sudo apt-get update -qy - -# install apt-utils so that debconf can configure installed packages -sudo apt-get install -qy apt-utils - -# git is needed for build-scripts/autogen to determine revision for such things as deps-packaging -sudo apt-get install -qy git - -# python3-pip is needed for cfengine-nova-hub.deb packaging -sudo apt-get install -qy python3 python3-pip - -# Install psycopg2 -apt-get -y install python3-psycopg2 - -# install composer and friends -sudo apt-get -qy install curl php7.4-cli php7.4-curl php7.4-zip php7.4-mbstring php7.4-xml php7.4-gd composer php7.4-ldap -# packages needed for autogen -sudo apt-get -qy install git autoconf automake m4 make bison flex \ - binutils libtool gcc g++ libc-dev libpam0g-dev python3 psmisc - -# packages needed for buildscripts -sudo apt-get -qy install libncurses5 rsync -# packages needed for building -sudo apt-get -qy install bison flex binutils build-essential fakeroot ntp \ - dpkg-dev libpam0g-dev python3 debhelper pkg-config psmisc nfs-common - -# remove unwanted packages -sudo apt-get -qq purge apache* "postgresql*" redis* - -# packages needed for installing Mission portal dependencies -# remove any nodejs or node- packages currently in place -sudo apt-get remove -qy 'nodejs*' 'node-*' -# replace with exact version we want -wget -O - https://deb.nodesource.com/setup_20.x | sudo -E bash - -sudo apt-get install -qy nodejs diff --git a/ci/shell.sh b/ci/shell.sh deleted file mode 100755 index e5f5d8171..000000000 --- a/ci/shell.sh +++ /dev/null @@ -1,2 +0,0 @@ -# shell into the docker container -docker exec -it cfengine-build-package bash