Skip to content

EdenGCP

EdenGCP #17

Workflow file for this run

---
name: EdenGCP
on: # yamllint disable-line rule:truthy
workflow_run:
workflows:
- Publish
types:
- completed
concurrency:
group: ${{ github.workflow }}
# yamllint disable rule:line-length
jobs:
integration:
name: Integration test (${{ matrix.backend }};${{ matrix.hv }};${{ matrix.fs }})
runs-on: ubuntu-22.04
strategy:
fail-fast: false
matrix:
backend: ["gcp", "rol"]
hv: ["kvm", "xen"]
fs: ["zfs", "ext4"]
steps:
- name: Check
run: |
for addr in $(ip addr list|sed -En -e 's/.*inet ([0-9.]+).*/\1/p')
do
if echo "$addr" | grep -q -E "10.11.(12|13).[0-9]+"; then
echo "$addr overlaps with test"; exit 1
fi
if echo "$addr" | grep -q -E "10.8.0.[0-9]+"; then
echo "$addr overlaps with vpn"; exit 1
fi
done
sudo df -h
sudo swapoff -a
sudo free
- name: Check RoL secrets
if: matrix.backend == 'rol'
run: |
if [ -z "$ROL_API_URL" ]; then echo "::error::ROL_API_URL is empty" && exit 1; fi
if [ -z "$ROL_API_KEY" ]; then echo "::error::ROL_API_KEY is empty" && exit 1; fi
if [ -z "$ROL_PROJECT" ]; then echo "::error::ROL_PROJECT is empty" && exit 1; fi
if [ -z "$ROL_OVPN_CONF_BASE64" ]; then echo "::error::ROL_OVPN_CONF_BASE64 is empty" && exit 1; fi
env:
ROL_API_URL: ${{ secrets.ROL_API_URL }}
ROL_API_KEY: ${{ secrets.ROL_API_KEY }}
ROL_PROJECT: ${{ secrets.ROL_PROJECT }}
ROL_OVPN_CONF_BASE64: ${{ secrets.ROL_OVPN_CONF_BASE64 }}
- name: Setup packages
run: |
sudo apt update
sudo apt install -y qemu binfmt-support qemu-user-static qemu-system-x86 qemu-system-aarch64 qemu-utils openvpn curl jq
- name: GCP Set up Google Cloud SDK
if: matrix.backend == 'gcp'
uses: google-github-actions/setup-gcloud@v0.5.0
with:
project_id: ${{ secrets.GCP_PROJECT_ID }}
- id: 'gcpauth'
if: matrix.backend == 'gcp'
name: GCP Auth to Google Cloud SDK
uses: google-github-actions/auth@v0.4.1
with:
project_id: ${{ secrets.GCP_PROJECT_ID }}
credentials_json: ${{ secrets.GCP_SA_KEY }}
create_credentials_file: true
- name: GCP Clean
if: matrix.backend == 'gcp'
run: |
gcloud compute instances delete eve-edengcp-actions-${{ matrix.hv }}-${{ matrix.fs }}-${{github.run_number}} -q --zone=us-west1-a || echo "Does not exist"
gcloud compute images delete eve-edengcp-actions-${{ matrix.hv }}-${{ matrix.fs }}-${{github.run_number}} -q || echo "Does not exist"
- name: Connect VPN
id: connect_vpn
timeout-minutes: 1
run: |
echo "$OVPN_GCP_FILE" | base64 -d > ./config_gcp.ovpn
echo "$OVPN_ROL_FILE" | base64 -d > ./config_rol.ovpn
sudo openvpn --config ./config_${{ matrix.backend }}.ovpn --daemon
until ip -f inet addr show tun0; do sleep 5; ip a; done
echo ::set-output name=tunnel_ip::$(ip -f inet addr show tun0 | sed -En -e 's/.*inet ([0-9.]+).*/\1/p')
env:
OVPN_GCP_FILE: ${{ secrets.OVPN_FILE }}
OVPN_ROL_FILE: ${{ secrets.ROL_OVPN_CONF_BASE64 }}
- name: Get EVE
uses: actions/checkout@v2
with:
path: 'eve'
# ROL introduced from Eden 0.4.0
# Conditions for backwards compatibility on old branches
- name: Prepare eden
run: |
if [ "${{ matrix.backend }}" == "rol" ] || ! [ -f ${{ github.workspace }}/eve/tests/eden/eden-version ]; then
EDEN_VERSION=lfedge/eden:0.7.0
else
EDEN_VERSION=$(cat ${{ github.workspace }}/eve/tests/eden/eden-version)
fi
docker run -v $PWD:/out $EDEN_VERSION cp -a /eden/. /out/
sudo chown -R $(whoami) .
- name: Eden setup
run: |
if [ "${{ matrix.backend }}" == "rol" ]; then
devmodel='general'
arch='arm64'
netboot='true'
tpm='false'
else
devmodel='GCP'
arch='amd64'
netboot='false'
tpm='true'
fi
./eden config add default --devmodel="${devmodel}" --arch="${arch}"
./eden config set default --key eve.tag --value="snapshot"
./eden config set default --key eve.hv --value ${{ matrix.hv }}
./eden config set default --key eve.tpm --value "${tpm}"
./eden config set default --key adam.eve-ip --value ${{ steps.connect_vpn.outputs.tunnel_ip }}
./eden config set default --key registry.ip --value ${{ steps.connect_vpn.outputs.tunnel_ip }}
./eden config set default --key=eden.tests --value=${{ github.workspace }}/eve/tests/eden
if [ "${{ matrix.fs }}" == "zfs" ]; then
if [ "${{ matrix.backend }}" == "gcp" ]; then
./eden config set default --key=eve.disks --value=4
fi
grub_options='set_global dom0_extra_args "$dom0_extra_args eve_install_zfs_with_raid_level "'
else
grub_options=''
fi
./eden setup -v debug --grub-options="${grub_options}" --netboot="${netboot}"
./eden start
- name: GCP Create VM
if: matrix.backend == 'gcp'
run: |
export ipv4=`curl https://api.ipify.org/?format=json | jq ".ip" -r`
./eden utils gcp firewall --source-range $ipv4/32 --name eve-edengcp-actions-${{ matrix.hv }}-${{ matrix.fs }}-${{github.run_number}} -k "${{ steps.gcpauth.outputs.credentials_file_path }}"
./eden utils gcp image --image-name eve-edengcp-actions-${{ matrix.hv }}-${{ matrix.fs }}-${{github.run_number}} -k "${{ steps.gcpauth.outputs.credentials_file_path }}" upload
./eden utils gcp vm --image-name eve-edengcp-actions-${{ matrix.hv }}-${{ matrix.fs }}-${{github.run_number}} --vm-name eve-edengcp-actions-${{ matrix.hv }}-${{ matrix.fs }}-${{github.run_number}} -k "${{ steps.gcpauth.outputs.credentials_file_path }}" run
sleep 100
BWD=$(./eden utils gcp vm get-ip --vm-name eve-edengcp-actions-${{ matrix.hv }}-${{ matrix.fs }}-${{github.run_number}} -k "${{ steps.gcpauth.outputs.credentials_file_path }}") || { echo "no IP, probably VM does not exist"; exit 1; }
echo "the IP is $BWD"
./eden utils gcp firewall -k "${{ steps.gcpauth.outputs.credentials_file_path }}" --source-range $BWD --name edengcp-actions-${{ matrix.hv }}-${{ matrix.fs }}-${{github.run_number}} || { echo "cannot set firewall"; exit 1; }
- name: RoL rent RPi4
id: rol
if: matrix.backend == 'rol'
timeout-minutes: 60
run: |
rent_id=$(./eden rol rent create -p "$ROL_PROJECT" -m raspberry --model pi_4_model_b_8gb -n GHAction-${{ github.run_number }}-snapshot-${{ matrix.hv }}-${{ matrix.fs }})
echo ::set-output name=id::$(echo $rent_id)
until [[ "$(./eden rol rent get -p "$ROL_PROJECT" -i $rent_id | jq -r .machineState)" == "Ready" ]]; do sleep 10; echo "Waiting for EVE to load"; done
env:
ROL_API_URL: ${{ secrets.ROL_API_URL }}
ROL_API_KEY: ${{ secrets.ROL_API_KEY }}
ROL_PROJECT: ${{ secrets.ROL_PROJECT }}
- name: Eden EVE onboard
run: |
./eden eve onboard
- name: Test
run: |
if [ "${{ matrix.backend }}" == "gcp" ]; then export EDEN_TEST=gcp; fi
EDEN_TEST_STOP=n ./eden test ${{ github.workspace }}/eve/tests/eden/workflow -v debug
- name: Collect logs
if: ${{ always() }}
run: |
./eden log --format json > trace.log || echo "no log"
./eden info --format json > info.log || echo "no info"
./eden metric --format json > metric.log || echo "no metric"
./eden netstat --format json > netstat.log || echo "no netstat"
docker logs eden_adam > adam.log 2>&1 || echo "no adam log"
if [ "${{ matrix.backend }}" == "gcp" ]; then
./eden utils gcp vm log --vm-name eve-edengcp-actions-${{ matrix.hv }}-${{ matrix.fs }}-${{github.run_number}} -k "${{ steps.gcpauth.outputs.credentials_file_path }}" > console.log || echo "no device log"
else
./eden rol rent console-output -p "$ROL_PROJECT" -i "${{ steps.rol.outputs.id }}" > console.log || echo "no device log"
fi
env:
ROL_API_URL: ${{ secrets.ROL_API_URL }}
ROL_API_KEY: ${{ secrets.ROL_API_KEY }}
ROL_PROJECT: ${{ secrets.ROL_PROJECT }}
- name: Log counting
if: ${{ always() }}
run: |
echo "::group::Total errors"
echo "$(jq '.severity' trace.log|grep err|wc -l)"
echo "::endgroup::"
echo "::group::Errors by source"
echo "errors by source: $(jq -s 'map(select(.severity|contains("err")))|group_by(.source)|map({"source": .[0].source, "total":length})|sort_by(.total)|reverse[]' trace.log)"
echo "::endgroup::"
echo "::group::Error log content duplicates"
echo "$(jq -s 'map(select(.severity | contains("err")))|group_by(.content)|map(select(length>1))' trace.log)"
echo "::endgroup::"
echo "::group::Error log function filename duplicates"
echo "$(jq -s 'map(select(.severity | contains("err")))|group_by(.filename)|map(select(length>10))|map({"source": .[0].source, "filename": .[0].filename, "function": .[0].function, "content": [.[].content], "total":length})|sort_by(.total)| reverse[]' trace.log)"
echo "::endgroup::"
echo "::group::Segfaults"
echo "$(jq -s 'map(select(.content | contains("segfault at")))' trace.log)"|tee segfaults.log
[ "$(jq length segfaults.log)" -gt 0 ] && echo "::warning::segfaults found, you can see them in Log counting->Segfaults section"
echo "::endgroup::"
- name: GCP Clean
if: ${{ always() }}
run: |
gcloud compute firewall-rules delete eve-edengcp-actions-${{ matrix.hv }}-${{ matrix.fs }}-${{github.run_number}} || echo "Does not exist"
gcloud compute firewall-rules delete edengcp-actions-${{ matrix.hv }}-${{ matrix.fs }}-${{github.run_number}} || echo "Does not exist"
gcloud compute instances delete eve-edengcp-actions-${{ matrix.hv }}-${{ matrix.fs }}-${{github.run_number}} -q --zone=us-west1-a || echo "Does not exist"
gcloud compute images delete eve-edengcp-actions-${{ matrix.hv }}-${{ matrix.fs }}-${{github.run_number}} -q || echo "Does not exist"
gsutil -o "Credentials:gs_service_key_file=${{ steps.gcpauth.outputs.credentials_file_path }}" rm gs://eve-live/eve-edengcp-actions-${{ matrix.hv }}-${{ matrix.fs }}-${{github.run_number}}.img.tar.gz || echo "Does not exists"
- name: RoL Clean
if: ${{ always() }}
run: |
if [ -z "${{ steps.rol.outputs.id }}" ]; then exit 0; fi
./eden rol rent close -p $ROL_PROJECT -i ${{ steps.rol.outputs.id }}
env:
ROL_API_URL: ${{ secrets.ROL_API_URL }}
ROL_API_KEY: ${{ secrets.ROL_API_KEY }}
ROL_PROJECT: ${{ secrets.ROL_PROJECT }}
- name: Store raw test results
if: ${{ always() }}
uses: actions/upload-artifact@v2
with:
name: eden-report-${{ matrix.backend }}-${{ matrix.hv }}-${{ matrix.fs }}
path: |
${{ github.workspace }}/trace.log
${{ github.workspace }}/info.log
${{ github.workspace }}/adam.log
${{ github.workspace }}/netstat.log
${{ github.workspace }}/metric.log
${{ github.workspace }}/console.log