summaryrefslogtreecommitdiffstats
path: root/GETTING-STARTED-WITH-dh-debputy.md
diff options
context:
space:
mode:
Diffstat (limited to 'GETTING-STARTED-WITH-dh-debputy.md')
-rw-r--r--GETTING-STARTED-WITH-dh-debputy.md316
1 files changed, 316 insertions, 0 deletions
diff --git a/GETTING-STARTED-WITH-dh-debputy.md b/GETTING-STARTED-WITH-dh-debputy.md
new file mode 100644
index 0000000..5d5d253
--- /dev/null
+++ b/GETTING-STARTED-WITH-dh-debputy.md
@@ -0,0 +1,316 @@
+# Getting started with `dh-debputy`
+
+_This is [how-to guide] and is primarily aimed at getting a task done._
+
+<!-- To writers and reviewers: Check the documentation against https://documentation.divio.com/ -->
+
+This document will help you convert a Debian source package using the `dh` sequencer from debhelper to
+use `dh-debputy`. Prerequisites for this how-to guide:
+
+ * You have a Debian source package using the `dh` sequencer. Ideally a simple one as not all packages
+ can be converted at this time. Note that `debputy` does *not* interact well with most third-party
+ `dh` addons. You are recommended to start with source packages without third-party `dh` addons.
+ * It is strongly recommended that your package is bit-for-bit reproducible before starting the conversion
+ as that makes it easier to spot bugs introduced by the conversion! The output of `debputy` will *not*
+ be bit-for-bit reproducible with `debhelper` in all cases. However, the differences should be easy to
+ review with `diffoscope` if the package was already bit-for-bit reproducible.
+ - Note that `debputy` does not use `strip-nondeterminism`. The bit-for-bit reproducible property should
+ ideally not rely on `strip-nondeterminism` for now.
+
+Note that during the conversion (particularly Step 1 and Step 2), you may find that `debputy` cannot
+support the requirements for your package for now. Feel free to file an issue for what is holding you
+back in the [debputy issue tracker].
+
+Prerequisites
+-------------
+
+This guide assumes familiarity with Debian packaging in general. Notably, you should understand
+the different between a (Debian) source package and a (Debian) binary package (e.g., `.deb`) plus
+how these concepts relates to `debian/control` (the source control file).
+
+Additionally, since this is about `debputy` integration with debhelper, the reader is expected to
+be familiar with `debhelper` (notably the `dh` style `debian/rules`).
+
+## Step 1: Have `debputy` convert relevant debhelper files
+
+The `debputy` integration with debhelper removes (replaces) some debhelper tools, but does **not**
+read their relevant config files. These should instead be converted in to the new format.
+
+You can have `debputy` convert these for you by using the following command:
+
+ # Dry-run conversion, creates `debian/debputy-manifest.new` if anything is migrated and prints a summary
+ # of what is done. Remove the --no-act when you are ready to commit the conversion.
+ $ debputy migrate-from-dh --no-act
+
+If relevant, `debputy` may inform you that:
+
+ 1) the package is using an unsupported feature. Unless that functionality can easily be removed (e.g., it is now
+ obsolete) or easily replaced, then you probably do not want to convert the package to `debputy` at this time.
+ * One common source of unsupported features are dh hook targets (such as override targets), which will be covered
+ in slightly more detail in the next section. If `debputy` detected any hook targets, it is probably worth it to
+ check if these can be migrated before continuing.
+ * It is worth noting that the migration tool will update an existing manifest when re-run. You can safely "jump"
+ around in the order of the steps, when you try to migrate, if that better suits you.
+ 2) the migration would trigger a conflict. This can occur for two reasons:
+ * The debhelper configuration has the conflict (example [#934499]), where debhelper is being lenient and ignores
+ the problem. In this case, you need to resolve the conflict in the debhelper config and re-run `debputy`.
+ * The package has a manifest already with a similar (but not identical) definition of what the migration would
+ generate. In this case, you need to reconcile the definitions manually (and removing one of them). After that
+ you can re-run `debputy`.
+
+
+As an example, if you had a `debian/foo.links` (with `foo` being defined in `debian/control`) containing the following:
+
+ usr/share/foo/my-first-symlink usr/share/bar/symlink-target
+ usr/lib/{{DEB_HOST_MULTIARCH}}/my-second-symlink usr/lib/{{DEB_HOST_MULTIARCH}}/baz/symlink-target
+
+The `debputy migrate-from-dh` tool would generate a manifest looking something like this:
+
+ manifest-version: "0.1"
+ packages:
+ foo:
+ transformations:
+ - create-symlink:
+ path: usr/share/foo/my-first-symlink
+ target: /usr/share/bar/symlink-target
+ - create-symlink:
+ path: usr/lib/{{DEB_HOST_MULTIARCH}}/my-second-symlink
+ target: /usr/lib/{{DEB_HOST_MULTIARCH}}/baz/symlink-target
+
+## Step 2: Migrate override/hook-targets in debian/rules
+
+Once you activate the `debputy` debhelper integration (see Step 3), the following debhelper tools will be
+removed from the `dh` sequence.
+
+ * `dh_install`
+ * `dh_installdocs`
+ * `dh_installchangelogs`
+ * `dh_installexamples`
+ * `dh_installman`
+ * `dh_installcatalogs` **(!)**
+ * `dh_installcron`
+ * `dh_installifupdown`
+ * `dh_installdebconf` **(!)**
+ * `dh_installemacsen` **(!)**
+ * `dh_installinfo`
+ * `dh_installinit` **(!)**
+ * `dh_installsysusers`
+ * `dh_installtmpfiles`
+ * `dh_installsystemd` **(!)**
+ * `dh_installsystemduser` **(!)**
+ * `dh_installmenu` **(!)**
+ * `dh_installmime`
+ * `dh_installmodules`
+ * `dh_installlogcheck`
+ * `dh_installlogrotate`
+ * `dh_installpam`
+ * `dh_installppp`
+ * `dh_installudev` **(!)**
+ * `dh_installgsettings`
+ * `dh_installinitramfs`
+ * `dh_installalternatives`
+ * `dh_bugfiles`
+ * `dh_ucf` **(!)**
+ * `dh_lintian`
+ * `dh_icons`
+ * `dh_perl`
+ * `dh_usrlocal` **(!)**
+ * `dh_links`
+ * `dh_installwm` **(!)**
+ * `dh_installxfonts`
+ * `dh_strip_nondeterminism`
+ * `dh_compress`
+ * `dh_fixperms`
+ * `dh_dwz`
+ * `dh_strip`
+ * `dh_makeshlibs`
+ * `dh_shlibdeps`
+ * `dh_missing`
+ * `dh_installdeb`
+ * `dh_gencontrol`
+ * `dh_md5sums`
+ * `dh_builddeb`
+
+Have a look at `debian/rules` and migrate any overrides you have for them to `debputy` features or other
+hook targets. See also the subsections below for concrete advice on how to deal with override or hook targets
+for some of these tools. However, since `debhelper` hooks are arbitrary code execution hooks, there will be
+many cases that the guide will not be able to cover or where `debputy` may not have the feature to support your
+hook target.
+
+While you could manually force these tools to be run via a hook target, they are very likely to feature
+interact with `debputy`. Either causing `debputy` to replace their output completely or by having the tool
+overwrite what `debputy` did (depending on the exact order). If you find, you *really* need to run one of these
+tools, because `debputy` is not supporting a particular feature they have, then you are probably better off waiting
+with migrating the package in question.
+
+Tools marked with **(!)** have no debputy support at all. If you rely on these tools, migration is unlikely
+to succeed. Other tools will have some form of support (often at least a commonly used flow/feature set).
+Where possible, `debputy migrate-from-dh --no-act` will detect these completely unsupported tools via existence
+of their config files or indirectly debhelper hook targets for these tools. However, some tools may only be
+detected late into the build (which is the case with `dh_usrlocal`).
+
+### Review and migrate any installation code from `dh_install`, `dh_installdocs`, etc. (if any)
+
+All code in `debian/rules` that involves copying or moving files into packages or around in packages must
+be moved to the manifest's `installations` section. The migration tool will attempt to auto-migrate
+any rules from `debian/install` (etc.). However, be aware of:
+
+ 1) The migration tool assumes none of install rules overlap. Most packages do not have overlapping
+ install rules as it tends to lead to file conflicts. If the install rules overlap, `debputy` will
+ detect it at runtime and stop with an error. In that case, you will have to tweak the migrated rules
+ manually.
+ 2) Any overrule target that copies or moves files around in packages must be moved to `installations`
+ (per source) or `transformations` (per package) depending on the case.
+ - For source packages installing content via `debian/tmp`, you can use `install` to rename paths as
+ you install them and `discard` (under `installations`) to ignore paths that should not be installed.
+ - For source packages installing content via `debian/<pkg>`, then everything in there is "auto-installed".
+ If you need to tweak that content, you can use `remove` or `move` transformations (under `transformations`)
+ for manipulation the content.
+
+Note that the migrator "blindly" appends new rules to the bottom of `installations` if you have any existing
+rules (per "none of the install rules overlap"-logic mentioned above). If you cannot convert all debhelper config
+files in one go, or you manually created some installation rules before running the migrator, you may need to
+manually re-order the generated installation rules to avoid conflicts due to inadequate ordering. You probably
+want to do so any way for readability/grouping purposes.
+
+
+#### Double-check the `language` settings on all `install-man` rules in `installations`
+
+The `dh_installman` tool auto-detects the language for manpages via two different methods:
+
+ 1) By path name (Does the installation path look like `man/<language>/man<section>/...`?)
+ 2) By basename (Does the basename look like `foo.<language>.<section>`?)
+
+Both methods are used in order with first match being the method of choice. Unfortunately, the second
+method is prune to false-positives. Does `foo.pl.1` mean a Polish translation of `foo.1` or is it the
+manpage for a Perl script called `foo.pl` (similar happens for languages/file extensions).
+
+To avoid this issue, `debputy` uses 1) by default and only that. Option 2) can be chosen by setting
+`language: derive-from-basename` on the concrete install rule. The problem is that the migration tool
+has to guess, and it is hard to tell if rules like `man/*.1` would need option 2) - especially when the
+migration tool does not attempt to resolve the glob (which it currently does not).
+
+Therefore, take a critical look at the generated `install-man` rules and the generated `language` property
+(or lack thereof).
+
+
+### Convert your overrides or excludes for `dh_fixperms` (if any)
+
+The `debputy` tool will normalize permissions like `dh_fixperms` during package build. If you have
+any special requirements that `dh_fixperms` did not solve for you, you will have to tell `debputy`
+about them.
+
+If you had something like:
+
+ override_dh_fixperms:
+ dh_fixperms -X bin/sudo
+
+and the goal was to have `dh_fixperms` not touch the mode but the ownership (root:root) was fine, you
+would have the manifest `debian/debputy.manifest`:
+
+ manifest-version: "0.1"
+ packages:
+ foo:
+ transformations:
+ - path-metadata:
+ path: usr/bin/sudo
+ mode: "04755"
+
+Note you have to spell out the desired mode for this file.
+
+On the other hand, if your `debian/rules` had something like:
+
+ execute_after_dh_fixperms:
+ chown www-data:www-data debian/foo/var/lib/something-owned-by-www-data
+
+Then the manifest would look something like:
+
+ manifest-version: "0.1"
+ packages:
+ foo:
+ transformations:
+ - path-metadata:
+ path: var/lib/something-owned-by-www-data
+ owner: www-data
+ group: www-data
+
+This can be combined with an explicit `mode: "02755"` if you also need a non-default mode.
+
+The paths provided here support substitution variables (`usr/lib/{{DEB_HOST_MULTIARCH}}/...`) and
+some _limited_ glob support (`usr/bin/sudo*`).
+
+_Remember to merge your manifest with previous steps rather than replacing it!_ Note that
+`debputy migrate-from-dh` will merge its changes into existing manifests and can safely be re-run
+after adding/writing this base manifest.
+
+### Convert your overrides for `dh_gencontrol` (if any)
+
+If the package uses an override to choose a custom version for a binary package, then it is possible in `debputy`
+by using the `binary-version` key under the package. Here is an example to force the package `foo` to have
+epoch `1`:
+
+ manifest-version: "0.1"
+ packages:
+ foo:
+ # The foo package needs a different epoch because we took it over from a different
+ # source package with higher epoch version
+ binary-version: '1:{{DEB_VERSION_UPSTREAM_REVISION}}'
+
+Useful if the source took over a binary package from a different source and that binary had a higher
+epoch version.
+
+Note that only limited manipulation of the version is supported, since your options are generally
+limited to expanding one of the following version related variables:
+
+ * `DEB_VERSION` - same definition as the one from `/usr/share/dpkg/pkg-info.mk` (from `dpkg`)
+ * `DEB_VERSION_EPOCH_UPSTREAM` - ditto
+ * `DEB_VERSION_UPSTREAM_REVISION` - ditto
+ * `DEB_VERSION_UPSTREAM` - ditto
+
+If the override is needed for dynamic substitution variables or binary versions that cannot be done with
+the above substitutions, then it might be better to hold off on the conversion.
+
+_Remember to merge your manifest with previous steps rather than replacing it!_ Note that
+`debputy migrate-from-dh` will merge its changes into existing manifests and can safely be re-run
+after adding/writing this base manifest.
+
+## Step 3: Adding the `dh-sequence-zz-debputy` sequence to Build-Depends
+
+The recommended way to do so is to add `dh-sequence-zz-debputy` to the `Build-Depends:` field.
+
+The `zz-` in `zz-debputy` is there to ensure the `debputy` add-on is loaded last by debhelper for
+the rare case there any other debhelper addons still active as the `debputy` sequence does not really
+play well with other `dh` addons. When there are other add-ons, it is generally better for `debputy` to
+be loaded last (as add-on order matters per [#885580]).
+
+## Step 4: Replace third-party dh add-ons to debputy plugins
+
+Packages using third-party `dh` add-ons may need to replace these with `debputy` plugins assuming the
+add-on has a `debputy` plugin to replace it in the first place. To request a `debputy` plugin, you
+will have to add `debputy-plugin-X` into your `Build-Depends`, where `X` is the name of the plugin.
+
+Note that `debputy` does not support the same features as `debhelper` at the moment for conditional
+plugin loading. Therefore, the plugins must be in `Build-Depends`.
+
+## Step 5: Verify the build
+
+At this stage, if there are no errors in your previous steps, you should be able to build your
+changed package with `debputy`. We recommend that you take time to verify this. For some packages,
+there was no conversion to do in the previous steps, and you would not even need a manifest at all
+in this case. However, we still recommend that you verify the build is successful here and now.
+
+The `debputy` supports bit-for-bit reproducibility in its output. However, the output is not bit-for-bit
+reproducible with `debhelper`. You are recommended to use `diffoscope` to compare the `debhelper`
+built-version with the `debputy` built version to confirm that all the changes are benign.
+
+However, `debputy` is bit-for-bit reproducible in its output with `(fakeroot) dpkg-deb -b`. Should you
+spot a difference where `debputy` does not produce bit-for-bit identical results with `dpkg-deb` (tar
+format, file ordering, etc.), then please file a bug against `debputy` with a reproducing test case.
+
+Once you have verified your built, the conversion is done. :) At this point, you can consider
+looking at other features that `debputy` supports that might be useful to you.
+
+[how-to guide]: https://documentation.divio.com/how-to-guides/
+[#885580]: https://bugs.debian.org/885580
+[#934499]: https://bugs.debian.org/934499
+[debputy issue tracker]: https://salsa.debian.org/debian/debputy/-/issues