Skip to content

Commit

Permalink
debian: Cleanup build process using more debhelper features (#223)
Browse files Browse the repository at this point in the history
refactor quite a bit the `debian/*` code so that we are less dependent
on our scripts, but instead we use debian tooling more.

In particular:
- Ensure that generated go files are properly created when bootstrapping
the repo and removing them
  - Use `dh-cargo` tools more, reducing duplication
    - And when it's not possible, mimic its behavior more
  - Address various lintian warnings
  - Use install files to install the produced binaries
- It has the benefit of fail if we miss something or if we're adding
unexpected
- Install the daemons in `/usr/libexec` instead of `/usr/sbin` (there's
no need for them to be in `$PATH`)

Closes: #218 

UDENG-2342
  • Loading branch information
denisonbarbosa authored Feb 29, 2024
2 parents 31f1add + 87985bd commit f97ddf1
Show file tree
Hide file tree
Showing 23 changed files with 144 additions and 66 deletions.
1 change: 1 addition & 0 deletions Cargo.lock

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

2 changes: 1 addition & 1 deletion systemd/authd.service → debian/authd.service.in
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@ PartOf=authd.socket

[Service]
Type=notify
ExecStart=/sbin/authd
ExecStart=@AUTHD_DAEMONS_PATH@/authd

# Some daemon restrictions
LockPersonality=yes
Expand Down
File renamed without changes.
11 changes: 7 additions & 4 deletions debian/control
Original file line number Diff line number Diff line change
Expand Up @@ -3,15 +3,17 @@ Section: admin
Priority: optional
Maintainer: Ubuntu Developers <[email protected]>
Build-Depends: debhelper-compat (= 13),
dbus,
dbus <!nocheck>,
dh-apport,
dh-cargo,
dh-exec,
dh-golang,
dctrl-tools,
golang-go (>= 2:1.21~),
jq,
libc6-dev (>= 2.35),
libpam0g-dev,
pkg-config,
pkgconf,
protobuf-compiler,
Standards-Version: 4.6.2
XS-Go-Import-Path: github.com/ubuntu/authd
Expand All @@ -21,7 +23,6 @@ Vcs-Browser: https://github.com/ubuntu/authd
Vcs-Git: https://github.com/ubuntu/authd.git
Rules-Requires-Root: no
Description: Authentication daemon for cloud-based identity provider
.
Authd is a versatile authentication service designed to seamlessly integrate
with cloud identity providers like OpenID Connect and Entra ID. It offers a
secure interface for system authentication, supporting cloud-based identity
Expand All @@ -31,7 +32,9 @@ Description: Authentication daemon for cloud-based identity provider

Package: authd
Architecture: any
Built-Using: ${misc:Built-Using},
Built-Using: ${misc:Built-Using}, ${cargo:Built-Using}
Static-Built-Using: ${misc:Static-Built-Using}, ${cargo:Static-Built-Using},
X-Cargo-Built-Using: ${cargo:X-Cargo-Built-Using},
Depends: ${shlibs:Depends},
${misc:Depends},
Description: ${source:Synopsis}
Expand Down
12 changes: 0 additions & 12 deletions debian/copyright
Original file line number Diff line number Diff line change
Expand Up @@ -321,10 +321,6 @@ Files: vendor_rust/errno/*
Copyright: 2014 Chris Wong
License: MIT

Files: vendor_rust/errno-dragonfly/*
Copyright: 2017 Michael Neumann
License: MIT

Files: vendor_rust/error-chain/*
Copyright: 2017 The Error-Chain Project Developers
License: MIT
Expand Down Expand Up @@ -384,10 +380,6 @@ Files: vendor_rust/hyper-timeout/*
Copyright: 2016 The weldr Project Developers
License: MIT

Files: vendor_rust/is-terminal/*
Copyright: 2015-2019 Doug Tangren
License: MIT

Files: vendor_rust/matchit/*
Copyright: 2022 Ibraheem Ahmed
License: MIT
Expand Down Expand Up @@ -425,10 +417,6 @@ Files: vendor_rust/rand/*
Copyright: 2018 Developers of the Rand project / 2014 The Rust Project Developers
License: MIT

Files: vendor_rust/redox_syscall/*
Copyright: 2017 Redox OS Developers
License: MIT

Files: vendor_rust/simple_logger/*
Copyright: 2015-2021 Sam Clements
License: MIT
Expand Down
2 changes: 2 additions & 0 deletions debian/docs
Original file line number Diff line number Diff line change
@@ -1,2 +1,4 @@
# Vendored dependency contains an Apache NOTICE
vendor/gopkg.in/yaml.v3/NOTICE
# Vendored rust dependencies
Cargo.lock
14 changes: 14 additions & 0 deletions debian/install
Original file line number Diff line number Diff line change
@@ -0,0 +1,14 @@
#!/usr/bin/dh-exec

# Install daemon
usr/bin/authd ${env:AUTHD_DAEMONS_PATH}

# pam-auth-update files
debian/pam-configs/* /usr/share/pam-configs

# PAM libraries
${env:BUILT_PAM_LIBS_PATH}/pam_authd.so ${env:AUTHD_PAM_MODULES_PATH}
${env:BUILT_PAM_LIBS_PATH}/go-loader/pam_go_loader.so ${env:AUTHD_PAM_MODULES_PATH}

# Install NSS library with right soname
target/${DEB_HOST_RUST_TYPE}/release/libnss_authd.so => /usr/lib/${DEB_TARGET_GNU_TYPE}/libnss_authd.so.2
1 change: 1 addition & 0 deletions debian/not-installed
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
usr/bin/pam
94 changes: 50 additions & 44 deletions debian/rules
Original file line number Diff line number Diff line change
@@ -1,8 +1,12 @@
#!/usr/bin/make -f
#export DH_VERBOSE = 1

export GOCACHE := $(shell mktemp -d /tmp/gocache-XXXX)
export GOFLAGS := -ldflags=-X=github.com/ubuntu/authd/internal/consts.Version=$(shell dpkg-parsechangelog -S Version) --mod=vendor -buildmode=pie
include /usr/share/rustc/architecture.mk

# The package name for authd, used only locally to avoid repetitions
AUTHD_GO_PACKAGE := $(shell grep-dctrl -s XS-Go-Import-Path -n - ./debian/control)

export GOFLAGS := -ldflags=-X=$(AUTHD_GO_PACKAGE)/internal/consts.Version=$(shell dpkg-parsechangelog -S Version) --mod=vendor -buildmode=pie

export DEB_BUILD_MAINT_OPTIONS := optimize=-lto

Expand All @@ -12,15 +16,16 @@ export DPKG_GENSYMBOLS_CHECK_LEVEL := 4
# Copy in build directory all content to embed
export DH_GOLANG_INSTALL_ALL := 1

# The following definitions are necessary because of the manual steps
# we need to do to work around some issues with either dh-cargo,
# the wrapper, or cargo
include /usr/share/rustc/architecture.mk
CARGO := /usr/share/cargo/bin/cargo
# We want to take whatever ubuntu propose to us (as it won’t download a newer version),
# as long as it matches the go.mod go stenza which is the language requirement.
export GOTOOLCHAIN := local

# Use the debian cargo wrapper
export CARGO_PATH := /usr/share/cargo/bin/cargo

# Needed for Rust vendored sources tracking
DH_CARGO_VENDORED_SOURCES := /usr/share/cargo/bin/dh-cargo-vendored-sources
export CARGO_VENDOR_DIR = vendor_rust
export DH_CARGO_VENDORED_SOURCES := /usr/share/cargo/bin/dh-cargo-vendored-sources
export CARGO_VENDOR_DIR := $(CURDIR)/vendor_rust

# Needed for Rust configure/build/test stages
export DEB_HOST_GNU_TYPE DEB_HOST_RUST_TYPE
Expand All @@ -29,12 +34,28 @@ export CARGO_HOME = $(CURDIR)/debian/cargo_home
# Needed by the pam module loader
export AUTHD_PAM_MODULES_PATH = /usr/lib/$(DEB_TARGET_GNU_TYPE)/security

# Used not to hardcore the daemons paths
export AUTHD_DAEMONS_PATH := /usr/libexec

# Skip some tests that rely on external dependencies when building package:
# they need external commands (e.g. `vhs`) that are not available in the build environment.
export AUTHD_SKIP_EXTERNAL_DEPENDENT_TESTS=1

# Skip some tests that fail when running as root as it may happen when building the packages
# in sbuild or similar environments.
export AUTHD_SKIP_ROOT_TESTS := 1

# Defines the targets to be built as part of dh_auto_build
export DH_GOLANG_BUILDPKG := $(AUTHD_GO_PACKAGE)/... \
$(NULL)

BUILDDIR := $(CURDIR)/obj-$(DEB_HOST_GNU_TYPE)

export BUILT_PAM_LIBS_PATH := obj-$(DEB_HOST_GNU_TYPE)/src/$(AUTHD_GO_PACKAGE)/pam

%:
dh $@ --buildsystem=golang --with=golang,apport
# --without=single-binary can be removed with dh 15.
dh $@ --buildsystem=golang --with=golang,apport --without=single-binary

override_dh_auto_clean:
dh_auto_clean
Expand All @@ -44,54 +65,39 @@ override_dh_auto_clean:
[ -d vendor/ ] || go mod vendor

# Vendor Rust dependencies when building the source package
[ -d vendor_rust/ ] || \
CARGO=$(CARGO) DH_CARGO_VENDORED_SOURCES=$(DH_CARGO_VENDORED_SOURCES) \
CARGO_VENDOR_DIR=$(CARGO_VENDOR_DIR) debian/vendor-rust.sh
[ -d vendor_rust/ ] || debian/vendor-rust.sh

# Cleanup empty cargo-checksum
rm -f debian/cargo-checksum.json

# Cleanup generated service files
rm -f debian/*.service

override_dh_auto_configure:
dh_auto_configure

[ ! -e $(DH_CARGO_VENDORED_SOURCES) ] || $(DH_CARGO_VENDORED_SOURCES)
DEB_CARGO_CRATE=nss_$(shell dpkg-parsechangelog --show-field Version) \
RUSTFLAGS="--cfg=rustix_use_libc" \
$(CARGO) prepare-debian $(CARGO_VENDOR_DIR)
touch debian/cargo-checksum.json
dh_auto_configure --buildsystem=cargo

for i in debian/*.service.in; do \
sed s,@AUTHD_DAEMONS_PATH@,$(AUTHD_DAEMONS_PATH),g $$i > $${i%.*}; \
done

override_dh_auto_build:
# Build PAM library & Go loader
go generate -x ./pam
DH_GOLANG_GO_GENERATE=1 dh_auto_build -- $(AUTHD_GO_PACKAGE)/pam

# Build the NSS library
$(CARGO) build --release
$(CARGO_PATH) build --release

# Build the daemon
DH_GOLANG_BUILDPKG=github.com/ubuntu/authd/cmd/authd dh_auto_build

override_dh_auto_test:
# We need to specify these Rust related variables to the Go tests in order to build the NSS lib
# with the cargo wrapper in the integration tests in order to force cargo to use vendored deps
# instead of querying crates.io for them.
CARGO_PATH=$(CARGO) dh_auto_test
dh_auto_build -- $(AUTHD_GO_PACKAGE)/cmd/authd

override_dh_auto_install:
dh_auto_install -- --no-source

# Install daemon in /sbin
mv debian/authd/usr/bin/ debian/authd/usr/sbin

# Install PAM module configuration
install -Dm644 debian/pam-configs/authd debian/authd/usr/share/pam-configs/authd

# Install PAM
install -Dm644 pam/go-loader/pam_go_loader.so debian/authd/$(AUTHD_PAM_MODULES_PATH)/pam_go_loader.so
install -Dm644 pam/pam_authd.so debian/authd/$(AUTHD_PAM_MODULES_PATH)/pam_authd.so

# Install NSS
# In Rust, HOST actually refers to the build target (see README.Debian in rustc)
install -Dm644 target/$(DEB_HOST_RUST_TYPE)/release/libnss_authd.so debian/authd/usr/lib/$(DEB_TARGET_GNU_TYPE)/libnss_authd.so.2
dh_auto_install --destdir=debian/tmp -- --no-source

# Install systemd units
mkdir -p debian/authd/lib/systemd/system
install -m644 systemd/* debian/authd/lib/systemd/system/
# Fills the built-using variables for rust
/usr/share/cargo/bin/dh-cargo-built-using authd

# Install gdm-PAM config file
dh_installpam -pauthd --name=gdm-authd
8 changes: 8 additions & 0 deletions debian/source/options
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
tar-ignore = */.git*
tar-ignore = */.go*
tar-ignore = */.editor*
tar-ignore = */.mailmap
tar-ignore = */.vscode
tar-ignore = *.so
tar-ignore = *.o
tar-ignore = vendor_rust/*.a
3 changes: 2 additions & 1 deletion debian/tests/control
Original file line number Diff line number Diff line change
@@ -1,3 +1,4 @@
Test-Command: AUTHD_SKIP_EXTERNAL_DEPENDENT_TESTS=1 go test -v -mod=vendor ./...
Test-Command: debian/tests/run-tests.sh
Features: test-name=go_tests
Restrictions: allow-stderr
Depends: @builddeps@
9 changes: 9 additions & 0 deletions debian/tests/run-tests.sh
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
#!/usr/bin/env bash

set -exuo pipefail

export AUTHD_SKIP_EXTERNAL_DEPENDENT_TESTS=1
export GOPROXY=off
export GOTOOLCHAIN=local

go test -v ./...
6 changes: 5 additions & 1 deletion debian/vendor-rust.sh
Original file line number Diff line number Diff line change
@@ -1,10 +1,14 @@
#!/bin/sh
set -eu

CARGO_HOME=${DEB_CARGO_HOME:-$(mktemp --tmpdir -d -t "cargo-home-XXXXXX")}
export CARGO_HOME
trap 'rm -rf "$CARGO_HOME"' EXIT INT HUP

# Some crates are shipped with .a files, which get removed by the helpers during the package build as a safety measure.
# This results in cargo failing to compile, since the files (which are listed in the checksums) are not there anymore.
# For those crates, we need to replace their checksum with a more general one that only lists the crate checksum, instead of each file.
CARGO_HOME=${HOME}/.cargo ${CARGO} vendor "${CARGO_VENDOR_DIR}"
${CARGO_PATH} vendor "${CARGO_VENDOR_DIR}"

[ ! -e "${DH_CARGO_VENDORED_SOURCES}" ] || ${DH_CARGO_VENDORED_SOURCES}
[ -e /usr/bin/jq ] || (echo "jq is required to run this script. Try installing it with 'sudo apt install jq'" && exit 1)
Expand Down
6 changes: 6 additions & 0 deletions internal/daemon/testdata/grpctestservice/generate.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
//go:build generate

//go:generate ../../../../tools/generate-proto.sh --with-grpc grpctestservice.proto

// Package grpctestservice contains the autogenerated GRPC API.
package grpctestservice
13 changes: 13 additions & 0 deletions internal/users/cache/db_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -60,6 +60,14 @@ func TestNew(t *testing.T) {
if tc.perm != nil {
err := os.Chmod(dbDestPath, *tc.perm)
require.NoError(t, err, "Setup: could not change mode of database file")

if *tc.perm == perm0644 {
currentUser, err := user.Current()
require.NoError(t, err)
if os.Getenv("AUTHD_SKIP_ROOT_TESTS") != "" && currentUser.Username == "root" {
t.Skip("Can't do permission checks as root")
}
}
}

c, err := cache.New(cacheDir)
Expand Down Expand Up @@ -452,6 +460,11 @@ func TestClear(t *testing.T) {
require.NoError(t, os.Remove(c.DbPath()), "Setup: should be able to remove database file")
}
if tc.readOnlyDir {
currentUser, err := user.Current()
require.NoError(t, err)
if os.Getenv("AUTHD_SKIP_ROOT_TESTS") != "" && currentUser.Username == "root" {
t.Skip("Can't do permission checks as root")
}
testutils.MakeReadOnly(t, filepath.Dir(c.DbPath()))
}

Expand Down
1 change: 1 addition & 0 deletions nss/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -22,6 +22,7 @@ libc = "0.2.152"
paste = "1.0.14"
tonic = "0.11.0"
prost = "0.12.3"
rustix = { version = "0.38.31", features = ["use-libc"] }
tokio = { version = "1.35.1", features = ["macros", "rt-multi-thread"] }
tower = "0.4.13"
log = "0.4.20"
Expand Down
4 changes: 3 additions & 1 deletion pam/generate.go
Original file line number Diff line number Diff line change
@@ -1,4 +1,6 @@
//go:build generate && !pam_debug
//go:build generate && !pam_module_generation && !pam_debug

//go:generate go generate -C internal/proto

//go:generate ./generate.sh -tags "!pam_binary_cli && !pam_debug"

Expand Down
8 changes: 7 additions & 1 deletion pam/generate.sh
Original file line number Diff line number Diff line change
Expand Up @@ -2,23 +2,29 @@

set -euo pipefail

PROJECT_ROOT=$PWD/..
SCRIPT_PATH=$(dirname "$0")
PROJECT_ROOT=$(realpath "$SCRIPT_PATH")/..
module_libname=pam_authd.so
loader_libname=pam_go_loader.so

cd "$SCRIPT_PATH"

if [ -d "$PROJECT_ROOT"/vendor ]; then
echo Vendored dependencies detected, not re-generating pam_module.go
else
go run github.com/msteinert/pam/v2/cmd/pam-moduler \
-libname "$module_libname" -type pamModule \
"${@}"
go generate -x -tags pam_module_generation
fi

cc_args=()
if [ -v AUTHD_PAM_MODULES_PATH ]; then
cc_args+=(-DAUTHD_PAM_MODULES_PATH=\""${AUTHD_PAM_MODULES_PATH}"\")
fi

# shellcheck disable=SC2086
# we do want to do word splitting on flags
${CC:-cc} -o go-loader/"$loader_libname" \
go-loader/module.c ${CFLAGS:-} -Wl,--as-needed -Wl,--allow-shlib-undefined \
-shared -fPIC -Wl,--unresolved-symbols=report-all \
Expand Down
4 changes: 3 additions & 1 deletion pam/generate_debug.go
Original file line number Diff line number Diff line change
@@ -1,4 +1,6 @@
//go:build generate && pam_debug
//go:build generate && !pam_module_generation && pam_debug

//go:generate go generate -C internal/proto

//go:generate env CFLAGS=-g3 CGO_CFLAGS=-g3 ./generate.sh -tags "!pam_binary_cli && pam_debug" -build-tags pam_gdm_debug -output pam_module_debug.go

Expand Down
5 changes: 5 additions & 0 deletions tools/generate-proto.sh
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,11 @@

set -euo pipefail

if [ -v DEB_HOST_GNU_TYPE ]; then
echo "Proto files should not be regenerated during package building"
exit 0
fi

# TODO: Watch https://github.com/protocolbuffers/protobuf for any changes on the
# experimental status of optional fields, previously described on:
# https://github.com/protocolbuffers/protobuf/blob/main/docs/implementing_proto3_presence.md.
Expand Down
Loading

0 comments on commit f97ddf1

Please sign in to comment.