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

dnsdist: Install binary, man page and systemd unit files with meson #15138

Merged
merged 9 commits into from
Feb 13, 2025
24 changes: 18 additions & 6 deletions docs/generate-man-pages.py
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,6 @@
import argparse
import glob
import itertools
import os
import subprocess
import sys
import venv
Expand All @@ -14,8 +13,8 @@ def main():
"""Start the script."""
args = create_argument_parser()

source_root = Path(os.environ["MESON_SOURCE_ROOT"])
build_root = Path(os.environ["MESON_BUILD_ROOT"])
source_root = args.source_root
build_root = args.build_root

# Create the venv.
venv_directory = build_root.joinpath(args.venv_name)
Expand All @@ -30,8 +29,8 @@ def main():
# Install some stuff into the venv.
requirements_file = source_root.joinpath(args.requirements_file)
pip = venv_directory.joinpath("bin").joinpath("pip")
subprocess.run([pip, "install", "-U", "pip", "setuptools", "wheel"])
subprocess.run([pip, "install", "-r", requirements_file])
subprocess.run([pip, "install", "-U", "pip", "setuptools", "wheel"], check=True)
subprocess.run([pip, "install", "-r", requirements_file], check=True)

# Run sphinx to generate the man-pages.
source_directory = source_root.joinpath(args.source_directory)
Expand All @@ -47,7 +46,8 @@ def main():
source_directory,
target_directory,
]
+ files
+ files,
check=True
)


Expand All @@ -56,6 +56,18 @@ def create_argument_parser():
parser = argparse.ArgumentParser(
description="Create a virtualenv from a requirements file"
)
parser.add_argument(
"--build-root",
type=Path,
required=True,
help="Build root",
)
parser.add_argument(
"--source-root",
type=Path,
required=True,
help="Source root",
)
parser.add_argument(
"--venv-name",
type=str,
Expand Down
34 changes: 24 additions & 10 deletions meson.build
Original file line number Diff line number Diff line change
Expand Up @@ -1011,16 +1011,30 @@ summary('Path', python.full_path(), section: 'Manual Pages')
summary('Version', python.version(), section: 'Manual Pages')

if python.found()
run_target(
'man-pages',
command: [
python,
product_source_dir / docs_dir / 'generate-man-pages.py',
'--venv-name', 'venv-auth-man-pages',
'--requirements-file', docs_dir / 'requirements.txt',
'--source-directory', docs_dir,
'--target-directory', 'auth-man-pages',
] + man_pages,
generated_man_pages = []
foreach tool, info: tools
if 'manpages' in info
foreach man_page: info['manpages']
generated_man_pages += man_page
endforeach
endif
endforeach
custom_target(
'man-pages',
input: man_pages,
output: generated_man_pages,
install: true,
install_dir: join_paths(get_option('mandir'), 'man1'),
command: [
python,
product_source_dir / docs_dir / 'generate-man-pages.py',
'--build-root', '@BUILD_ROOT@',
'--source-root', '@SOURCE_ROOT@',
'--venv-name', 'venv-auth-man-pages',
'--requirements-file', docs_dir / 'requirements.txt',
'--source-directory', docs_dir,
'--target-directory', '@BUILD_ROOT@',
] + man_pages,
)
endif

Expand Down
61 changes: 61 additions & 0 deletions pdns/dnsdistdist/dnsdist.service.meson.in
Original file line number Diff line number Diff line change
@@ -0,0 +1,61 @@
[Unit]
Description=@Description@
Documentation=man:dnsdist(1)
Documentation=https://dnsdist.org
Wants=network-online.target
After=network-online.target time-sync.target

[Service]
ExecStartPre=@BinDir@/dnsdist --check-config
# Note: when editing the ExecStart command, keep --supervised and --disable-syslog
ExecStart=@BinDir@/dnsdist --supervised --disable-syslog
User=@ServiceUser@
Group=@ServiceGroup@
SyslogIdentifier=dnsdist
Type=notify
Restart=on-failure
RestartSec=2
TimeoutStopSec=5
StartLimitInterval=0

# Tuning
TasksMax=8192
LimitNOFILE=16384
# Note: increasing the amount of lockable memory is required to use eBPF support
# LimitMEMLOCK=infinity

# Sandboxing
# Note: adding CAP_SYS_ADMIN is required to use eBPF support,
# and CAP_NET_RAW to be able to set the source interface to contact a backend
# If an AppArmor policy is in use, it might have to be updated to allow dnsdist to keep the
# capability: adding a 'capability sys_admin,' line to the policy is usually enough.
CapabilityBoundingSet=CAP_NET_BIND_SERVICE
AmbientCapabilities=CAP_NET_BIND_SERVICE
@LockPersonality@
NoNewPrivileges=true
@PrivateDevices@
@PrivateTmp@
# Setting PrivateUsers=true prevents us from opening our sockets
@ProtectClock@
@ProtectControlGroups@
@ProtectHome@
@ProtectHostname@
@ProtectKernelLogs@
@ProtectKernelModules@
@ProtectKernelTunables@
@ProtectSystem@
@RestrictAddressFamilies@
@RestrictNamespaces@
@RestrictRealtime@
@RestrictSUIDSGID@
@SystemCallArchitectures@
@SystemCallFilter@
@ProtectProc@
@PrivateIPC@
@RemoveIPC@
DevicePolicy=closed
# Not enabled by default because it does not play well with LuaJIT
@MemoryDenyWriteExecute@

[Install]
WantedBy=multi-user.target
1 change: 1 addition & 0 deletions pdns/dnsdistdist/docs/generate-man-pages.py
137 changes: 126 additions & 11 deletions pdns/dnsdistdist/meson.build
Original file line number Diff line number Diff line change
Expand Up @@ -416,6 +416,7 @@ tools = {
dep_json11,
dep_systemd,
],
'install': true,
},
}

Expand Down Expand Up @@ -523,6 +524,7 @@ foreach tool, info: tools
files_extra = 'files-extra' in info ? info['files-extra'] : []
deps_extra = 'deps-extra' in info ? info['deps-extra'] : []
link_args = 'link-args' in info ? info['link-args'] : []
install = 'install' in info ? info['install'] : false

set_variable(
var_name,
Expand All @@ -537,6 +539,7 @@ foreach tool, info: tools
libdnsdist_common,
deps_extra,
],
install: install,
)
)

Expand All @@ -559,16 +562,128 @@ summary('Python', python.found(), bool_yn: true, section: 'Manual Pages')
summary('Path', python.full_path(), section: 'Manual Pages')
summary('Version', python.version(), section: 'Manual Pages')

if python.found()
run_target(
'man-pages',
command: [
python,
product_source_dir / docs_dir / 'generate-man-pages.py',
'--venv-name', 'venv-dnsdist-man-pages',
'--requirements-file', docs_dir / 'requirements.txt',
'--source-directory', docs_dir,
'--target-directory', 'dnsdist-man-pages',
] + man_pages,
if get_option('man-pages') and python.found()
generated_man_pages = []
foreach tool, info: tools
if 'manpages' in info
foreach man_page: info['manpages']
generated_man_pages += man_page
endforeach
endif
endforeach
custom_target(
'man-pages',
input: man_pages,
output: generated_man_pages,
install: true,
install_dir: join_paths(get_option('mandir'), 'man1'),
command: [
python,
product_source_dir / docs_dir / 'generate-man-pages.py',
'--build-root', '@BUILD_ROOT@',
'--source-root', '@SOURCE_ROOT@',
'--venv-name', 'venv-dnsdist-man-pages',
'--requirements-file', docs_dir / 'requirements.txt',
'--source-directory', docs_dir,
'--target-directory', '@BUILD_ROOT@',
] + man_pages,
)
endif

if dep_systemd_prog.found()

systemd_system_unit_dir = dep_systemd_prog.get_variable(
'systemdsystemunitdir',
)

systemd_service_conf = configuration_data()
systemd_service_conf.set('Description', 'DNS Loadbalancer')
systemd_service_conf.set('BinDir', get_option('prefix') / get_option('bindir'))
systemd_service_user = get_option('systemd-service-user')
systemd_service_group = get_option('systemd-service-group')
systemd_service_conf.set('ServiceUser', systemd_service_user)
systemd_service_conf.set('ServiceGroup', systemd_service_group)
summary('Service User', systemd_service_user, section: 'Systemd')
summary('Service Group', systemd_service_group, section: 'Systemd')

systemd_service_conf.set(
'ProtectSystem', have_systemd_protect_system ? 'ProtectSystem=full' : '',
)
systemd_service_conf.set(
'SystemCallArchitectures',
have_systemd_system_call_architectures ? 'SystemCallArchitectures=native' : '',
)
systemd_system_call_filter = '~ @clock @debug @module @mount @raw-io @reboot @swap @cpu-emulation @obsolete'
systemd_service_conf.set(
'SystemCallFilter',
have_systemd_system_call_filter ? 'SystemCallFilter=' + systemd_system_call_filter : '',
)
systemd_service_conf.set(
'ProtectProc',
have_systemd_protect_proc ? 'ProtectProc=invisible' : '',
)

systemd_features = {
'LockPersonality': have_systemd_lock_personality,
'PrivateDevices': have_systemd_private_devices,
'PrivateTmp': have_systemd_private_tmp,
'PrivateUsers': false, # Setting it to true prevents us from opening our sockets.
'ProtectClock': have_systemd_protect_clock,
'ProtectControlGroups': have_systemd_protect_control_groups,
'ProtectHome': have_systemd_protect_home,
'ProtectHostname': have_systemd_protect_hostname,
'ProtectKernelLogs': have_systemd_protect_kernel_logs,
'ProtectKernelModules': have_systemd_protect_kernel_modules,
'ProtectKernelTunables': have_systemd_protect_kernel_tunables,
'RestrictNamespaces': have_systemd_restrict_namespaces,
'RestrictRealtime': have_systemd_restrict_realtime,
'RestrictSUIDSGID': have_systemd_restrict_suidsgid,
'PrivateIPC': have_systemd_private_ipc,
'RemoveIPC': have_systemd_remove_ipc,
}

foreach feature, enable_it: systemd_features
systemd_service_conf.set(feature, enable_it ? feature + '=true': '')
endforeach

# Disabled, it breaks LuaJIT.
systemd_service_conf.set(
'MemoryDenyWriteExecute',
have_systemd_memory_deny_write_execute ? 'MemoryDenyWriteExecute=false' : '',
)
systemd_service_conf.set(
'RestrictAddressFamilies',
have_systemd_restrict_address_families ? 'RestrictAddressFamilies=AF_UNIX AF_INET AF_INET6' : '',
)

dnsdist_service_conf_general = configuration_data()
dnsdist_service_conf_general.set('Description', 'DNS Loadbalancer')
dnsdist_service_conf_general.merge_from(systemd_service_conf)
dnsdist_service_conf_general.set('SyslogIdentifier', 'dnsdist')

configure_file(
input: 'dnsdist.service.meson.in',
output: 'dnsdist.service',
configuration: dnsdist_service_conf_general,
install: true,
install_dir: systemd_system_unit_dir,
)

dnsdist_service_conf_instance = configuration_data()
dnsdist_service_conf_instance.merge_from(systemd_service_conf)
dnsdist_service_conf_instance.set('Description', 'DNS Loadbalancer %i')
dnsdist_service_conf_instance.set('SyslogIdentifier', 'dnsdist-%i')

configure_file(
input: 'dnsdist.service.meson.in',
output: '[email protected]',
configuration: dnsdist_service_conf_instance,
install: true,
install_dir: systemd_system_unit_dir,
)
endif

install_data(
'dnsdist.conf-dist',
install_dir : get_option('sysconfdir')
)
1 change: 1 addition & 0 deletions pdns/dnsdistdist/meson_options.txt
Original file line number Diff line number Diff line change
Expand Up @@ -37,3 +37,4 @@ option('fuzz-targets', type: 'boolean', value: false, description: 'Enable fuzzi
option('ebpf', type: 'feature', value: 'disabled', description: 'Enable eBPF support')
option('fuzzer_ldflags', type: 'string', value: '', description: 'Linker flags used for the fuzzing targets (a path to the libFuzzer static library, for example)')
option('yaml', type: 'feature', value: 'disabled', description: 'Enable YAML configuration')
option('man-pages', type: 'boolean', value: true, description: 'Generate man pages')
34 changes: 24 additions & 10 deletions pdns/recursordist/meson.build
Original file line number Diff line number Diff line change
Expand Up @@ -576,16 +576,30 @@ summary('Path', python.full_path(), section: 'Manual Pages')
summary('Version', python.version(), section: 'Manual Pages')

if python.found()
run_target(
'man-pages',
command: [
python,
product_source_dir / docs_dir / 'generate-man-pages.py',
'--venv-name', 'venv-rec-man-pages',
'--requirements-file', docs_dir / 'requirements.txt',
'--source-directory', docs_dir,
'--target-directory', 'rec-man-pages',
] + man_pages,
generated_man_pages = []
foreach tool, info: tools
if 'manpages' in info
foreach man_page: info['manpages']
generated_man_pages += man_page
endforeach
endif
endforeach
custom_target(
'man-pages',
input: man_pages,
output: generated_man_pages,
install: true,
install_dir: join_paths(get_option('mandir'), 'man1'),
command: [
python,
product_source_dir / docs_dir / 'generate-man-pages.py',
'--build-root', '@BUILD_ROOT@',
'--source-root', '@SOURCE_ROOT@',
'--venv-name', 'venv-rec-man-pages',
'--requirements-file', docs_dir / 'requirements.txt',
'--source-directory', docs_dir,
'--target-directory', '@BUILD_ROOT@',
] + man_pages,
)
endif

Expand Down