Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Package dnst as DEB & RPM packages, and Docker images. #22

Draft
wants to merge 25 commits into
base: use-domain-nsec3-support
Choose a base branch
from
Draft
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
25 commits
Select commit Hold shift + click to select a range
e852f25
Initial packaging attempt.
ximon18 Nov 13, 2024
27ae143
Merge branch 'use-domain-nsec3-support' into packaging
ximon18 Nov 13, 2024
8e056dc
Update pkg.yml
ximon18 Nov 13, 2024
afb9c6c
Remove file in wrong directory.
ximon18 Nov 13, 2024
68dd251
No dockerfile yet.
ximon18 Nov 13, 2024
d7e51b2
Add required metadata and a symbolic link via assets (if that works o…
ximon18 Nov 13, 2024
65771d9
Merge branch 'packaging' of github.com:NLnetLabs/dnst into packaging
ximon18 Nov 13, 2024
fcb522e
Fix incorrect links paths.
ximon18 Nov 13, 2024
2e5c0c0
Does 777 help for a symlink?
ximon18 Nov 13, 2024
69dd0c7
And without preserve-symlinks?
ximon18 Nov 13, 2024
b5dc5b4
Try maintainer scripts for creating symlinks instead.
ximon18 Nov 13, 2024
43440ec
Invert ln args. Use scripts for symlink creation for RPMs too.
ximon18 Nov 13, 2024
3d5373d
FIX: -V/--version output shouldn't output the module prefix or set th…
ximon18 Nov 13, 2024
46d46db
Remove unused symlink.
ximon18 Nov 13, 2024
2caa3a6
Fix upgrade failure due to existing sym link.
ximon18 Nov 13, 2024
d3884fe
Remove symlinks in prerm, not postrm, to attempt to fix package upgrade.
ximon18 Nov 13, 2024
be163b6
Overwrite existing symlinks on RPM upgrade.
ximon18 Nov 13, 2024
ed7d058
Instruct package managers that dnst replaces/obsoletes ldns utilities.
ximon18 Nov 13, 2024
6601204
cargo-generate-rpm obsoletes must be a string.
ximon18 Nov 13, 2024
32bd39c
cargo-generate-rpm obsoletes must be a string: second attempt (the co…
ximon18 Nov 13, 2024
5937ad7
Use conflicts instead of replaces because uninstall of obsolete ldns …
ximon18 Nov 14, 2024
7dd9ffb
FIX: ldns-xxx parse error should not cause dnst command to be tried.
ximon18 Nov 14, 2024
19ef71f
Add a dnst docker image.
ximon18 Nov 14, 2024
5cd885b
Oops, add tini.
ximon18 Nov 14, 2024
771ce14
We need libgcc too.
ximon18 Nov 14, 2024
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 2 additions & 0 deletions .dockerignore
Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@
/target
.git
19 changes: 12 additions & 7 deletions .github/workflows/pkg.yml
Original file line number Diff line number Diff line change
Expand Up @@ -2,8 +2,6 @@ name: Packaging

on:
push:
branches:
- "main"
tags:
- v*

Expand All @@ -14,10 +12,17 @@ on:

jobs:
package:
#
# Set @vN to the latest released version.
# For more information see: https://github.com/NLnetLabs/ploutos/blob/main/README.md
#
uses: NLnetLabs/ploutos/.github/workflows/pkg-rust.yml@v7
# secrets:
# DOCKER_HUB_ID: ${{ secrets.DOCKER_HUB_ID }}
# DOCKER_HUB_TOKEN: ${{ secrets.DOCKER_HUB_TOKEN }}
with:
docker_org: nlnetlabs
docker_repo: dnst
docker_build_rules: pkg/rules/docker-images-to-build.yml
docker_sanity_check_command: --version

# TODO
package_build_rules: pkg/rules/packages-to-build.yml
package_test_scripts_path: pkg/test-scripts/test-<package>.sh

rpm_scriptlets_path: pkg/rpm/scriptlets.toml
48 changes: 46 additions & 2 deletions Cargo.toml
Original file line number Diff line number Diff line change
@@ -1,7 +1,12 @@
[package]

Check notice on line 1 in Cargo.toml

View workflow job for this annotation

GitHub Actions / package / pkg (dnst, ubuntu:xenial, x86_64)

Cargo deb variant 'ubuntu-xenial' not found, using defaults instead.

Check notice on line 1 in Cargo.toml

View workflow job for this annotation

GitHub Actions / package / pkg (dnst, ubuntu:bionic, x86_64)

Cargo deb variant 'ubuntu-bionic' not found, using defaults instead.

Check notice on line 1 in Cargo.toml

View workflow job for this annotation

GitHub Actions / package / pkg (dnst, ubuntu:focal, x86_64)

Cargo deb variant 'ubuntu-focal' not found, using defaults instead.

Check notice on line 1 in Cargo.toml

View workflow job for this annotation

GitHub Actions / package / pkg (dnst, ubuntu:jammy, x86_64)

Cargo deb variant 'ubuntu-jammy' not found, using defaults instead.

Check notice on line 1 in Cargo.toml

View workflow job for this annotation

GitHub Actions / package / pkg (dnst, debian:stretch, x86_64)

Cargo deb variant 'debian-stretch' not found, using defaults instead.

Check notice on line 1 in Cargo.toml

View workflow job for this annotation

GitHub Actions / package / pkg (dnst, debian:buster, x86_64)

Cargo deb variant 'debian-buster' not found, using defaults instead.

Check notice on line 1 in Cargo.toml

View workflow job for this annotation

GitHub Actions / package / pkg (dnst, debian:bullseye, x86_64)

Cargo deb variant 'debian-bullseye' not found, using defaults instead.

Check notice on line 1 in Cargo.toml

View workflow job for this annotation

GitHub Actions / package / pkg (dnst, debian:bookworm, x86_64)

Cargo deb variant 'debian-bookworm' not found, using defaults instead.

Check notice on line 1 in Cargo.toml

View workflow job for this annotation

GitHub Actions / package / pkg (dnst, debian:bullseye, armv7-unknown-linux-musleabihf)

Cargo deb variant 'debian-bullseye-armv7-unknown-linux-musleabihf' not found, using defaults instead.

Check notice on line 1 in Cargo.toml

View workflow job for this annotation

GitHub Actions / package / pkg (dnst, debian:buster, arm-unknown-linux-musleabihf)

Cargo deb variant 'debian-buster-arm-unknown-linux-musleabihf' not found, using defaults instead.

Check notice on line 1 in Cargo.toml

View workflow job for this annotation

GitHub Actions / package / pkg (dnst, debian:buster, aarch64-unknown-linux-musl)

Cargo deb variant 'debian-buster-aarch64-unknown-linux-musl' not found, using defaults instead.
name = "dnst"
version = "0.1.0"
edition = "2021"
authors = ["NLnet Labs <[email protected]>"]
description = "Reimplementation of important ldns programs."
repository = "https://github.com/NLnetLabs/dnst"
license = "BSD-3-Clause"
readme = "README.md"
default-run = "dnst"

[[bin]]
Expand All @@ -10,7 +15,7 @@

[dependencies]
arbitrary = { version = "1", optional = true, features = ["derive"] }
clap = { version = "4", features = ["derive"] }
clap = { version = "4", features = ["cargo", "derive"] }
#domain = "0.10.3"
domain = { git = "https://github.com/NLnetLabs/domain/", branch = "initial-nsec3-generation", features = ["ring", "unstable-validator"] }
lexopt = "0.3.0"
Expand All @@ -19,4 +24,43 @@
test_bin = "0.4.0"

[features]
arbitrary = [ "dep:arbitrary", "domain/arbitrary" ]
arbitrary = [ "dep:arbitrary", "domain/arbitrary" ]

[package.metadata.deb]
license-file = ["LICENSE", "0"]
depends = "$auto"
section = "net"
priority = "optional"
assets = [
["target/release/dnst", "usr/bin/", "755"],
["README.md", "usr/share/doc/dnst/", "644"],
# TODO: Extend Ploutos to generate the man pages from sources.
#["doc/dnst.1", "usr/share/man/man1/dnst.1", "644"],
]
changelog = "target/debian/changelog" # this will be generated by the pkg workflow
copyright = "Copyright (c) 2024, NLnet Labs. All rights reserved."
# preserve_symlinks didn't prevent error "Asset file path does not match any files"
# Perhaps a newer version of cargo-deb than the one used by Ploutos would fix this.
# Instead create and remove them using maintainer scripts.
#preserve-symlinks = true
maintainer-scripts = "pkg/debian"
conflicts = "ldnsutils"

[package.metadata.generate-rpm]
# "BSD" alone is the 3-clause license. Inheriting "license" from above causes rpmlint to
# complain with "invalid-license".
# See: https://fedoraproject.org/wiki/Licensing:Main?rd=Licensing
license = "BSD"
assets = [
{ source = "target/release/dnst", dest = "/usr/bin/dnst", mode = "755" },
# TODO: Extend Ploutos to generate the man pages from sources.
#{ source = "doc/routinator.1", dest = "/usr/share/man/man1/routinator.1", mode = "644", doc = true },
]

# These get set using cargo-generate-rpm --set-metadata at package build time.
#post_install_script = ...
#pre_uninstall_script = ...
#post_uninstall_script = ...

[package.metadata.generate-rpm.conflicts]
ldns-utils = "*"
150 changes: 150 additions & 0 deletions Dockerfile
Original file line number Diff line number Diff line change
@@ -0,0 +1,150 @@
# This is a multi-stage Dockerfile, with a selectable first stage. With this
# approach we get:
#
# 1. Separation of dependencies needed to build our app in the 'build' stage
# and those needed to run our app in the 'final' stage, as we don't want
# the build-time dependencies to be included in the final Docker image.
#
# 2. Support for either building our app for the architecture of the base
# image using MODE=build (the default) or for externally built app
# binaries (e.g. cross-compiled) using MODE=copy.
#
# In total there are four stages consisting of:
# - Two possible first stages: 'build' or 'copy'.
# - A special 'source' stage which selects either 'build' or 'copy' as the
# source of binaries to be used by ...
# - The 'final' stage.


###
### ARG DEFINITIONS ###########################################################
###

# This section defines arguments that can be overriden on the command line
# when invoking `docker build` using the argument form:
#
# `--build-arg <ARGNAME>=<ARGVALUE>`.

# MODE
# ====
# Supported values: build (default), copy
#
# By default this Dockerfile will build our app from sources. If the sources
# have already been (cross) compiled by some external process and you wish to
# use the resulting binaries from that process, then:
#
# 1. Create a directory on the host called 'dockerbin/$TARGETPLATFORM'
# containing the already compiled app binaries (where $TARGETPLATFORM
# is a special variable set by Docker BuiltKit).
# 2. Supply arguments `--build-arg MODE=copy` to `docker build`.
ARG MODE=build


# BASE_IMG
# ========
#
# Only used when MODE=build.
ARG BASE_IMG=alpine:3.20


# CARGO_ARGS
# ==========
#
# Only used when MODE=build.
#
# This ARG can be used to control the features enabled when compiling the app
# or other compilation settings as necessary.
ARG CARGO_ARGS


###
### BUILD STAGES ##############################################################
###


# -----------------------------------------------------------------------------
# Docker stage: build
# -----------------------------------------------------------------------------
#
# Builds our app binaries from sources.
FROM ${BASE_IMG} AS build
ARG CARGO_ARGS

RUN apk add --no-cache rust cargo

WORKDIR /tmp/build
COPY . .

# `CARGO_HTTP_MULTIPLEXING` forces Cargo to use HTTP/1.1 without pipelining
# instead of HTTP/2 with multiplexing. This seems to help with various
# "spurious network error" warnings when Cargo attempts to fetch from crates.io
# when building this image on Docker Hub and GitHub Actions build machines.
#
# `cargo install` is used instead of `cargo build` because it places just the
# binaries we need into a predictable output directory. We can't control this
# with arguments to cargo build as `--out-dir` is unstable and contentious and
# `--target-dir` still requires us to know which profile and target the
# binaries were built for. By using `cargo install` we can also avoid needing
# to hard-code the set of binary names to copy so that if we add or remove
# built binaries in future this will "just work". Note that `--root /tmp/out`
# actually causes the binaries to be placed in `/tmp/out/bin/`. `cargo install`
# will create the output directory for us.
RUN CARGO_HTTP_MULTIPLEXING=false cargo install \
--locked \
--path . \
--root /tmp/out/ \
${CARGO_ARGS}


# -----------------------------------------------------------------------------
# Docker stage: copy
# -----------------------------------------------------------------------------
# Only used when MODE=copy.
#
# Copy binaries from the host directory 'dockerbin/$TARGETPLATFORM' directory
# into this build stage to the same predictable location that binaries would be
# in if MODE were 'build'.
#
# Requires that `docker build` be invoked with variable `DOCKER_BUILDKIT=1` set
# in the environment. This is necessary so that Docker will skip the unused
# 'build' stage and so that the magic $TARGETPLATFORM ARG will be set for us.
FROM ${BASE_IMG} AS copy
ARG TARGETPLATFORM
ONBUILD COPY dockerbin/$TARGETPLATFORM /tmp/out/bin/


# -----------------------------------------------------------------------------
# Docker stage: source
# -----------------------------------------------------------------------------
# This is a "magic" build stage that "labels" a chosen prior build stage as the
# one that the build stage after this one should copy application binaries
# from. It also causes the ONBUILD COPY command from the 'copy' stage to be run
# if needed. Finally, we ensure binaries have the executable flag set because
# when copied in from outside they may not have the flag set, especially if
# they were uploaded as a GH actions artifact then downloaded again which
# causes file permissions to be lost.
# See: https://github.com/actions/upload-artifact#permission-loss
FROM ${MODE} AS source
RUN chmod a+x /tmp/out/bin/*


# -----------------------------------------------------------------------------
# Docker stage: final
# -----------------------------------------------------------------------------
# Create an image containing just the binaries, configs & scripts needed to run
# our app, and not the things needed to build it.
#
# The previous build stage from which binaries are copied is controlled by the
# MODE ARG (see above).
FROM ${BASE_IMG} AS final

# Copy binaries from the 'source' build stage into the image we are building
COPY --from=source /tmp/out/bin/* /usr/local/bin/

# Install required runtime dependencies
RUN apk add --no-cache libgcc tini

# Use Tini to ensure that our application responds to CTRL-C when run in the
# foreground without the Docker argument "--init" (which is actually another
# way of activating Tini, but cannot be enabled from inside the Docker image).
ENTRYPOINT ["/sbin/tini", "--", "dnst"]
8 changes: 8 additions & 0 deletions pkg/debian/postinst
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
#!/bin/sh -e

case "$1" in
configure)
# Create symbolic links
ln -s /usr/bin/dnst /usr/bin/ldns-nsec3-hash
;;
esac
8 changes: 8 additions & 0 deletions pkg/debian/prerm
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
#!/bin/sh -e

case "$1" in
upgrade|remove)
# Remove symbolic links
rm -f /usr/bin/ldns-nsec3-hash
;;
esac
23 changes: 23 additions & 0 deletions pkg/rpm/scriptlets.toml
Original file line number Diff line number Diff line change
@@ -0,0 +1,23 @@
post_install_script = '''
#!/bin/bash -e
FORCE=
if [ $1 -eq 2 ]; then
# Upgrade
FORCE=-f
fi
# Create symbolic links
ln -s ${FORCE} /usr/bin/dnst /usr/bin/ldns-nsec3-hash
'''

post_uninstall_script = '''
#!/bin/bash -e
#RPM_SYSTEMD_MACROS#
if [ $1 -eq 0 ] ; then
# Uninstallation
# Remove symbolic links
rm -f /usr/bin/ldns-nsec3-hash
fi
'''
36 changes: 36 additions & 0 deletions pkg/rules/docker-images-to-build.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,36 @@
---
# matrix field notes:
# platform: used by Docker to use the right architecture base image.
# the set of supported values can be seen at:
# https://go.dev/doc/install/source#environment
# from: https://github.com/docker-library/official-images#architectures-other-than-amd64
# from: https://docs.docker.com/desktop/multi-arch/
# one must also take any "normalization" into account, e.g. arm64v8 -> arm64, see:
# https://github.com/containerd/containerd/blob/v1.4.3/platforms/database.go#L83
# see also:
# https://stackoverflow.com/a/70889505
# shortname: used by us to tag the architecture specific "manifest" image.
# crosstarget: (optional) used to download the correct cross-compiled binary that was produced earlier by the
# 'cross' job above.
# mode: (optional) set to 'copy' for cross-compiled targets.
# cargo_args: (optional) can be used when testing, e.g. set to '--no-default-features' to speed up the Krill
# build.
include:
- platform: 'linux/amd64'
shortname: 'amd64'
mode: 'build'

- platform: 'linux/arm/v6'
shortname: 'armv6'
crosstarget: 'arm-unknown-linux-musleabihf'
mode: 'copy'

- platform: 'linux/arm/v7'
shortname: 'armv7'
crosstarget: 'armv7-unknown-linux-musleabihf'
mode: 'copy'

- platform: 'linux/arm64'
shortname: 'arm64'
crosstarget: 'aarch64-unknown-linux-musl'
mode: 'copy'
Loading
Loading