name: tunasync on: [push] jobs: build: name: Build runs-on: ubuntu-latest steps: - name: Set up Go 1.16 uses: actions/setup-go@v1 with: go-version: 1.16 id: go - name: Check out code into the Go module directory uses: actions/checkout@v2 - name: Get dependencies run: | go get -v -t -d ./cmd/tunasync go get -v -t -d ./cmd/tunasynctl - name: Build run: | make tunasync make tunasynctl - name: Keep artifacts uses: actions/upload-artifact@v1 with: name: tunasync-bin path: build-linux-amd64/ test: name: Test runs-on: ubuntu-latest services: registry: image: registry:2 ports: - 5000:5000 steps: - name: Setup test dependencies run: | sudo apt-get update sudo apt-get install -y cgroup-tools docker pull alpine:3.8 lssubsys -am sudo cgcreate -a $USER -t $USER -g cpu:tunasync sudo cgcreate -a $USER -t $USER -g memory:tunasync - name: Set up Go 1.16 uses: actions/setup-go@v1 with: go-version: 1.16 id: go - name: Check out code into the Go module directory uses: actions/checkout@v2 - name: Run Unit tests. run: | go install github.com/wadey/gocovmerge@latest TERM=xterm-256color make test - name: Run Additional Unit tests. run: | make build-test-worker sudo cgexec -g "*:/" bash -c "echo 0 > /sys/fs/cgroup/systemd/tasks; exec sudo -u $USER env USECURCGROUP=1 TERM=xterm-256color cgexec -g cpu,memory:tunasync ./worker.test -test.v=true -test.coverprofile profile2.cov -test.run TestCgroup" - name: Set up Docker Buildx uses: docker/setup-buildx-action@v1 with: driver-opts: network=host - name: Cache Docker layers uses: actions/cache@v2 if: github.event_name == 'push' with: path: /tmp/.buildx-cache key: ${{ runner.os }}-buildx-${{ github.sha }} restore-keys: | ${{ runner.os }}-buildx- - name: Cache Docker layers uses: actions/cache@v2 if: github.event_name == 'pull_request' with: path: /tmp/.buildx-cache key: ${{ runner.os }}-pr-${{ github.event.pull_request.head.user.login }}-buildx-${{ github.sha }} restore-keys: | ${{ runner.os }}-pr-${{ github.event.pull_request.head.user.login }}-buildx- ${{ runner.os }}-buildx- - name: Cache Docker layers if: github.event_name != 'push' && github.event_name != 'pull_request' run: | echo "I do not know how to setup cache" exit -1 - name: Prepare cache directory run: | mkdir -p /tmp/.buildx-cache - name: Build Docker image for uml rootfs uses: docker/build-push-action@v2 with: context: .umlrootfs file: .umlrootfs/Dockerfile push: true tags: localhost:5000/umlrootfs cache-from: type=local,src=/tmp/.buildx-cache cache-to: type=local,dest=/tmp/.buildx-cache - name: Fetch and install uml package run: | sudo apt-get update sudo apt-get install -y debian-archive-keyring sudo ln -sf /usr/share/keyrings/debian-archive-keyring.gpg /etc/apt/trusted.gpg.d/ echo "deb http://deb.debian.org/debian buster main" | sudo tee /etc/apt/sources.list.d/buster.list sudo apt-get update apt-get download user-mode-linux/buster sudo rm /etc/apt/sources.list.d/buster.list sudo apt-get update sudo mv user-mode-linux_*.deb /tmp/uml.deb sudo apt-get install --no-install-recommends -y /tmp/uml.deb sudo rm /tmp/uml.deb sudo apt-get install --no-install-recommends -y rsh-redone-client - name: Prepare uml environment run: | docker container create --name umlrootfs localhost:5000/umlrootfs sudo mkdir -p umlrootfs docker container export umlrootfs | sudo tar -xv -C umlrootfs docker container rm umlrootfs sudo cp -a --target-directory=umlrootfs/lib/ /usr/lib/uml/modules /bin/echo -e "127.0.0.1 localhost\n254.255.255.1 host" | sudo tee umlrootfs/etc/hosts sudo ip tuntap add dev umltap mode tap sudo ip addr add 254.255.255.1/24 dev umltap sudo ip link set umltap up - name: Start Uml run: | start_uml () { sudo bash -c 'linux root=/dev/root rootflags=/ rw rootfstype=hostfs mem=2G eth0=tuntap,umltap hostfs="$PWD/umlrootfs" con1=pts systemd.unified_cgroup_hierarchy=1 & pid=$!; echo "UMLINUX_PID=$pid" >> '"$GITHUB_ENV" } ( start_uml ) started=0 for i in $(seq 1 60); do if ping -c 1 -w 1 254.255.255.2; then started=1 break fi done if [ "$started" != "1" ]; then echo "Failed to wait Umlinux online" fi - name: Prepare Uml Environment run: | CUSER="$(id --user --name)" CUID="$(id --user)" CGID="$(id --group)" sudo chroot umlrootfs bash --noprofile --norc -eo pipefail << EOF groupadd --gid "${CGID?}" "${CUSER?}" useradd --create-home --home-dir "/home/${CUSER}" --gid "${CGID?}" \ --uid "${CUID?}" --shell "\$(which bash)" "${CUSER?}" EOF ln ./worker.test "umlrootfs/home/${CUSER}/worker.test" - name: Run Tests in Cgroupv2 run: | CUSER="$(id --user --name)" sudo rsh 254.255.255.2 bash --noprofile --norc -eo pipefail << EOF cd "/home/${CUSER}" mkdir -p /sys/fs/cgroup/tunasync TERM=xterm-256color ./worker.test -test.v=true -test.coverprofile \ profile3.cov -test.run TestCgroup rmdir /sys/fs/cgroup/tunasync systemd-run --service-type=oneshot --uid="${CUSER}" --pipe --wait \ --property=Delegate=yes --setenv=USECURCGROUP=1 \ --setenv=TERM=xterm-256color --same-dir \ "\${PWD}/worker.test" -test.v=true -test.coverprofile \ profile4.cov -test.run TestCgroup EOF - name: Stop Uml run: | sudo rsh 254.255.255.2 systemctl poweroff sleep 10 if [ -e "/proc/$UMLINUX_PID" ]; then sleep 10 if [ -e "/proc/$UMLINUX_PID" ]; then sudo kill -TERM "$UMLINUX_PID" || true sleep 1 fi fi if [ -e "/proc/$UMLINUX_PID" ]; then sleep 10 if [ -e "/proc/$UMLINUX_PID" ]; then sudo kill -KILL "$UMLINUX_PID" || true sleep 1 fi fi - name: Combine coverage files run : | CUSER="$(id --user --name)" "${HOME}/go/bin/gocovmerge" profile.cov profile2.cov \ "umlrootfs/home/${CUSER}/profile3.cov" \ "umlrootfs/home/${CUSER}/profile4.cov" > profile-all.cov - name: Convert coverage to lcov uses: jandelgado/gcov2lcov-action@v1.0.0 with: infile: profile-all.cov outfile: coverage.lcov - name: Coveralls uses: coverallsapp/github-action@v1.0.1 with: github-token: ${{ secrets.github_token }} path-to-lcov: coverage.lcov