diff options
Diffstat (limited to '')
-rw-r--r-- | .github/workflows/ci-deb.yml | 232 | ||||
-rw-r--r-- | .github/workflows/ci-rpm.yml | 332 | ||||
-rw-r--r-- | .github/workflows/ci.yml | 483 | ||||
-rw-r--r-- | .github/workflows/crossbuild.yml | 91 | ||||
-rw-r--r-- | .github/workflows/docker.yml | 81 | ||||
-rw-r--r-- | .github/workflows/dockerhub.yml | 111 |
6 files changed, 1330 insertions, 0 deletions
diff --git a/.github/workflows/ci-deb.yml b/.github/workflows/ci-deb.yml new file mode 100644 index 0000000..131f907 --- /dev/null +++ b/.github/workflows/ci-deb.yml @@ -0,0 +1,232 @@ +name: CI DEB + +on: + push: + branches-ignore: + - coverity_scan + pull_request: + +env: + DEBIAN_FRONTEND: noninteractive + CC: gcc + +jobs: + deb-build: + + strategy: + matrix: + env: + - { NAME: "ubuntu-20.04", OS: "ubuntu:20.04" } + - { NAME: "ubuntu-22.04", OS: "ubuntu:22.04" } + - { NAME: "ubuntu-24.04", OS: "ubuntu:24.04" } + - { NAME: "debian-10", OS: "debian:buster" } + - { NAME: "debian-11", OS: "debian:bullseye" } + - { NAME: "debian-12", OS: "debian:bookworm" } + - { NAME: "debian-sid", OS: "debian:sid" } + fail-fast: false + + runs-on: ubuntu-latest + + container: + image: ${{ matrix.env.OS }} + + env: + HOSTAPD_BUILD_DIR: /tmp/eapol_test.ci + HOSTAPD_GIT_TAG: hostap_2_8 + + name: "DEB build" + + steps: + + - name: Package manager performance and stability improvements + run: | + if [ -f "/etc/apt/sources.list" ]; then + sed -i 's/deb.debian.org/debian-archive.trafficmanager.net/' /etc/apt/sources.list + sed -i 's/archive.ubuntu.com/azure.archive.ubuntu.com/' /etc/apt/sources.list + fi + echo 'Acquire::Retries "10";' > /etc/apt/apt.conf.d/80-retries + echo 'force-unsafe-io' > /etc/dpkg/dpkg.cfg.d/02speedup + echo 'man-db man-db/auto-update boolean false' | debconf-set-selections + apt-get update + + - name: Install recent git + run: | + apt-get install -y --no-install-recommends git-core ca-certificates + + - uses: actions/checkout@v4 + with: + path: freeradius + + - name: Prepare filesystem + run: | + pwd + ls -la + mkdir debs + ls -la + + - name: Install build dependencies + run: | + apt-get install -y --no-install-recommends build-essential devscripts quilt equivs procps fakeroot + debian/rules debian/control + mk-build-deps -irt"apt-get -y" debian/control + working-directory: freeradius + + - name: Show versions + run: | + $CC --version + make --version + krb5-config --all || : + openssl version + + - name: Build DEBs + run: | + make deb + working-directory: freeradius + + - name: Collect DEBs + run: | + mv *.deb debs/ + + - name: Restore eapol_test build directory from cache + uses: actions/cache@v4 + id: hostapd-cache + with: + path: ${{ env.HOSTAPD_BUILD_DIR }} + key: hostapd-${{ matrix.env.NAME }}-${{ env.HOSTAPD_GIT_TAG }}-v1 + + # Debian sid defaults to gcc12 which fails to build eapol_test + - name: Install GCC 10 for eapol_test build + run: | + apt-get install -y --no-install-recommends gcc-10 + update-alternatives --install /usr/bin/gcc gcc /usr/bin/gcc-10 60 && update-alternatives --set gcc /usr/bin/gcc-10 + if: ${{ matrix.env.OS == 'debian:sid' }} + + - name: Build eapol_test + run: | + apt-get install -y libnl-3-dev libnl-genl-3-dev + scripts/ci/eapol_test-build.sh + mv scripts/ci/eapol_test/eapol_test ../debs + working-directory: freeradius + + - name: Store DEBs + uses: actions/upload-artifact@v4 + with: + name: debs-${{ matrix.env.NAME }} + path: debs + + # + # If the CI has failed and the branch is ci-debug then start a tmate + # session. SSH rendezvous point is emited continuously in the job output. + # + - name: "Debug: Package dependancies for tmate" + run: | + apt-get install -y --no-install-recommends xz-utils + if: ${{ github.ref == 'refs/heads/ci-debug' && failure() }} + + - name: "Debug: Start tmate" + uses: mxschmitt/action-tmate@v3 + with: + limit-access-to-actor: true + sudo: false + if: ${{ github.ref == 'refs/heads/ci-debug' && failure() }} + + + deb-test: + + needs: + - deb-build + + strategy: + matrix: + env: + - { NAME: "ubuntu-20.04", OS: "ubuntu:20.04" } + - { NAME: "ubuntu-22.04", OS: "ubuntu:22.04" } + - { NAME: "ubuntu-24.04", OS: "ubuntu:24.04" } + - { NAME: "debian-10", OS: "debian:buster" } + - { NAME: "debian-11", OS: "debian:bullseye" } + - { NAME: "debian-12", OS: "debian:bookworm" } + - { NAME: "debian-sid", OS: "debian:sid" } + fail-fast: false + + runs-on: ubuntu-latest + + container: + image: ${{ matrix.env.OS }} + + name: "DEB install test" + + steps: + + - name: Load DEBs + uses: actions/download-artifact@v4 + with: + name: debs-${{ matrix.env.NAME }} + + - name: Package manager performance improvements + run: | + if [ -f "/etc/apt/sources.list" ]; then + sed -i 's/deb.debian.org/debian-archive.trafficmanager.net/' /etc/apt/sources.list + sed -i 's/archive.ubuntu.com/azure.archive.ubuntu.com/' /etc/apt/sources.list + fi + echo force-unsafe-io > /etc/dpkg/dpkg.cfg.d/02speedup + echo 'man-db man-db/auto-update boolean false' | debconf-set-selections + apt-get update + + # For pkill and strings + - name: Install procps and binutils + run: | + apt-get update + apt-get install -y --no-install-recommends procps binutils + + - name: Install DEBs + run: | + find . -maxdepth 1 -name '*.deb' | xargs apt-get install -y --no-install-recommends + + - name: Config test + run: | + freeradius -XxC + + # + # We now perform some post-install tests that depend on the availability + # of the source tree + # + - name: Install pre-built eapol_test + run: | + apt-get install -y libssl1.? libdbus-1-? libnl-3-200 libnl-genl-3-200 + mv eapol_test /usr/local/bin + chmod +x /usr/local/bin/eapol_test + + - uses: actions/checkout@v4 + with: + path: freeradius + + - name: Run the post-install test target + run: | + echo "top_builddir := $(pwd)" > Make.inc + make -C src/tests/ OPENSSL_LIBS=1 EAPOL_TEST_BIN="$(which eapol_test)" $(pwd)/build/tests/eapol_test/eapol_test.mk + make -f scripts/ci/package-test.mk package-test + working-directory: freeradius + + - name: Upload radius logs on failure + if: ${{ failure() }} + uses: actions/upload-artifact@v4 + with: + name: radius-logs-${{ matrix.env.NAME }}.tgz + path: | + /var/log/freeradius + freeradius/build/tests/eapol_test + + # + # See above comments for tmate + # + - name: "Debug: Package dependancies for tmate" + run: | + apt-get install -y --no-install-recommends xz-utils + if: ${{ github.ref == 'refs/heads/ci-debug' && failure() }} + + - name: "Debug: Start tmate" + uses: mxschmitt/action-tmate@v3 + with: + limit-access-to-actor: true + sudo: false + if: ${{ github.ref == 'refs/heads/ci-debug' && failure() }} diff --git a/.github/workflows/ci-rpm.yml b/.github/workflows/ci-rpm.yml new file mode 100644 index 0000000..00c56f9 --- /dev/null +++ b/.github/workflows/ci-rpm.yml @@ -0,0 +1,332 @@ +name: CI RPM + +on: + push: + branches-ignore: + - coverity_scan + pull_request: + +env: + CC: gcc + +jobs: + rpm-build: + + strategy: + matrix: + env: + - { NAME: "centos-7", OS: "centos:7", BADNODE: true } + - { NAME: "rocky-8", OS: "rockylinux/rockylinux:8", BADNODE: false } + - { NAME: "rocky-9", OS: "rockylinux/rockylinux:9", BADNODE: false } + fail-fast: false + + runs-on: ubuntu-latest + + container: + image: ${{ matrix.env.OS }} + + env: + HOSTAPD_BUILD_DIR: /tmp/eapol_test.ci + HOSTAPD_GIT_TAG: hostapd_2_8 + ACTIONS_ALLOW_USE_UNSECURE_NODE_VERSION: ${{ matrix.env.BADNODE }} + + name: "RPM build" + + steps: + + - name: Fix up CentOS 7 repositories + if: ${{ matrix.env.NAME == 'centos-7' }} + run: | + sed -i "s/^mirrorlist/#mirrorlist/g" /etc/yum.repos.d/CentOS-* + sed -i "s|#\s*baseurl=http://mirror.centos.org|baseurl=http://vault.centos.org|g" /etc/yum.repos.d/CentOS-* + + # Required so that the checkout action uses git protocol rather than the GitHub REST API. + # make rpm requires the FR directory to be a git repository. + - name: Install recent git for CentOS 7 + if: ${{ matrix.env.NAME == 'centos-7' }} + run: | + yum install -y https://packages.endpointdev.com/rhel/7/os/x86_64/git-core-2.30.1-1.ep7.x86_64.rpm + + # Rocky 9 uses dnf by default. CentOS 7 doesn't have dnf. Install yum on Rocky 9 so all distros work + - name: Install yum + if: ${{ matrix.env.NAME == 'rocky-9'}} + run: | + dnf install -y yum + + - name: Install distro git for Rocky. + if: ${{ startsWith(matrix.env.NAME, 'rocky-') }} + run: | + yum install -y git-core + + - uses: actions/checkout@v3 + with: + path: freeradius + + - name: Prepare filesystem + run: | + pwd + ls -la + mkdir rpms + ls -la + + - name: LTB repo for CentOS and Rocky Linux 8 + if: ${{ startsWith(matrix.env.NAME, 'centos-') || matrix.env.NAME == 'rocky-8' }} + run: | + echo '[ltb-project]' > /etc/yum.repos.d/ltb-project.repo + echo 'name=LTB project packages' >> /etc/yum.repos.d/ltb-project.repo + echo 'baseurl=https://ltb-project.org/rpm/$releasever/$basearch' >> /etc/yum.repos.d/ltb-project.repo + echo 'enabled=1' >> /etc/yum.repos.d/ltb-project.repo + echo 'gpgcheck=1' >> /etc/yum.repos.d/ltb-project.repo + echo 'gpgkey=https://www.ltb-project.org/documentation/_static/RPM-GPG-KEY-LTB-project' >> /etc/yum.repos.d/ltb-project.repo + rpm --import https://www.ltb-project.org/documentation/_static/RPM-GPG-KEY-LTB-project + + - name: Enable EPEL for CentOS and Rocky Linux + if: ${{ startsWith(matrix.env.NAME, 'centos-') || startsWith(matrix.env.NAME, 'rocky-') }} + run: | + yum install -y epel-release + + - name: Enable PowerTools on Rocky 8. + if: ${{ matrix.env.NAME == 'rocky-8' }} + run: | + yum install -y yum-utils + yum config-manager --enable PowerTools || : + yum config-manager --enable powertools || : + + - name: Enable Code Ready Builer on Rocky 9. + if: ${{ matrix.env.NAME == 'rocky-9' }} + run: | + yum install -y yum-utils + yum config-manager --enable crb + + - name: Install common tools + run: | + yum install -y \ + bzip2 \ + gcc \ + make \ + perl \ + rpm-build \ + yum-utils + + # + # We just patch the SPEC file for Fedora since we want to use the standard + # make rpm target which wants to build with LDAP. + # + - name: Disable rlm_ldap on Fedora (no LTB packages) + if: ${{ startsWith(matrix.env.NAME, 'fedora-') }} + run: | + sed -ie 's/%bcond_without ldap/%global _without_ldap: 1/' freeradius/redhat/freeradius.spec + + - name: Install build dependencies + run: | + yum-builddep -y freeradius/redhat/freeradius.spec + + # + # It has been observed that sometimes not all the dependencies are + # installed on the first go. Give it a second chance. + # + - name: Second run of install build dependencies + run: | + yum-builddep -y redhat/freeradius.spec + working-directory: freeradius + + - name: Show versions + run: | + $CC --version + make --version + krb5-config --all || : + openssl version + + # For pkill and ps + - name: Enable procps-ng on Rocky + if: ${{ startsWith(matrix.env.NAME, 'rocky-') }} + run: | + yum install -y procps-ng + + - name: Build RPMs + run: | + [ -r /opt/rh/devtoolset-8/enable ] && source /opt/rh/devtoolset-8/enable || : + ./configure + make rpm + working-directory: freeradius + + - name: Collect RPMs + run: | + mv freeradius/rpmbuild/RPMS/x86_64/*.rpm rpms/ + + - name: Restore eapol_test build directory from cache + uses: actions/cache@v3 + id: hostapd-cache + with: + path: ${{ env.HOSTAPD_BUILD_DIR }} + key: hostapd-${{ matrix.env.NAME }}-${{ env.HOSTAPD_GIT_TAG }}-v1 + + - name: Build eapol_test + run: | + yum install -y libnl3-devel which + [ -r /opt/rh/devtoolset-8/enable ] && source /opt/rh/devtoolset-8/enable || : + scripts/ci/eapol_test-build.sh + mv scripts/ci/eapol_test/eapol_test ../rpms/ + working-directory: freeradius + + - name: Store RPMs + uses: actions/upload-artifact@v3 + with: + name: rpms-${{ matrix.env.NAME }} + path: rpms + + # + # If the CI has failed and the branch is ci-debug then start a tmate + # session. SSH rendezvous point is emited continuously in the job output. + # + - name: "Debug: Package dependancies for tmate" + run: | + yum install -y xz + ln -s /bin/true /bin/apt-get + if: ${{ github.ref == 'refs/heads/ci-debug' && failure() }} + + - name: "Debug: Start tmate" + uses: mxschmitt/action-tmate@v3 + with: + limit-access-to-actor: true + sudo: false + if: ${{ github.ref == 'refs/heads/ci-debug' && failure() }} + + + rpm-test: + + needs: + - rpm-build + + strategy: + matrix: + env: + - { NAME: "centos-7", OS: "centos:7", BADNODE: true } + - { NAME: "rocky-8", OS: "rockylinux/rockylinux:8", BADNODE: false } + - { NAME: "rocky-9", OS: "rockylinux/rockylinux:9", BADNODE: false } + fail-fast: false + + runs-on: ubuntu-latest + + container: + image: ${{ matrix.env.OS }} + + env: + ACTIONS_ALLOW_USE_UNSECURE_NODE_VERSION: ${{ matrix.env.BADNODE }} + + name: "RPM install test" + + steps: + + - name: Fix up CentOS 7 repositories + if: ${{ matrix.env.NAME == 'centos-7' }} + run: | + sed -i "s/^mirrorlist/#mirrorlist/g" /etc/yum.repos.d/CentOS-* + sed -i "s|#\s*baseurl=http://mirror.centos.org|baseurl=http://vault.centos.org|g" /etc/yum.repos.d/CentOS-* + + - name: Install yum + if: ${{ matrix.env.NAME == 'rocky-9'}} + run: | + dnf install -y yum + + - name: LTB repo for CentOS and Rocky 8 + if: ${{ startsWith(matrix.env.NAME, 'centos-') || matrix.env.NAME == 'rocky-8' }} + run: | + echo '[ltb-project]' > /etc/yum.repos.d/ltb-project.repo + echo 'name=LTB project packages' >> /etc/yum.repos.d/ltb-project.repo + echo 'baseurl=https://ltb-project.org/rpm/$releasever/$basearch' >> /etc/yum.repos.d/ltb-project.repo + echo 'enabled=1' >> /etc/yum.repos.d/ltb-project.repo + echo 'gpgcheck=1' >> /etc/yum.repos.d/ltb-project.repo + echo 'gpgkey=https://www.ltb-project.org/documentation/_static/RPM-GPG-KEY-LTB-project' >> /etc/yum.repos.d/ltb-project.repo + rpm --import https://www.ltb-project.org/documentation/_static/RPM-GPG-KEY-LTB-project + + - name: Enable EPEL for CentOS and Rocky Linux + if: ${{ startsWith(matrix.env.NAME, 'centos-') || startsWith(matrix.env.NAME, 'rocky-') }} + run: | + yum install -y epel-release + + - name: Enable PowerTools on Rocky 8 + if: ${{ matrix.env.NAME == 'rocky-8' }} + run: | + yum install -y yum-utils + yum config-manager --enable PowerTools || : + yum config-manager --enable powertools || : + + - name: Enable Code Ready Builer on Rocky 9. + if: ${{ matrix.env.NAME == 'rocky-9' }} + run: | + yum install -y yum-utils + yum config-manager --enable crb + + # For pkill + - name: Enable procps-ng on Centos and Rocky + if: ${{ startsWith(matrix.env.NAME, 'centos-') || startsWith(matrix.env.NAME, 'rocky-') }} + run: | + yum install -y procps-ng + + - name: Load RPMs + uses: actions/download-artifact@v3 + with: + name: rpms-${{ matrix.env.NAME }} + + - name: Install RPMs + run: | + yum install -y *.rpm + + - name: Ensure certificates are created + if: ${{ matrix.env.NAME == 'centos-7' }} + run: | + if [ ! -e /etc/raddb/certs/server.pem ]; then + /sbin/runuser -g radiusd -c 'umask 007; /etc/raddb/certs/bootstrap' + fi + + - name: Config check + run: | + radiusd -XxC + + # + # We now perform some post-install tests that depend on the availability + # of the source tree + # + - name: Install pre-built eapol_test + run: | + yum install -y libnl3 make gdb which + mv eapol_test /usr/local/bin + chmod +x /usr/local/bin/eapol_test + + - uses: actions/checkout@v3 + with: + path: freeradius + + - name: Run the post-install test target + run: | + echo "top_builddir := $(pwd)" > Make.inc + make -C src/tests/ OPENSSL_LIBS=1 EAPOL_TEST_BIN="$(which eapol_test)" $(pwd)/build/tests/eapol_test/eapol_test.mk + make -f scripts/ci/package-test.mk package-test + working-directory: freeradius + + - name: Upload radius logs on failure + if: ${{ failure() }} + uses: actions/upload-artifact@v3 + with: + name: radius-logs-${{ matrix.env.NAME }}.tgz + path: | + /var/log/radius + freeradius/build/tests/eapol_test + + # + # See above comments for tmate + # + - name: "Debug: Package dependancies for tmate" + run: | + yum install -y xz + ln -s /bin/true /bin/apt-get + if: ${{ github.ref == 'refs/heads/ci-debug' && failure() }} + + - name: "Debug: Start tmate" + uses: mxschmitt/action-tmate@v3 + with: + limit-access-to-actor: true + sudo: false + if: ${{ github.ref == 'refs/heads/ci-debug' && failure() }} + diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml new file mode 100644 index 0000000..caf9753 --- /dev/null +++ b/.github/workflows/ci.yml @@ -0,0 +1,483 @@ +name: CI + +on: + push: + branches-ignore: + - coverity_scan + pull_request: + +env: + PANIC_ACTION: "gdb -batch -x raddb/panic.gdb %e %p 1>&0 2>&0" + ALT_OPENSSL: "3.0.8" + CI: 1 + GH_ACTIONS: 1 + DEBIAN_FRONTEND: noninteractive + APT_OPTS: "-y --no-install-recommends" + LDAP_TEST_SERVER: 127.0.0.1 + LDAP_TEST_SERVER_PORT: 3890 + REST_TEST_SERVER: 127.0.0.1 + REST_TEST_SERVER_PORT: 8080 + REST_TEST_SERVER_SSL_PORT: 8443 + SQL_MYSQL_TEST_SERVER: mariadb + SQL_POSTGRESQL_TEST_SERVER: postgres + ASAN_OPTIONS: symbolize=1 detect_leaks=1 detect_stack_use_after_return=1 + LSAN_OPTIONS: fast_unwind_on_malloc=0:malloc_context_size=50 + UBSAN_OPTIONS: print_stacktrace=1 + +jobs: + pre-ci: + runs-on: ubuntu-latest + outputs: + should_skip: ${{ steps.skip_check.outputs.should_skip }} + selfhosted: ${{ github.repository_owner == 'FreeRADIUS' && '1' || '0' }} + docker_prefix: ${{ github.repository_owner == 'FreeRADIUS' && 'docker.internal.networkradius.com/' || '' }} + steps: + - id: skip_check + uses: fkirc/skip-duplicate-actions@master + + ci: + needs: pre-ci + if: ${{ needs.pre-ci.outputs.should_skip != 'true' }} + + runs-on: ${{ matrix.os.runs_on }} + + container: + image: ${{ matrix.os.docker }} + + strategy: + fail-fast: false + matrix: + os: +# +# runs_on - where GitHub will spin up the runner, either +# "self-hosted", or the name of a GitHub VM image. +# code - the name/version of the OS (for step evaluations below) +# docker - the docker image name, if containers are being used +# name - used in the job name only +# + - runs_on: "${{ needs.pre-ci.outputs.selfhosted == '1' && 'self-hosted' || 'ubuntu-20.04' }}" + docker: "${{ needs.pre-ci.outputs.selfhosted == '1' && 'docker.internal.networkradius.com/self-hosted' || 'ubuntu:20.04' }}" + name: "${{ needs.pre-ci.outputs.selfhosted == '1' && 'self' || 'gh' }}-ubuntu20" + code: "ubuntu2004" + + env: + - { CC: gcc, DO_BUILD: yes, LIBS_OPTIONAL: no, LIBS_ALT: no, REPRODUCIBLE: no, SANITIZER: no, BUILD_CFLAGS: "-DWITH_EVAL_DEBUG", NAME: linux-gcc-lean } + - { CC: gcc, DO_BUILD: yes, LIBS_OPTIONAL: yes, LIBS_ALT: no, REPRODUCIBLE: no, SANITIZER: no, BUILD_CFLAGS: "-DWITH_EVAL_DEBUG", NAME: linux-gcc } + - { CC: gcc, DO_BUILD: yes, LIBS_OPTIONAL: yes, LIBS_ALT: no, REPRODUCIBLE: yes, SANITIZER: no, BUILD_CFLAGS: "-DWITH_EVAL_DEBUG", NAME: linux-gcc-reproducible } + - { CC: gcc, DO_BUILD: yes, LIBS_OPTIONAL: yes, LIBS_ALT: no, REPRODUCIBLE: no, SANITIZER: no, BUILD_CFLAGS: "-DWITH_EVAL_DEBUG -O2 -g3", NAME: linux-gcc-O2-g3 } + - { CC: clang, DO_BUILD: yes, LIBS_OPTIONAL: no, LIBS_ALT: no, REPRODUCIBLE: no, SANITIZER: no, BUILD_CFLAGS: "-DWITH_EVAL_DEBUG", NAME: linux-clang-lean } + - { CC: clang, DO_BUILD: yes, LIBS_OPTIONAL: yes, LIBS_ALT: no, REPRODUCIBLE: no, SANITIZER: no, BUILD_CFLAGS: "-DWITH_EVAL_DEBUG", NAME: linux-clang } + - { CC: clang, DO_BUILD: yes, LIBS_OPTIONAL: yes, LIBS_ALT: yes, REPRODUCIBLE: no, SANITIZER: no, BUILD_CFLAGS: "-DWITH_EVAL_DEBUG", NAME: linux-clang-altlibs } + - { CC: clang, DO_BUILD: yes, LIBS_OPTIONAL: yes, LIBS_ALT: no, REPRODUCIBLE: yes, SANITIZER: no, BUILD_CFLAGS: "-DWITH_EVAL_DEBUG", NAME: linux-clang-reproducible } + - { CC: clang, DO_BUILD: yes, LIBS_OPTIONAL: yes, LIBS_ALT: no, REPRODUCIBLE: no, SANITIZER: yes, BUILD_CFLAGS: "-DWITH_EVAL_DEBUG", NAME: linux-clang-sanitizer } + - { CC: clang, DO_BUILD: yes, LIBS_OPTIONAL: yes, LIBS_ALT: no, REPRODUCIBLE: no, SANITIZER: no, BUILD_CFLAGS: "-DWITH_EVAL_DEBUG -O2 -g3", NAME: linux-clang-O2-g3 } + + env: ${{ matrix.env }} + + # Test names are used in the branch protection rules in GitHub + # If you change the names here, or add additional matrix entries, you + # must also amend the branch protection fules. + name: "v3.2.x-${{ matrix.os.name }}-${{ matrix.env.NAME }}" + + # The standard GitHub environment contains PostgreSQL and + # MySQL already. However when running on hosted GitHub runners + # we need to run separate database containers to provide these. + services: + mariadb: + image: ${{ needs.pre-ci.outputs.docker_prefix }}mariadb + env: + MARIADB_ALLOW_EMPTY_ROOT_PASSWORD: yes + ports: + - 3306:3306 + options: --health-cmd="mariadb-admin ping" --health-interval 10s --health-timeout 5s --health-retries 10 + + postgres: + image: ${{ needs.pre-ci.outputs.docker_prefix }}postgres + env: + POSTGRES_HOST_AUTH_METHOD: trust + ports: + - 5432:5432 + options: --health-cmd pg_isready --health-interval 10s --health-timeout 5s --health-retries 5 + + steps: + + - name: Self-hosted runner container fixes + run: | + ln -fs /usr/bin/env /usr/local/bin/sudo + rm -rf "$HOME"/* + + - name: Package manager performance improvements + run: | + sudo sh -c 'echo force-unsafe-io > /etc/dpkg/dpkg.cfg.d/02speedup' + if command -v mandb >/dev/null; then + echo 'man-db man-db/auto-update boolean false' | sudo debconf-set-selections + sudo dpkg-reconfigure man-db + fi + + - name: Freshen APT repo metadata + run: | + sudo apt-get update + + - name: Install common build dependencies + run: | + sudo apt-get install ${APT_OPTS} \ + autoconf \ + build-essential \ + debhelper \ + devscripts \ + dh-make \ + fakeroot \ + firebird-dev \ + freetds-dev \ + gawk \ + git \ + git-lfs \ + gnupg \ + libcap-dev \ + libcollectdclient-dev \ + libcurl4-openssl-dev \ + libgdbm-dev \ + libhiredis-dev \ + libidn11-dev \ + libiodbc2 \ + libiodbc2-dev \ + libjson-c-dev \ + libkqueue-dev \ + libkrb5-dev \ + libldap2-dev \ + libmemcached-dev \ + libmysqlclient-dev \ + libnl-3-dev \ + libnl-genl-3-dev \ + libpam0g-dev \ + libpcap-dev \ + libpcre3-dev \ + libperl-dev \ + libpq-dev \ + libreadline-dev \ + libruby \ + libsnmp-dev \ + libsqlite3-dev \ + libssl-dev \ + libtalloc-dev \ + libunbound-dev \ + libwbclient-dev \ + libykclient-dev \ + libyubikey-dev \ + lintian \ + pbuilder \ + python-dev \ + python3-dev \ + ruby-dev \ + snmp \ + software-properties-common \ + quilt + + - name: Install LLVM 15 for 20.04 + if: ${{ matrix.os.code == 'ubuntu2004' && matrix.env.CC == 'clang' }} + run: | + wget -O - https://apt.llvm.org/llvm-snapshot.gpg.key | sudo apt-key add + sudo apt-add-repository "deb http://apt.llvm.org/focal/ llvm-toolchain-focal-15 main" + sudo apt-get install ${APT_OPTS} clang-15 llvm-15 gdb libclang-rt-15-dev + sudo update-alternatives --install /usr/bin/clang clang /usr/bin/clang-15 60 && sudo update-alternatives --set clang /usr/bin/clang-15 + sudo update-alternatives --install /usr/bin/llvm-symbolizer llvm-symbolizer /usr/bin/llvm-symbolizer-15 60 && sudo update-alternatives --set llvm-symbolizer /usr/bin/llvm-symbolizer-15 + + - name: Install GCC + if: ${{ matrix.env.CC == 'gcc' }} + run: | + sudo apt-get install ${APT_OPTS} gcc gdb + + # + # Build using some alternative libraries + # + # MIT Kerberos -> HEIMDAL Kerberos + # OpenSSL 1.0 -> OpenSSL 3.0 + # + - name: 'Fetch OpenSSL 3.0 SHA' + id: opensslshasum + if: ${{ matrix.env.LIBS_ALT == 'yes' }} + run: | + wget -qO- http://www.openssl.org/source/openssl-$ALT_OPENSSL.tar.gz.sha256 | sed -ne 's/^\s\+/shasum=/p' >> $GITHUB_OUTPUT + + - name: 'Restore OpenSSL 3.0 from the cache' + if: ${{ matrix.env.LIBS_ALT == 'yes' }} + uses: actions/cache@v4 + id: openssl-cache + with: + path: /opt/openssl/ + key: openssl3-${{ steps.opensslshasum.outputs.shasum }} + + - name: 'Build OpenSSL 3.0 (if cache stale)' + if: ${{ matrix.env.LIBS_ALT == 'yes' && steps.openssl-cache.outputs.cache-hit != 'true' }} + run: | + cd ~ + wget https://www.openssl.org/source/openssl-$ALT_OPENSSL.tar.gz + tar xzf openssl-$ALT_OPENSSL.tar.gz + cd openssl-$ALT_OPENSSL + ./Configure --prefix=/opt/openssl --openssldir=. + make -j `nproc` + make install + + - name: Use alternative libraries + if: ${{ matrix.env.LIBS_ALT == 'yes' }} + run: | + echo /opt/openssl/lib64 | sudo tee /etc/ld.so.conf.d/openssl3.conf >/dev/null + sudo ldconfig + sudo apt-get install ${APT_OPTS} heimdal-dev + + - name: Show versions + run: | + printf "$CC: " ; $CC --version + printf "\nmake: " ; make --version + printf "\nkrb5: " ; krb5-config --all || : + [ -d /opt/openssl ] && export PATH=/opt/openssl/bin:$PATH + printf "\nopenssl: " ; openssl version + + - uses: actions/checkout@v4 + + - name: Build eapol_test + run: | + if [ -d /opt/openssl ]; then + # Used by scripts/ci/eapol_test-build.sh + export PATH=/opt/openssl/bin:$PATH + export EAPOL_TEST_CFLAGS="-I/opt/openssl/include" + export EAPOL_TEST_LDFLAGS="-L/opt/openssl/lib64" + fi + ./scripts/ci/eapol_test-build.sh + + - name: Build FreeRADIUS + run: | + export PATH=$(echo "$PATH" | sed -e 's#:/home/linuxbrew/[^:]\+##g') + if [ -d /opt/openssl ]; then + export PATH=/opt/openssl/bin:$PATH + CONFIG_OPENSSL="--with-openssl-lib-dir=/opt/openssl/lib64 --with-openssl-include-dir=/opt/openssl/include" + fi + + if [ $SANITIZER = "yes" ]; then + echo "Enabling sanitizers" + enable_sanitizers="--enable-address-sanitizer --enable-undefined-behaviour-sanitizer" + if [ "`uname`" != "Darwin" ]; then + enable_sanitizers="$enable_sanitizers --enable-leak-sanitizer" + fi + # TODO: libunbound is broken when built with LSAN/ASAN, let's disable it for now. + extra_cflags="--without-rlm_unbound" + + # Temporary hack just to skip and see the result. + # memory leak in rlm_{ldap,rest} and problems in perl+llvm + rm -rf src/tests/modules/ldap/ + rm -rf src/tests/modules/rest/ + else + enable_sanitizers="" + extra_cflags="" + fi + CFLAGS="${BUILD_CFLAGS}" ./configure -C \ + --enable-developer \ + ${enable_sanitizers} \ + $CONFIG_OPENSSL \ + $extra_cflags \ + --enable-werror \ + --prefix=$HOME/freeradius \ + --with-threads=$LIBS_OPTIONAL \ + --with-udpfromto=$LIBS_OPTIONAL \ + --with-openssl=$LIBS_OPTIONAL \ + --with-pcre=$LIBS_OPTIONAL \ + --enable-reproducible-builds=${REPRODUCIBLE} + make -j $(($(nproc) + 1)) + + - name: clang scan + run: | + make -j $(($(nproc) + 1)) scan && [ "$(find build/plist/ -name *.html)" = '' ] + if: ${{ matrix.env.CC == 'clang' }} + + - name: "Clang Static Analyzer: Store assets on failure" + uses: actions/upload-artifact@v4 + with: + name: clang-scan.tgz + path: build/plist/**/*.html + if: ${{ matrix.env.CC == 'clang' && failure() }} + + - name: Add OpenResty repository + shell: bash + run: | + wget -O - https://openresty.org/package/pubkey.gpg | sudo apt-key add - + echo "deb http://openresty.org/package/ubuntu $(lsb_release -sc) main" | sudo tee /etc/apt/sources.list.d/openresty.list + + sudo apt-get update + + - name: Setup git + shell: bash + run: git config --global --add safe.directory "$GITHUB_WORKSPACE" + + - name: Install test requisites + run: | + # Temporarily replace ucf (for config merge) with cp since it's + # terribly slow! + sudo mv /usr/bin/ucf /usr/bin/ucf.disabled + sudo sh -c 'echo "#!/bin/sh" > /usr/bin/ucf' + sudo sh -c 'echo "shift && cp -v \$@" >> /usr/bin/ucf' + sudo chmod +x /usr/bin/ucf + + sudo apt-get install ${APT_OPTS} \ + apparmor-utils \ + ldap-utils \ + openresty \ + slapd + + sudo mv -f /usr/bin/ucf.disabled /usr/bin/ucf + + - name: Database dependencies + run: | + sudo apt-get install ${APT_OPTS} \ + mariadb-client \ + postgresql-client + + slapd + + - name: Build certificates for REST tests + run: | + cp -r raddb/certs raddb/restcerts + cd ./raddb/restcerts && make ca && make server + + - name: Setup test databases + run: | + for i in \ + postgresql-setup.sh \ + mysql-setup.sh \ + openresty-setup.sh \ + ldap-setup.sh \ + ldap2-setup.sh; do + + script="./scripts/ci/$i" + echo "Calling $i" + $script + done + + - name: Configure test database access + run: | + mysql -h mariadb -uroot -e "CREATE USER 'radius'@'%' IDENTIFIED BY 'radpass';" + mysql -u root -h mariadb -e "GRANT ALL ON radius.* TO 'radius'; FLUSH PRIVILEGES;" + + - name: Run tests + run: | + [ -d /opt/openssl ] && export PATH=/opt/openssl/bin:$PATH + + openssl dhparam -out ./raddb/certs/dh -2 128 || \ + openssl dhparam -out ./raddb/certs/dh -2 512 || \ + true + + make ci-test + + - name: Show debug logs on failure + if: ${{ failure() }} + run: | + cat src/tests/radius.log || : + + # + # If the CI has failed and the branch is ci-debug then start a tmate + # session. SSH rendezvous point is emited continuously in the job output. + # + - name: "Debug: Start tmate" + uses: mxschmitt/action-tmate@v3 + with: + limit-access-to-actor: true + if: ${{ github.ref == 'refs/heads/ci-debug' && failure() }} + +########################################################################################## +# FREERADIUS CORE DEVELOPERS ONLY +########################################################################################## +# +# Direct push access to the main freeradius-server repo has been disabled in an attempt +# to keep CI passing reliably. +# +# The code below will automatically push to the main repository if a commit passes CI in +# your fork on a branch that exists in the main repository. +# +# The code below will only run if PERSONAL_ACCESS_TOKEN is defined in the repository +# secrets for your fork of the freeradius-server repo. +# +# If the above CI checks pass then we auto-merge into the same branch in the +# main FR repo (only on push) if the PERSONAL_ACCESS_TOKEN secret is defined, i.e. when +# the actor claims to be a FreeRADIUS developer with push access. +# +# Personal access tokens can be generated via the GitHub website: +# +# - Click on the Profile menu (top right) +# > Settings +# > Developer settings +# > Personal access tokens +# > Generate New Token +# - Next, add the following settings and scopes: +# Note: FreeRADIUS CI Push +# public_repo (checked) +# +# This will allow any git operations using this PERSONAL_ACCESS_TOKEN to commit code to any +# public repository you have access to. +# +# As this PERSONAL_ACCESS_TOKEN will only ever be accessible from GitHub actions when they are +# running from your fork of the FreeRADIUS repo, this shouldn't be a security issue. +# +# After generating your PERSONAL_ACCESS_TOKEN you will need to add it as a secret to your +# repository. +# +# - Copy your new token +# - Click on the Profile menu (top right) +# > Your repositories +# - Search for freeradius-server +# > Click freeradius-server +# - Click settings in the tabs on the left +# - Click secrets in the menu items on the left +# - Click New repository secret +# - Name: PERSONAL_ACCESS_TOKEN +# Value: <value you copied> +# - Click Add secret + # + # Needed because secrets are not available for evaluation in if conditions + # at the job level, so we evaluate the existence of the PERSONAL_ACCESS_TOKEN secret + # within a step and export the result instead. We also extract the short + # branch name here because it's convenient to do so. + # + merge-preflight: + needs: + - ci + if: ( github.event_name == 'push' ) && ( github.repository_owner != 'FreeRADIUS' ) && ( github.ref == 'refs/heads/master' || github.ref == 'refs/heads/v3.2.x' ) + name: "Merge preflight" + runs-on: ubuntu-latest + steps: + - name: "Report whether PERSONAL_ACCESS_TOKEN secret exists" + id: merge-preflight + run: | + [ -z "$PERSONAL_ACCESS_TOKEN" ] || echo "::set-output name=PERSONAL_ACCESS_TOKEN_EXISTS::1" + env: + PERSONAL_ACCESS_TOKEN: ${{ secrets.PERSONAL_ACCESS_TOKEN }} + outputs: + PERSONAL_ACCESS_TOKEN_EXISTS: ${{ steps.merge-preflight.outputs.PERSONAL_ACCESS_TOKEN_EXISTS }} + + merge-upstream: + needs: + - ci + - merge-preflight + if: needs.merge-preflight.outputs.PERSONAL_ACCESS_TOKEN_EXISTS == '1' + runs-on: ubuntu-latest + name: "Merge into upstream" + steps: + - uses: actions/checkout@v4 + with: + fetch-depth: 0 + lfs: false + persist-credentials: false + # Note: This also opportunistically updates the developer's branch with commits from + # the main repository. + # This update may fail if the developer has pushed additional commits since the + # workflow started. This is normal, and we ignore the failure. + - name: "Merge into upstream dev branch and update local branch" + run: | + BRANCH=${GITHUB_REF#refs/heads/} + git remote add upstream https://$USERNAME:$REPO_KEY@github.com/FreeRADIUS/freeradius-server.git + git fetch --no-recurse-submodules upstream +refs/heads/*:refs/remotes/upstream/* +refs/tags/*:refs/tags/upstream/* + git checkout --progress --force -B upstream-branch "refs/remotes/upstream/$BRANCH" + git merge "$BRANCH" --ff-only + git push upstream "upstream-branch:$BRANCH" + git push origin "$BRANCH" || true + env: + USERNAME: ${{ github.actor }} + REPO_KEY: ${{ secrets.PERSONAL_ACCESS_TOKEN }} diff --git a/.github/workflows/crossbuild.yml b/.github/workflows/crossbuild.yml new file mode 100644 index 0000000..d3d9186 --- /dev/null +++ b/.github/workflows/crossbuild.yml @@ -0,0 +1,91 @@ +name: Check Crossbuild + +on: + push: + branches-ignore: + - coverity_scan + workflow_dispatch: + +env: + CI: 1 + GH_ACTIONS: 1 + DEBIAN_FRONTEND: noninteractive + APT_OPTS: "-y --no-install-recommends" + +jobs: + # + # Generate matrix based on crossbuild docker directories. + # + gen-matrix: + + runs-on: ubuntu-latest + + outputs: + matrix: ${{ steps.gen-matrix.outputs.matrix }} + + steps: + + - uses: actions/checkout@v4 + with: + lfs: false + + - id: gen-matrix + name: Generate matrix based on crossbuild targets + run: | + cd scripts/crossbuild/docker + M=$(ls | perl -n -e '{chomp; push @L,"\"$_\""} END{print "{\"env\":[{\"OS\":",join("},{\"OS\":",@L),"}]}"}') + echo "Matrix: $M" + echo matrix=$M >> $GITHUB_OUTPUT + + # + # Run crossbuild target for each given OS. This will build the + # Docker image and run `make test` inside. + # + crossbuild: + needs: + - gen-matrix + + runs-on: ubuntu-20.04 + + strategy: + fail-fast: false + matrix: ${{ fromJson(needs.gen-matrix.outputs.matrix) }} + + env: ${{ matrix.env }} + + name: "v3.2.x-${{ matrix.env.OS }}" + + steps: + + - uses: actions/checkout@v4 + with: + fetch-depth: 0${{ ( matrix.env.OS != 'centos7' ) && '1' }} + + - name: Run crossbuild tests + run: | + make crossbuild.$OS + + - name: Show build log + if: ${{ success() || failure() }} + run: | + cat scripts/crossbuild/build/build.$OS + + - name: Show configure log + if: ${{ success() || failure() }} + run: | + cat scripts/crossbuild/build/configure.$OS + + - name: Show test log + if: ${{ success() || failure() }} + run: | + cat scripts/crossbuild/build/log.$OS + + # + # If the CI has failed and the branch is ci-debug then start a tmate + # session. SSH rendezvous point is emited continuously in the job output. + # + - name: "Debug: Start tmate" + uses: mxschmitt/action-tmate@v3 + with: + limit-access-to-actor: true + if: ${{ github.ref == 'refs/heads/ci-debug' && failure() }} diff --git a/.github/workflows/docker.yml b/.github/workflows/docker.yml new file mode 100644 index 0000000..67af2a2 --- /dev/null +++ b/.github/workflows/docker.yml @@ -0,0 +1,81 @@ +name: Build Dockerfiles + +on: + push: + branches-ignore: + - coverity_scan + workflow_dispatch: + +env: + CI: 1 + GH_ACTIONS: 1 + DEBIAN_FRONTEND: noninteractive + APT_OPTS: "-y --no-install-recommends" + +jobs: + # + # Generate matrix based on docker directories. + # + gen-matrix: + + runs-on: ubuntu-latest + + outputs: + matrix: ${{ steps.gen-matrix.outputs.matrix }} + + steps: + + - uses: actions/checkout@v4 + with: + lfs: false + + - id: gen-matrix + name: Generate matrix based on docker targets + run: | + cd scripts/docker/dists + M=$(ls | perl -n -e '{chomp; push @L,"\"$_\""} END{print "{\"env\":[{\"OS\":",join("},{\"OS\":",@L),"}]}"}') + echo "Matrix: $M" + echo matrix=$M >> $GITHUB_OUTPUT + + # + # Run docker target for each given OS. This will build the + # Docker image. + # + docker: + needs: + - gen-matrix + + runs-on: ubuntu-20.04 + + strategy: + fail-fast: false + matrix: ${{ fromJson(needs.gen-matrix.outputs.matrix) }} + + env: ${{ matrix.env }} + + name: "v3.2.x-${{ matrix.env.OS }}" + + steps: + + - uses: actions/checkout@v4 + with: + fetch-depth: 1 + + - name: Regenerate Dockerfile + run: | + rm scripts/docker/dists/$OS/Dockerfile || true + make docker.$OS.regen + + - name: Build docker image + run: | + make docker.$OS.build + + # + # If the CI has failed and the branch is ci-debug then start a tmate + # session. SSH rendezvous point is emited continuously in the job output. + # + - name: "Debug: Start tmate" + uses: mxschmitt/action-tmate@v3 + with: + limit-access-to-actor: true + if: ${{ github.ref == 'refs/heads/ci-debug' && failure() }} diff --git a/.github/workflows/dockerhub.yml b/.github/workflows/dockerhub.yml new file mode 100644 index 0000000..738c9c0 --- /dev/null +++ b/.github/workflows/dockerhub.yml @@ -0,0 +1,111 @@ +name: Dockerhub Dev + +on: + push: + branches-ignore: + - coverity_scan + workflow_dispatch: + +env: + CI: 1 + GH_ACTIONS: 1 + DEBIAN_FRONTEND: noninteractive + APT_OPTS: "-y --no-install-recommends" + DOCKER_REPOSITORY: freeradius-dev + BRANCH: v3.2.x + +jobs: + # + # Run docker target for each given OS and ARCH. This will + # build the Docker images. + # + build_docker_images: + runs-on: ubuntu-22.04 + if: github.repository_owner == 'FreeRADIUS' + + strategy: + matrix: + env: + - { OS: "ubuntu", ARCH: "linux/amd64", NAME: "amd64" } + - { OS: "ubuntu", ARCH: "linux/arm/v7", NAME: "armv7" } + - { OS: "ubuntu", ARCH: "linux/arm64/v8", NAME: "arm64v8" } + - { OS: "alpine", ARCH: "linux/amd64", NAME: "amd64" } + - { OS: "alpine", ARCH: "linux/arm/v6", NAME: "armv6" } + - { OS: "alpine", ARCH: "linux/arm/v7", NAME: "armv7" } + - { OS: "alpine", ARCH: "linux/arm64/v8", NAME: "arm64v8" } + + fail-fast: false + + name: "${{ matrix.env.OS }}-${{ matrix.env.ARCH }}" + + steps: + + - uses: actions/checkout@v4 + with: + fetch-depth: 1 + + - name: Regenerate Dockerfiles + run: | + rm scripts/docker/dists/*/Dockerfile || true + make docker.regen + + - name: Install qemu + run: | + sudo apt-get update + sudo apt-get install ${APT_OPTS} qemu-user-static + + - name: Build docker image + run: | + make docker-${{ matrix.env.OS }} \ + DOCKER_TAG="$DOCKER_REPOSITORY" \ + DOCKER_BUILD_ARGS="--no-cache --platform ${{ matrix.env.ARCH }}" \ + DOCKER_VERSION="${{ matrix.env.NAME }}-$BRANCH" + + - name: Docker login + uses: docker/login-action@v3 + with: + username: ${{ secrets.DOCKERHUB_USERNAME }} + password: ${{ secrets.DOCKERHUB_PASSWORD }} + + - name: Push arch image to Docker registry + shell: bash + run: | + make docker-push-${{ matrix.env.OS }} \ + DOCKER_TAG="$DOCKER_REPOSITORY" \ + DOCKER_VERSION="${{ matrix.env.NAME }}-$BRANCH" + + + manifest: + runs-on: ubuntu-22.04 + needs: build_docker_images + if: github.repository_owner == 'FreeRADIUS' + + strategy: + matrix: + env: + - { OS: "ubuntu", ARCHS: "amd64 armv7 arm64v8", SUFFIX: "" } + - { OS: "alpine", ARCHS: "amd64 armv6 armv7 arm64v8", SUFFIX: "-alpine" } + + fail-fast: false + + name: "manifest-${{ matrix.env.OS }}" + + steps: + + - uses: actions/checkout@v4 + with: + fetch-depth: 1 + + - name: Docker login + uses: docker/login-action@v3 + with: + username: ${{ secrets.DOCKERHUB_USERNAME }} + password: ${{ secrets.DOCKERHUB_PASSWORD }} + + - name: Create manifests + shell: bash + run: | + make docker-ci-manifest \ + DOCKER_TAG="$DOCKER_REPOSITORY" \ + DOCKER_VERSION="$BRANCH${{ matrix.env.SUFFIX }}" \ + DOCKER_ARCHS="${{ matrix.env.ARCHS }}" |