diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index dbb3a2fab..62de92448 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -10,3 +10,7 @@ jobs: build_cfengine_hub_package: uses: ./.github/workflows/build-using-buildscripts.yml secrets: inherit + + deployment_tests: + uses: ./.github/workflows/deployment-tests.yml + secrets: inherit diff --git a/.github/workflows/deployment-tests.yml b/.github/workflows/deployment-tests.yml new file mode 100644 index 000000000..3ae60ce6c --- /dev/null +++ b/.github/workflows/deployment-tests.yml @@ -0,0 +1,123 @@ +name: Deployment tests for built package + +on: + workflow_call: + secrets: + GH_ACTIONS_SSH_DEPLOY_KEY_ENTERPRISE_REPO: + required: true + GH_ACTIONS_SSH_DEPLOY_KEY_NOVA_REPO: + required: true + GH_ACTIONS_SSH_DEPLOY_KEY_MISSION_PORTAL_REPO: + required: true + +jobs: + deployment_tests: + name: Run simple deployment tests + runs-on: ubuntu-20.04 + steps: + - name: Checkout Together Action + uses: actions/checkout@v3 + with: + repository: cfengine/together-javascript-action + ref: main + ssh-key: ${{ secrets.GH_ACTIONS_SSH_DEPLOY_KEY_TOGETHER_REPO }} + ssh-known-hosts: github.com + + - name: Action step + uses: ./ + id: together + with: + myToken: ${{ secrets.GITHUB_TOKEN }} + + - name: Checkout Core + uses: actions/checkout@v3 + with: + repository: cfengine/core + path: core + ref: ${{steps.together.outputs.core || github.base_ref}} + submodules: recursive + + - name: Checkout Masterfiles + uses: actions/checkout@v3 + with: + repository: cfengine/masterfiles + path: masterfiles + ref: ${{steps.together.outputs.masterfiles || github.base_ref}} + + - name: Checkout Buildscripts (current project) + uses: actions/checkout@v3 + with: + path: buildscripts + fetch-depth: 20 + + - name: Checkout Nova + uses: actions/checkout@v3 + with: + repository: cfengine/nova + path: nova + ref: ${{steps.together.outputs.nova || github.base_ref}} + ssh-key: ${{ secrets.GH_ACTIONS_SSH_DEPLOY_KEY_NOVA_REPO }} + ssh-known-hosts: github.com + + - name: Checkout Enterprise + uses: actions/checkout@v3 + with: + repository: cfengine/enterprise + path: enterprise + ref: ${{steps.together.outputs.enterprise || github.base_ref}} + submodules: recursive + ssh-key: ${{ secrets.GH_ACTIONS_SSH_DEPLOY_KEY_ENTERPRISE_REPO }} + ssh-known-hosts: github.com + + - name: Checkout Mission Portal + uses: actions/checkout@v3 + with: + repository: cfengine/mission-portal + path: mission-portal + ref: ${{steps.together.outputs.mission-portal || github.base_ref}} + submodules: recursive + ssh-key: ${{ secrets.GH_ACTIONS_SSH_DEPLOY_KEY_MISSION_PORTAL_REPO }} + ssh-known-hosts: github.com + + - name: get PACKAGE_SHA for package cache + run: echo "PACKAGE_SHA=$(mission-portal/ci/package-sha.sh)" | tee -a ${GITHUB_ENV} + + - name: get SHA of buildscripts/deps-packaging last commit + run: echo "DEPS_SHA=$(git log --pretty='format:%h' -1 -- .)" | tee -a ${GITHUB_ENV} + working-directory: buildscripts/deps-packaging + + - name: restore packages cache + uses: actions/cache/restore@v3 + with: + path: packages + key: packages-${{ env.PACKAGE_SHA }} + restore-keys: | + packages-${{ env.PACKAGE_SHA }} + + - name: Restore dependency cache + uses: actions/cache/restore@v3 + with: + path: cache + key: deps-${{ github.base_ref }}-${{ env.DEPS_SHA }} + restore-keys: | + deps-${{ github.base_ref }} + deps-master + deps + + - name: Build package in docker + run: test ! -f packages/cfe*deb && buildscripts/ci/docker-build-package.sh || true + + - name: Run deployment tests + run: test ! -f packages/cfe*deb && buildscripts/ci/docker-deployment-tests.sh || true + + - name: Save dependency cache + uses: actions/cache/save@v3 + with: + path: cache + key: deps-${{ github.base_ref }}-${{ env.DEPS_SHA }} + + - name: Save packages cache + uses: actions/cache/save@v3 + with: + path: packages + key: packages-${{ env.PACKAGE_SHA }} diff --git a/ci/Dockerfile-cfengine-deployment-tests b/ci/Dockerfile-cfengine-deployment-tests new file mode 100644 index 000000000..3cc511d1c --- /dev/null +++ b/ci/Dockerfile-cfengine-deployment-tests @@ -0,0 +1,3 @@ +FROM ubuntu:20.04 +RUN apt-get update -y && apt-get install -y systemd sudo +CMD [ "/lib/systemd/systemd" ] diff --git a/ci/clean.sh b/ci/clean-build-package.sh similarity index 100% rename from ci/clean.sh rename to ci/clean-build-package.sh diff --git a/ci/clean-deployment-tests.sh b/ci/clean-deployment-tests.sh new file mode 100755 index 000000000..30baf84d1 --- /dev/null +++ b/ci/clean-deployment-tests.sh @@ -0,0 +1,6 @@ +# 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 new file mode 100755 index 000000000..063f229d0 --- /dev/null +++ b/ci/deployment-tests.sh @@ -0,0 +1,52 @@ +#!/usr/bin/env bash +# 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)} + +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 + +# now that cfengine is probably installed, run cf-support if there is an error +trap failure ERR + +function failure() { + sudo mkdir -p "${NTECH_ROOT}/artifacts" + sudo chown $USER "${NTECH_ROOT}/artifacts" + cd "${NTECH_ROOT}/artifacts" + sudo cf-support --yes 2>&1 > $$.cfsupportlog || cat $$.cfsupportlog + rm $$.cfsupportlog +} + +AGENT_LOG="${NTECH_ROOT}/artifacts/agent.log" +if [ -f "$AGENT_LOG" ]; then + mv "$AGENT_LOG" "$AGENT_LOG".$(date +%s) +fi +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" +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 2>&1 >>"$AGENT_LOG" +sudo /var/cfengine/bin/cf-agent -KI 2>&1 >>"$AGENT_LOG" +sudo /var/cfengine/bin/cf-agent -KI 2>&1 >>"$AGENT_LOG" + +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 new file mode 100755 index 000000000..765d5b8c1 --- /dev/null +++ b/ci/docker-build-package.sh @@ -0,0 +1,36 @@ +#!/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 +# todo, check the image against the Dockerfile for up-to-date ness? +docker build -t $name -f "${NTECH_ROOT}/buildscripts/ci/Dockerfile-$name" . || true +# todo, check if already running and up-to-date? +docker run -d --privileged -v ${NTECH_ROOT}:/data --name $name $name || true + +# copy local caches to docker container +mkdir -p "${NTECH_ROOT}/packages" +mkdir -p "${NTECH_ROOT}/cache" +# 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 + +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/" + +# if no packages, then fail +[ -f packages/*.deb ] || [ -f packages/*.rpm ] diff --git a/ci/docker-deployment-tests.sh b/ci/docker-deployment-tests.sh new file mode 100755 index 000000000..341a22d82 --- /dev/null +++ b/ci/docker-deployment-tests.sh @@ -0,0 +1,28 @@ +#!/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 100755 index 765d5b8c1..000000000 --- a/ci/docker.sh +++ /dev/null @@ -1,36 +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 -# todo, check the image against the Dockerfile for up-to-date ness? -docker build -t $name -f "${NTECH_ROOT}/buildscripts/ci/Dockerfile-$name" . || true -# todo, check if already running and up-to-date? -docker run -d --privileged -v ${NTECH_ROOT}:/data --name $name $name || true - -# copy local caches to docker container -mkdir -p "${NTECH_ROOT}/packages" -mkdir -p "${NTECH_ROOT}/cache" -# 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 - -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/" - -# if no packages, then fail -[ -f packages/*.deb ] || [ -f packages/*.rpm ] diff --git a/ci/docker.sh b/ci/docker.sh new file mode 120000 index 000000000..04af95afb --- /dev/null +++ b/ci/docker.sh @@ -0,0 +1 @@ +docker-build-package.sh \ No newline at end of file