Review: sd-debian 0.1.0-1
Package Information
| Description | Software-defined Debian Software-defined Debian (sd-debian) is a next-generation declarative framework to deterministically define a Debian system with all its packages, configuration, and data. |
|---|---|
| Maintainer | sd-debian Maintainers <team+sd-debian@tracker.debian.org> |
| Changed By | Daniel Baumann <daniel@debian.org> |
| Sponsor | mail@daniel-baumann.ch |
| Distribution | sid |
| Architecture | all |
| VCS | git: https://git.sd.debian.net/packages/sd-debian (browse) |
| Tracker | https://tracker.debian.org/pkg/sd-debian |
| Uploaded | 6 days ago |
New Package Report
.changes
| Version | 0.1.0-1 |
|---|---|
| Changed-By | Daniel Baumann <daniel@debian.org> |
| Architecture | source all |
| Distribution | sid |
| Date | Sun, 01 Nov 2026 13:01:20 +0100 |
| Source | sd-debian |
Changelog
sd-debian (0.1.0-1) sid; urgency=medium . * Initial upload to sid.
.dsc
| Section | admin |
|---|---|
| Priority | optional |
| Component | main |
| Package-List | sd-debian-ansible deb admin optional arch=all |
debian/copyright
Format: https://www.debian.org/doc/packaging-manuals/copyright-format/1.0/ Upstream-Name: sd-debian Upstream-Contact: https://git.sd.debian.net/packages/sd-debian/issues Source: https://git.sd.debian.net/packages/sd-debian/tags Files: * Copyright: 2024-2026 Patrik Dufresne <patrik@ikus-soft.com> License: GPL-3+ Files: debian/* Copyright: 2024-2026 Daniel Baumann <daniel@debian.org> 2024-2026 Patrik Dufresne <patrik@ikus-soft.com> License: GPL-3+ License: GPL-3+ The full text of the GNU General Public License 3 can be found in the file /usr/share/common-licenses/GPL-3
DFSG Assistant LLM REVIEW 0 blocker, 1 important, 4 minor
This is an LLM based review using a Debian Inference based workflow. It was not written by a member of the DFSG team and has not been checked by one. It is not a decision on the package: it may be wrong, and it may have missed things.
Reviewed 6 days ago.
Report
DFSG NEW review for sd-debian version 0.1.0-1
Summary
- Licensing is DFSG-compliant and
debian/copyrightis accurate: Yes - Packaging is of good quality: No
- Issues: 0 blocker, 1 important, 4 minor
- debian/watch: version 5
- debian/copyright: machine-readable
- Scan before the review: nothing found
Licensing
debian/copyright is accurate and the licensing is DFSG-compliant. It is DEP-5 with the current Format URL, a Files: * stanza (2024-2026 Patrik Dufresne, GPL-3+) and a later Files: debian/* stanza (Daniel Baumann, Patrik Dufresne, GPL-3+), and GPL-3+ correctly names the GPL-3 text in /usr/share/common-licenses. Every source file carries Copyright (C) 2024-2026 Patrik Dufresne and SPDX-License-Identifier: GPL-3.0+, LICENSE is the GPL-3 text and pyproject.toml declares GPL-3.0-or-later; no other holder, licence, non-free term or vendored third-party code exists in the tree. Nothing in the package is a built or generated artifact without its source.
Packaging
The packaging is largely well done (compat 14, pybuild with the single-binary addon, generated manpage and bash completion, sysusers/tmpfiles integration, generated relationships correct), but as uploaded the binary is uninstallable: it Breaks every python3-configargparse in the archive while its Build-Depends asks for 1.9.0, which exists nowhere. A wrongly profiled <!nocheck> build-dependency also breaks any DEB_BUILD_OPTIONS=nocheck build, Enhances: sd-debian names no package that exists, prerm purges the configuration of every managed package on plain removal, and the .tmpfiles file creates a /usr/lib bundle directory that the program never reads.
Issues
important packaging 1. Relationships require python3-configargparse >= 1.9.0, which Debian does not have (only 1.7-4), so the package cannot be installed or built ◂
- Files:
debian/control:24,debian/control:51,src/sd_debian/config.py:35-41 - Basis: checked, in the package or with a reference tool
- Evidence: debian/control:24
python3-configargparse (>= 1.9.0) <!nocheck>,and debian/control:51python3-configargparse (<< 1.9.0),(Breaks). apt-cache show python3-configargparse:Version: 1.7-4, no other version, and not among the uploads in NEW. config.py:38 gates the feature onVersion("1.7.5")and falls back when it is older. - Problem: The Breaks forbids the only version in the archive and no newer one exists to upgrade to, while the package also depends on python3-configargparse (through
${python3:Depends}, and in any case its own Breaks): dpkg will refuse to configure it with 1.7-4 installed and apt can neither upgrade nor remove the dependency, so the binary is uninstallable in sid. The same versioned Build-Depends makes the build-dependency set unsatisfiable in a clean chroot, so a normal (non-nocheck) build cannot even start; the code itself only wants 1.7.5 and already degrades gracefully without it. - Fix: Depend on the version Debian has (drop the version, or use
>= 1.7), remove or correct the Breaks, and either adjust config.py's 1.7.5 feature gate or keep the documented fallback.
minor packaging 2. python3-configargparse is marked <!nocheck> although the build's completion and manpage hooks import it ◂
- Files:
debian/control:24,debian/rules:39-58,src/sd_debian/config.py:28 - Basis: checked, in the package or with a reference tool
- Evidence: debian/control:24
python3-configargparse (>= 1.9.0) <!nocheck>,; debian/rules:42shtab --shell=bash --error-unimportable sd_debian.config.get_parserand debian/rules:53argparse-manpage --module sd_debian.config; src/sd_debian/config.py:28import configargparse. At compat 14 dh skips hook targets only for dh_auto_test/dh_dwz/dh_strip (debhelper tool, search "nocheck"). - Problem: With DEB_BUILD_OPTIONS=nocheck the build-dependency is not installed, but
execute_before_dh_bash-completionandexecute_after_dh_installmanstill run and must import sd_debian.config, which imports configargparse at module level. Both hooks then fail (shtab's --error-unimportable turns the ImportError into a fatal error), so such a build fails; the annotation belongs on the test-only tools, not on a module the build itself imports. - Fix: Remove
<!nocheck>from python3-configargparse (python3-yaml too if configargparse's YAML parser needs it at import time), keeping it on the tools only the test/lint steps use.
minor packaging 3. Enhances: sd-debian names a binary package that does not exist ◂
- Files:
debian/control:54-55 - Basis: checked, in the package or with a reference tool
- Evidence: debian/control:54-55
Enhances:/sd-debian,; the .dsc hasBinary: sd-debian-ansible; apt-cache:There is no binary package named sd-debian in these lists, and nothing provides it, and it is not in NEW. - Problem: sd-debian is the source package name, not a binary; the relationship can never be satisfied and says nothing about the one binary this source builds (Policy 5.6.10/7.2). It reads as a leftover from an earlier package name.
- Fix: Drop the Enhances field, or point it at a real binary package whose functionality is enhanced.
minor packaging 4. prerm purges the configuration of every managed package when the tool is merely removed ◂
- Files:
debian/sd-debian-ansible.prerm:7,files/usr/share/sd-debian/ansible/entrypoint.yml,src/sd_debian/main.py:551-600 - Basis: checked, in the package or with a reference tool
- Evidence: debian/sd-debian-ansible.prerm:7
sd-debian run --remove ALL --purge ALL || true; config.py'srun --purgelist is passed aspurge_packages, and entrypoint.yml expandsALLto every installed package and runs the roles'postpurgetasks for it ("Running package purge roles"). - Problem: prerm is called with
removefor both removal and purging, sodpkg -r sd-debian-ansibledeletes the configuration of every package sd-debian manages; Policy 6.8 and 10.7.3 reserve removing configuration for the purge, and a user removing the tool does not expect their managed configuration to be purged. The call also runs ansible from inside dpkg's prerm (dpkg holds its lock; any role task using apt/dpkg will fail) and|| truehides the result. - Fix: Run only
--remove ALLin prerm's remove case and do the postpurge work from postrm's purge case (or gate it on dpkg's state), and stop masking the exit status.
minor packaging 5. tmpfiles creates /usr/lib/sd-debian/bundles, which the program never reads; the code uses /usr/share/sd-debian/bundles ◂
- Files:
debian/sd-debian-ansible.tmpfiles:4,debian/sd-debian-ansible.postrm:8,src/sd_debian/paths.py:66 - Basis: checked, in the package or with a reference tool
- Evidence: debian/sd-debian-ansible.tmpfiles:4
d /usr/lib/sd-debian/bundles 0750 root root(and postrm:8 rmdirs it), while src/sd_debian/paths.py:66SDD_DIR_BUNDLES = ... "usr/share/sd-debian/bundles"and the callback plugin mapsusr/share/sd-debian/bundles; FHS 4.1: "/usr is shareable, read-only data ... must not be written to". - Problem: The created directory is dead (nothing looks there, no package ships it), and creating it at boot/tmpfiles time writes into /usr, which the FHS forbids; the postrm also spends effort removing it. Either the path is a typo for /usr/share/sd-debian/bundles or the entry should not exist.
- Fix: Remove the /usr/lib line and the matching rmdir, or ship /usr/share/sd-debian/bundles as an empty directory in the package if bundles are meant to be dropped there by other packages.
Verified ◂
- debian/copyright read in full: DEP-5 with the exact current
Format:URL,Files: *(2024-2026 Patrik Dufresne, GPL-3+), laterFiles: debian/*(2024-2026 Daniel Baumann and Patrik Dufresne, GPL-3+), oneLicense: GPL-3+paragraph pointing at /usr/share/common-licenses/GPL-3;*covers every file and the debian/* stanza overrides it for debian/, so every file is matched. - Licence evidence across the whole tree: all 7 .py files and files/usr/share/sd-debian/ansible/entrypoint.yml carry
Copyright (C) 2024-2026 Patrik DufresneandSPDX-License-Identifier: GPL-3.0+; LICENSE is the GPL-3 text; pyproject.toml declaresGPL-3.0-or-later. No other holder, licence, non-commercial/no-modification wording or vendored third-party copy appears in any file (also checked ansible.cfg, plugin_filters.yml, files/etc/sd-debian/sd-debian.yml, files/usr/libexec/sd-debian/git-askpass/return-secret.sh, tox.ini, .ansible-lint, .git-changelog.toml, CHANGELOG.md, README.md). - The prescan listed no individual file: its author check found every holder it saw named in debian/copyright (Patrik Dufresne, Daniel Baumann). Daniel Baumann appears in pyproject.toml's
authorsand in the changelog's commit credits, but no file carries a copyright notice for him, soFiles: *naming Patrik Dufresne alone is not contradicted by any notice. - No generated binaries, minified files, PDFs, images or fonts in the tree. The bash completion and manpage are generated at build time from src/sd_debian/config.py by python3-shtab and python3-argparse-manpage (debian/rules:39-58), so nothing lacks its preferred form for modification.
- Checked the .dsc and both tarballs: the orig tarball holds the same upstream tree reviewed here (LICENSE, no LICENSE.txt, no extra files) and the debian tarball holds exactly the debian/ files reviewed, with no debian/patches (the empty .pc/ quilt record was ignored as instructed).
- debhelper 14.5 provides the referenced sequences (Sequence/single_binary.pm, Sequence/installsysusers.pm) and single-binary sets dh_auto_install's destdir to debian/sd-debian-ansible, which matches rules. dh_installsysusers adds
systemd | systemd-standalone-sysusers | systemd-sysusersto misc:Depends at compat 14 (read /usr/bin/dh_installsysusers), so no sysusers dependency is missing; theu!line is valid per sysusers.d(5). dh_installtmpfiles runs in the default sequence from compat 13 (debhelper tool), so the .tmpfiles file is installed. - dh-python's pybuild installs to /usr/lib/python3.13/dist-packages (DEFAULT_INSTALL_DIR in /usr/share/dh-python/dhpython/build/options.py; the versioned path is fixed later by dh_python3), so the versioned PYTHONPATH in both rules hooks is correct, as is the tests-removal path.
- Standards-Version 4.7.4 against Policy 4.7.4.1: current. debian/changelog is plausible: 0.1.0-1, sid, urgency medium, and Sun, 01 Nov 2026 is indeed a Sunday.
- apt-cache checks: ansible-core 2.22.0~beta2, opensysusers 0.7.5-1, systemd-standalone-sysusers 262.1-1, python3-shtab 1.12.1, python3-argparse-manpage 4.7, python3-flake8-copyright 0.2.4, black, isort and tox exist, so the remaining Breaks/Depends and Build-Depends can be satisfied; python3-configargparse is 1.7-4 (reported above).
- There is no debian/tests/ directory, so the package has no autopkgtest; that is not required by Policy and is not reported as an issue.
- Every pointer of
debian/copyrightto /usr/share/common-licenses names a file that is there (GPL-3).
Not confirmed ◂
-
pyproject.toml:12
license-files = ["LICENSE.txt"]matches no file (the tarball ships LICENSE). The setuptools 78.1.1 installed here only warns (setuptools/warnings.py raises only with SETUPTOOLS_ENFORCE_DEPRECATION), but its source says the match failure is meant to become an InvalidConfigError, and the archive's setuptools is 84.2.0, which could not be read on this system: whether the build fails on it is unconfirmed. -
Whether
tox -e lint(debian/rules:31) can install.[dev]at all withPIP_NO_INDEX=1: debian/rules:16 setsPIP_NO_BUILD_ISOLATION=0, which contradicts its own comment and leaves pip's build isolation on, so it may need to fetch setuptools>=77 with the index disabled. tox and pip are not installed on this system, so tox's actual behaviour could not be checked. -
The mode of files/usr/libexec/sd-debian/git-askpass/return-secret.sh could not be read; if it is not executable, using it as GIT_ASKPASS will fail at runtime.
-
uscan got no usable answer from the upstream site (unreachable, or refusing the request), so
debian/watchis untested:In watchfile debian/watch, reading webpage https://sd.debian.net/archive/packages/sd-debian failed: 403 Forbidden
Proposed changes ◂
None.
Uploader's response to the LLM review
- false positive (python3-configarparse 1.9.0 is in sid)
- fixed in git
- false positive (src:sd-debian-metapackages, also in NEW)
- false positive (that's the indendet behaviour)
- fixed in git
— Daniel Baumann (daniel), 6 days ago
Review Information
accepted — allocated to mechtilde 6 days ago, started 6 days ago, completed 6 days ago.