--- /dev/null
+scripts/docker/build/
+scripts/docker/m4/
# there's no point in requiring the developer to run configure
# *before* making packages.
#
-ifeq "$(filter deb rpm pkg_version crossbuild.% freeradius-server-%,$(MAKECMDGOALS))" ""
+ifeq "$(filter deb rpm pkg_version dist-check% crossbuild.% docker.% freeradius-server-%,$(MAKECMDGOALS))" ""
$(if $(wildcard Make.inc),,$(error Missing 'Make.inc' Run './configure [options]' and retry))
include Make.inc
else
# If we're building packages or crossbuilding, just do that.
# Don't try to do a local build.
#
-ifeq "$(filter deb rpm pkg_version crossbuild.% freeradius-server-%,$(MAKECMDGOALS))" ""
+ifeq "$(filter deb rpm pkg_version dist-check% crossbuild.% docker.% freeradius-server-%,$(MAKECMDGOALS))" ""
#
# Include all of the autoconf definitions into the Make variable space
gpg --default-key packages@freeradius.org -b $<
# high-level targets
-.PHONY: dist-check
-dist-check: redhat/freeradius.spec debian/changelog
+.PHONY: dist-check-rpm
+dist-check-rpm: redhat/freeradius.spec
@if [ `grep '^%global _version' redhat/freeradius.spec | cut -d' ' -f3` != "$(PKG_VERSION)" ]; then \
sed 's/^%global _version .*/%global _version $(PKG_VERSION)/' redhat/freeradius.spec > redhat/.foo; \
mv redhat/.foo redhat/freeradius.spec; \
echo Updated redhat/freeradius.spec '_version' to $(PKG_VERSION); \
fi
+.PHONY: dist-check
+dist-check: dist-check-rpm debian/changelog
@if [ `head -n 1 doc/ChangeLog | awk '/^FreeRADIUS/{print $$2}'` != "$(PKG_VERSION)" ]; then \
echo doc/ChangeLog needs to be updated; \
exit 1; \
include scripts/docker/crossbuild.mk
endif
+#
+# Conditionally include the docker make file
+#
+ifneq "$(findstring docker,$(MAKECMDGOALS))" ""
+ include scripts/docker/docker.mk
+endif
+
#
# Clean gcov files, too.
#
--- /dev/null
+#
+# Docker targets to create Docker images that run FreeRADIUS
+#
+ifeq ($(shell which docker 2> /dev/null),)
+.PHONY: docker docker.help
+docker docker.help :
+ @echo docker targets require Docker to be installed
+else
+
+#
+# Short list of common builds
+#
+DOCKER_COMMON:=ubuntu22
+
+# Top level of where all crossbuild and docker files are
+CB_DIR:=$(dir $(realpath $(lastword $(MAKEFILE_LIST))))
+
+# Where the docker directories are
+DT:=$(CB_DIR)/build
+
+# Location of top-level m4 template
+DOCKER_TMPL:=$(CB_DIR)/m4/Dockerfile.m4
+
+# List of all the docker images (sorted for "docker.info")
+IMAGES:=$(sort $(patsubst $(DT)/%,%,$(wildcard $(DT)/*)))
+
+# Don't use the Docker cache if asked
+ifneq "$(NOCACHE)" ""
+ DOCKER_BUILD_OPTS += " --no-cache"
+endif
+
+# Docker image name prefix
+D_IPREFIX:=freeradius4
+
+#
+# This Makefile is included in-line, and not via the "boilermake"
+# wrapper. But it's still useful to use the same process for
+# seeing commands that are run.
+#
+ifeq "${VERBOSE}" ""
+ Q=@
+else
+ Q=
+endif
+
+#
+# Enter here: This builds everything
+#
+.PHONY: docker docker.common
+docker: docker.info $(foreach IMG,${IMAGES},docker.${IMG})
+docker.common: docker.info $(foreach IMG,${DOCKER_COMMON},docker.${IMG})
+
+#
+# Dump out some useful information on what images we're going to test
+#
+.PHONY: docker.info docker.info_header docker.help
+docker.info: docker.info_header $(foreach IMG,${IMAGES},docker.${IMG}.status)
+ @echo All images: $(IMAGES)
+ @echo Common images: $(DOCKER_COMMON)
+
+docker.info_header:
+ @echo Built images:
+
+docker.help:
+ @echo ""
+ @echo "Make targets:"
+ @echo " docker - build all images"
+ @echo " docker.common - build and test common images"
+ @echo " docker.info - list images"
+ @echo " docker.regen - regenerate all Dockerfiles"
+ @echo ""
+ @echo "Per-image targets:"
+ @echo " docker.IMAGE.build - build image as $(D_IPREFIX)/<IMAGE>"
+ @echo " docker.IMAGE.regen - regenerate Dockerfile from template"
+ @echo ""
+ @echo "Use 'make NOCACHE=1 ...' to disregard the Docker cache on build"
+
+#
+# Regenerate all Dockerfiles from m4 templates
+#
+docker.regen: $(foreach IMG,${IMAGES},docker.${IMG}.regen)
+
+#
+# Define rules for building a particular image
+#
+define CROSSBUILD_IMAGE_RULE
+
+.PHONY: docker.${1}.status
+docker.${1}.status:
+ ${Q}docker image ls --format "\t{{.Repository}} \t{{.CreatedAt}}" $(D_IPREFIX)/${1}
+
+#
+# Build the docker image
+#
+.PHONY: docker.${1}.build
+docker.${1}.build:
+ ${Q}echo "BUILD ${1} ($(D_IPREFIX)/${1}) from $(DT)/${1}/Dockerfile"
+
+ ${Q}docker buildx build \
+ $(DOCKER_BUILD_OPTS) \
+ --progress=plain \
+ . \
+ -f $(DT)/${1}/Dockerfile \
+ -t $(D_IPREFIX)/${1}
+
+#
+# Regenerate the image Dockerfile from the m4 templates
+#
+.PHONY: docker.${1}.regen
+docker.${1}.regen: $(DT)/${1}/Dockerfile
+
+$(DT)/${1}/Dockerfile: $(DOCKER_TMPL) $(CB_DIR)/m4/docker.deb.m4 $(CB_DIR)/m4/docker.rpm.m4
+ ${Q}echo REGEN ${1} "->" $$@
+ ${Q}m4 -I $(CB_DIR)/m4 -D D_NAME=${1} -D D_TYPE=docker $$< > $$@
+
+endef
+
+#
+# Add all the image building rules
+#
+$(foreach IMAGE,$(IMAGES),\
+ $(eval $(call CROSSBUILD_IMAGE_RULE,$(IMAGE))))
+
+
+# if docker is defined
+endif
--- /dev/null
+#!/bin/sh
+set -e
+
+# this if will check if the first argument is a flag
+# but only works if all arguments require a hyphenated flag
+# -v; -SL; -f arg; etc will work, but not arg1 arg2
+if [ "$#" -eq 0 ] || [ "${1#-}" != "$1" ]; then
+ set -- freeradius "$@"
+fi
+
+# check for the expected command
+if [ "$1" = 'freeradius' ]; then
+ shift
+ exec freeradius -f "$@"
+fi
+
+# many people are likely to call "radiusd" as well, so allow that
+if [ "$1" = 'radiusd' ]; then
+ shift
+ exec freeradius -f "$@"
+fi
+
+# else default to run whatever the user wanted like "bash" or "sh"
+exec "$@"
--- /dev/null
+#!/bin/sh
+set -e
+
+# this if will check if the first argument is a flag
+# but only works if all arguments require a hyphenated flag
+# -v; -SL; -f arg; etc will work, but not arg1 arg2
+if [ "$#" -eq 0 ] || [ "${1#-}" != "$1" ]; then
+ set -- radiusd "$@"
+fi
+
+# check for the expected command
+if [ "$1" = 'radiusd' ]; then
+ shift
+ exec radiusd -f "$@"
+fi
+
+# debian people are likely to call "freeradius" as well, so allow that
+if [ "$1" = 'freeradius' ]; then
+ shift
+ exec radiusd -f "$@"
+fi
+
+# else default to run whatever the user wanted like "bash" or "sh"
+exec "$@"
--- /dev/null
+ARG from=DOCKER_IMAGE
+FROM ${from} as build
+
+ARG DEBIAN_FRONTEND=noninteractive
+
+#
+# Install build tools
+#
+RUN apt-get update
+RUN apt-get install -y devscripts equivs git quilt gcc curl
+
+#
+# Set up NetworkRADIUS extras repository
+#
+RUN install -d -o root -g root -m 0755 /etc/apt/keyrings \
+ && curl -o /etc/apt/keyrings/packages.networkradius.com.asc "https://packages.networkradius.com/pgp/packages%40networkradius.com" \
+ && echo "deb [signed-by=/etc/apt/keyrings/packages.networkradius.com.asc] http://packages.networkradius.com/extras/OS_NAME/OS_CODENAME OS_CODENAME main" > /etc/apt/sources.list.d/networkradius-extras.list \
+ && apt-get update
+
+#
+# Create build directory
+#
+RUN mkdir -p /usr/local/src/repositories/freeradius-server
+WORKDIR /usr/local/src/repositories/freeradius-server/
+
+#
+# Copy the FreeRADIUS directory in
+#
+COPY . .
+
+#
+# Clean up tree - we want to build from the latest commit, not from
+# any cruft left around on the local system
+#
+RUN git clean -fdxx \
+ && git reset --hard HEAD
+
+#
+# Install build dependencies
+#
+RUN if [ -e ./debian/control.in ]; then \
+ debian/rules debian/control; \
+ fi; \
+ echo 'y' | mk-build-deps -irt'apt-get -yV' debian/control
+
+#
+# Build the server
+#
+RUN make -j$(nproc) deb
+
+#
+# Clean environment and run the server
+#
+FROM ${from}
+ARG DEBIAN_FRONTEND=noninteractive
+
+COPY --from=build /usr/local/src/repositories/*.deb /tmp/
+
+#
+# We need curl to get the signing key
+#
+RUN apt-get update \
+ && apt-get install -y curl \
+ && apt-get clean \
+ && rm -r /var/lib/apt/lists/*
+
+#
+# Set up NetworkRADIUS extras repository
+#
+RUN install -d -o root -g root -m 0755 /etc/apt/keyrings \
+ && curl -o /etc/apt/keyrings/packages.networkradius.com.asc "https://packages.networkradius.com/pgp/packages%40networkradius.com" \
+ && echo "deb [signed-by=/etc/apt/keyrings/packages.networkradius.com.asc] http://packages.networkradius.com/extras/OS_NAME/OS_CODENAME OS_CODENAME main" > /etc/apt/sources.list.d/networkradius-extras.list
+
+ifelse(ifelse(
+ D_NAME, `debian10', no,
+ D_NAME, `ubuntu18', no,
+ D_NAME, `ubuntu20', no,
+ yes), yes, `dnl
+ARG freerad_uid=101
+ARG freerad_gid=101
+
+RUN groupadd -g ${freerad_gid} -r freerad \
+ && useradd -u ${freerad_uid} -g freerad -r -M -d /etc/freeradius -s /usr/sbin/nologin freerad \
+ && apt-get update \',
+`RUN apt-get update \')
+ && apt-get install -y /tmp/*.deb \
+ && apt-get clean \
+ && rm -r /var/lib/apt/lists/* /tmp/*.deb \
+ \
+ && ln -s /etc/freeradius /etc/raddb
+
+WORKDIR /
+COPY scripts/docker/etc/docker-entrypoint.sh.PKG_TYPE docker-entrypoint.sh
+RUN chmod +x docker-entrypoint.sh
+
+EXPOSE 1812/udp 1813/udp
+ENTRYPOINT ["/docker-entrypoint.sh"]
+CMD ["freeradius"]
--- /dev/null
+ARG from=DOCKER_IMAGE
+FROM ${from} as build
+
+ifelse(OS_VER, 8, `dnl
+RUN rpmkeys --import /etc/pki/rpm-gpg/RPM-GPG-KEY-rockyofficial
+')dnl
+ifelse(OS_VER, 9, `dnl
+RUN rpmkeys --import /etc/pki/rpm-gpg/RPM-GPG-KEY-Rocky-9
+')
+#
+# Install build tools
+#
+RUN yum groupinstall -y "Development Tools"
+ifelse(OS_VER, 7,`dnl
+RUN yum install -y rpmdevtools
+RUN yum install -y openssl
+',`
+RUN yum install -y rpmdevtools openssl dnf-utils
+')
+
+#
+# Set up NetworkRADIUS extras repository
+#
+RUN echo $'[networkradius-extras]\n\
+name=NetworkRADIUS-extras-$releasever\n\
+baseurl=http://packages.networkradius.com/extras/OS_NAME/$releasever/\n\
+enabled=1\n\
+gpgcheck=1\n\
+gpgkey=https://packages.networkradius.com/pgp/packages@networkradius.com'\
+> /etc/yum.repos.d/networkradius-extras.repo
+RUN rpm --import https://packages.networkradius.com/pgp/packages@networkradius.com
+
+#
+# Create build directory
+#
+RUN mkdir -p /usr/local/src/repositories/freeradius-server
+WORKDIR /usr/local/src/repositories/freeradius-server/
+
+#
+# Copy the FreeRADIUS directory in
+#
+COPY . .
+
+#
+# Clean up tree - we want to build from the latest commit, not from
+# any cruft left around on the local system
+#
+RUN git clean -fdxx \
+ && git reset --hard HEAD
+
+#
+# Other requirements
+#
+changequote(`{', `}')dnl
+ifelse(ifelse(OS_VER, 8, yes, no), yes, {
+# Use LTB's openldap packages instead of the distribution version to avoid linking against NSS
+RUN echo $'[ltb-project]\n\
+name=LTB project packages\n\
+baseurl=https://ltb-project.org/rpm/$releasever/$basearch\n\
+enabled=1\n\
+gpgcheck=1\n\
+gpgkey=file:///etc/pki/rpm-gpg/RPM-GPG-KEY-LTB-project'\
+> /etc/yum.repos.d/ltb-project.repo
+RUN rpm --import https://ltb-project.org/lib/RPM-GPG-KEY-LTB-project
+})dnl
+changequote({`}, {'})dnl
+
+# Enable EPEL repository for freetds and hiredis
+RUN yum install -y https://dl.fedoraproject.org/pub/epel/epel-release-latest-OS_VER.noarch.rpm
+ifelse(OS_VER, 8, `
+# Enable powertools repo
+RUN yum config-manager --enable powertools
+
+# Enable epel-testing, currently needed for hiredis-devel
+RUN yum config-manager --enable epel-testing
+')dnl
+ifelse(OS_VER, 9, `
+# Enable Code Ready Builder repo (CentOS powertools equivalent)
+RUN yum install -y yum-utils
+RUN yum config-manager --enable crb
+')dnl
+
+#
+# Install build dependencies
+#
+# Run twice, it doesn't always get everything with one invocation
+RUN [ -e redhat/freeradius.spec ] && \
+ yum-builddep -y redhat/freeradius.spec && \
+ yum-builddep -y redhat/freeradius.spec
+
+#
+# Create RPM build environment
+#
+ENV BUILDDIR=/root/rpmbuild
+RUN rpmdev-setuptree
+
+RUN ./configure
+RUN make pkg_version > /VERSION
+RUN cat /VERSION
+RUN make freeradius-server-$(cat /VERSION).tar.bz2
+RUN cp freeradius-server-$(cat /VERSION).tar.bz2 $BUILDDIR/SOURCES/
+RUN cp -r redhat/* $BUILDDIR/SOURCES/
+RUN make dist-check-rpm
+RUN cp -r redhat/freeradius.spec $BUILDDIR/SPECS/
+WORKDIR $BUILDDIR
+
+#
+# Build the server
+#
+ENV QA_RPATHS=0x0003
+RUN rpmbuild -bb --define "_release $(cat /VERSION)" "$BUILDDIR/SPECS/freeradius.spec"
+
+RUN mkdir /root/rpms
+RUN mv $BUILDDIR/RPMS/*/*.rpm /root/rpms/
+
+#
+# Clean environment and run the server
+#
+FROM ${from}
+
+COPY --from=build /root/rpms /tmp/
+
+#
+# Set up NetworkRADIUS extras repository
+#
+RUN echo $'[networkradius-extras]\n\
+name=NetworkRADIUS-extras-$releasever\n\
+baseurl=http://packages.networkradius.com/extras/OS_NAME/$releasever/\n\
+enabled=1\n\
+gpgcheck=1\n\
+gpgkey=https://packages.networkradius.com/pgp/packages@networkradius.com'\
+> /etc/yum.repos.d/networkradius-extras.repo
+RUN rpm --import https://packages.networkradius.com/pgp/packages@networkradius.com
+
+#
+# Other requirements
+#
+changequote(`{', `}')dnl
+ifelse(ifelse(OS_VER, 8, yes, no), yes, {dnl
+# Use LTB's openldap packages instead of the distribution version to avoid linking against NSS
+RUN echo $'[ltb-project]\n\
+name=LTB project packages\n\
+baseurl=https://ltb-project.org/rpm/$releasever/$basearch\n\
+enabled=1\n\
+gpgcheck=1\n\
+gpgkey=file:///etc/pki/rpm-gpg/RPM-GPG-KEY-LTB-project'\
+> /etc/yum.repos.d/ltb-project.repo \
+ && rpm --import https://ltb-project.org/lib/RPM-GPG-KEY-LTB-project
+})dnl
+changequote({`}, {'})dnl
+
+ifelse(OS_VER, 9, `dnl
+# Needed for mysql-libs on Rocky 9
+RUN yum install -y yum-utils
+RUN yum config-manager --enable crb
+')dnl
+
+# EPEL repository for freetds and hiredis
+RUN yum install -y https://dl.fedoraproject.org/pub/epel/epel-release-latest-OS_VER.noarch.rpm \
+ && yum install -y dnf-utils \
+ && yum config-manager --enable epel-testing
+
+ARG radiusd_uid=95
+ARG radiusd_gid=95
+
+RUN groupadd -g ${radiusd_gid} -r radiusd \
+ && useradd -u ${radiusd_uid} -g radiusd -r -M -d /home/radiusd -s /sbin/nologin radiusd \
+ && yum install -y /tmp/*.rpm
+
+WORKDIR /
+COPY scripts/docker/etc/docker-entrypoint.sh.PKG_TYPE docker-entrypoint.sh
+RUN chmod +x docker-entrypoint.sh
+
+EXPOSE 1812/udp 1813/udp
+ENTRYPOINT ["/docker-entrypoint.sh"]
+CMD ["radiusd"]