mirror of
				https://github.com/juanfont/headscale.git
				synced 2025-10-28 10:51:44 +01:00 
			
		
		
		
	Refactor Debian/Ubuntu package
Move files for packaging outside the docs directory into its own packaging directory. Replace the existing postinstall and postremove scripts with Debian maintainerscripts to behave more like a typical Debian package: * Start and enable the headscale systemd service by default * Does not print informational messages * No longer stop and disable the service on updates This package also performs migrations for all changes done in previous package versions on upgrade: * Set login shell to /usr/sbin/nologin * Set home directory to /var/lib/headscale * Migrate to system UID/GID The package is lintian-clean with a few exceptions that are documented as excludes and it passes puipars (both tested on Debian 12). The following scenarious were tested on Ubuntu 22.04, Ubuntu 24.04, Debian 11, Debian 12: * Install * Install same version again * Install -> Remove -> Install * Install -> Purge -> Install * Purge * Update from 0.22.0 * Update from 0.26.0 See: #2278 See: #2133 Fixes: #2311
This commit is contained in:
		
							parent
							
								
									d2879b2b36
								
							
						
					
					
						commit
						4a941a2cb4
					
				| @ -64,8 +64,15 @@ nfpms: | ||||
|     vendor: headscale | ||||
|     maintainer: Kristoffer Dalby <kristoffer@dalby.cc> | ||||
|     homepage: https://github.com/juanfont/headscale | ||||
|     license: BSD | ||||
|     description: |- | ||||
|       Open source implementation of the Tailscale control server. | ||||
|       Headscale aims to implement a self-hosted, open source alternative to the | ||||
|       Tailscale control server. Headscale's goal is to provide self-hosters and | ||||
|       hobbyists with an open-source server they can use for their projects and | ||||
|       labs. It implements a narrow scope, a single Tailscale network (tailnet), | ||||
|       suitable for a personal use, or a small open-source organisation. | ||||
|     bindir: /usr/bin | ||||
|     section: net | ||||
|     formats: | ||||
|       - deb | ||||
|     contents: | ||||
| @ -74,15 +81,21 @@ nfpms: | ||||
|         type: config|noreplace | ||||
|         file_info: | ||||
|           mode: 0644 | ||||
|       - src: ./docs/packaging/headscale.systemd.service | ||||
|       - src: ./packaging/systemd/headscale.service | ||||
|         dst: /usr/lib/systemd/system/headscale.service | ||||
|       - dst: /var/lib/headscale | ||||
|         type: dir | ||||
|       - dst: /var/run/headscale | ||||
|         type: dir | ||||
|       - src: LICENSE | ||||
|         dst: /usr/share/doc/headscale/copyright | ||||
|     scripts: | ||||
|       postinstall: ./docs/packaging/postinstall.sh | ||||
|       postremove: ./docs/packaging/postremove.sh | ||||
|       postinstall: ./packaging/deb/postinst | ||||
|       postremove: ./packaging/deb/postrm | ||||
|       preremove: ./packaging/deb/prerm | ||||
|     deb: | ||||
|       lintian_overrides: | ||||
|         - no-changelog  # Our CHANGELOG.md uses a different formatting | ||||
|         - no-manual-page | ||||
|         - statically-linked-binary | ||||
| 
 | ||||
| kos: | ||||
|   - id: ghcr | ||||
|  | ||||
| @ -1,5 +0,0 @@ | ||||
| # Packaging | ||||
| 
 | ||||
| We use [nFPM](https://nfpm.goreleaser.com/) for making `.deb`, `.rpm` and `.apk`. | ||||
| 
 | ||||
| This folder contains files we need to package with these releases. | ||||
| @ -1,88 +0,0 @@ | ||||
| #!/bin/sh | ||||
| # Determine OS platform | ||||
| # shellcheck source=/dev/null | ||||
| . /etc/os-release | ||||
| 
 | ||||
| HEADSCALE_EXE="/usr/bin/headscale" | ||||
| BSD_HIER="" | ||||
| HEADSCALE_RUN_DIR="/var/run/headscale" | ||||
| HEADSCALE_HOME_DIR="/var/lib/headscale" | ||||
| HEADSCALE_USER="headscale" | ||||
| HEADSCALE_GROUP="headscale" | ||||
| HEADSCALE_SHELL="/usr/sbin/nologin" | ||||
| 
 | ||||
| ensure_sudo() { | ||||
| 	if [ "$(id -u)" = "0" ]; then | ||||
| 		echo "Sudo permissions detected" | ||||
| 	else | ||||
| 		echo "No sudo permission detected, please run as sudo" | ||||
| 		exit 1 | ||||
| 	fi | ||||
| } | ||||
| 
 | ||||
| ensure_headscale_path() { | ||||
| 	if [ ! -f "$HEADSCALE_EXE" ]; then | ||||
| 		echo "headscale not in default path, exiting..." | ||||
| 		exit 1 | ||||
| 	fi | ||||
| 
 | ||||
| 	printf "Found headscale %s\n" "$HEADSCALE_EXE" | ||||
| } | ||||
| 
 | ||||
| create_headscale_user() { | ||||
| 	printf "PostInstall: Adding headscale user %s\n" "$HEADSCALE_USER" | ||||
| 	useradd -r -s "$HEADSCALE_SHELL" -d "$HEADSCALE_HOME_DIR" -c "headscale default user" "$HEADSCALE_USER" | ||||
| } | ||||
| 
 | ||||
| create_headscale_group() { | ||||
| 	if command -V systemctl >/dev/null 2>&1; then | ||||
| 		printf "PostInstall: Adding headscale group %s\n" "$HEADSCALE_GROUP" | ||||
| 		groupadd -r "$HEADSCALE_GROUP" | ||||
| 
 | ||||
| 		printf "PostInstall: Adding headscale user %s to group %s\n" "$HEADSCALE_USER" "$HEADSCALE_GROUP" | ||||
| 		usermod -a -G "$HEADSCALE_GROUP" "$HEADSCALE_USER" | ||||
| 	fi | ||||
| 
 | ||||
| 	if [ "$ID" = "alpine" ]; then | ||||
| 		printf "PostInstall: Adding headscale group %s\n" "$HEADSCALE_GROUP" | ||||
| 		addgroup -S "$HEADSCALE_GROUP" | ||||
| 
 | ||||
| 		printf "PostInstall: Adding headscale user %s to group %s\n" "$HEADSCALE_USER" "$HEADSCALE_GROUP" | ||||
| 		addgroup "$HEADSCALE_USER" "$HEADSCALE_GROUP" | ||||
| 	fi | ||||
| } | ||||
| 
 | ||||
| create_run_dir() { | ||||
| 	printf "PostInstall: Creating headscale run directory \n" | ||||
| 	mkdir -p "$HEADSCALE_RUN_DIR" | ||||
| 
 | ||||
| 	printf "PostInstall: Modifying group ownership of headscale run directory \n" | ||||
| 	chown "$HEADSCALE_USER":"$HEADSCALE_GROUP" "$HEADSCALE_RUN_DIR" | ||||
| } | ||||
| 
 | ||||
| summary() { | ||||
| 	echo "----------------------------------------------------------------------" | ||||
| 	echo " headscale package has been successfully installed." | ||||
| 	echo "" | ||||
| 	echo " Please follow the next steps to start the software:" | ||||
| 	echo "" | ||||
| 	echo "    sudo systemctl enable headscale" | ||||
| 	echo "    sudo systemctl start headscale" | ||||
| 	echo "" | ||||
| 	echo " Configuration settings can be adjusted here:" | ||||
| 	echo "    ${BSD_HIER}/etc/headscale/config.yaml" | ||||
| 	echo "" | ||||
| 	echo "----------------------------------------------------------------------" | ||||
| } | ||||
| 
 | ||||
| # | ||||
| # Main body of the script | ||||
| # | ||||
| { | ||||
| 	ensure_sudo | ||||
| 	ensure_headscale_path | ||||
| 	create_headscale_user | ||||
| 	create_headscale_group | ||||
| 	create_run_dir | ||||
| 	summary | ||||
| } | ||||
| @ -1,15 +0,0 @@ | ||||
| #!/bin/sh | ||||
| # Determine OS platform | ||||
| # shellcheck source=/dev/null | ||||
| . /etc/os-release | ||||
| 
 | ||||
| if command -V systemctl >/dev/null 2>&1; then | ||||
| 	echo "Stop and disable headscale service" | ||||
| 	systemctl stop headscale >/dev/null 2>&1 || true | ||||
| 	systemctl disable headscale >/dev/null 2>&1 || true | ||||
| 	echo "Running daemon-reload" | ||||
| 	systemctl daemon-reload || true | ||||
| fi | ||||
| 
 | ||||
| echo "Removing run directory" | ||||
| rm -rf "/var/run/headscale.sock" | ||||
| @ -87,8 +87,8 @@ managed by systemd. | ||||
|     sudo nano /etc/headscale/config.yaml | ||||
|     ``` | ||||
| 
 | ||||
| 1.  Copy [headscale's systemd service file](../../packaging/headscale.systemd.service) to | ||||
|     `/etc/systemd/system/headscale.service` and adjust it to suit your local setup. The following parameters likely need | ||||
| 1.  Copy [headscale's systemd service file](https://github.com/juanfont/headscale/blob/main/packaging/systemd/headscale.service) | ||||
|     to `/etc/systemd/system/headscale.service` and adjust it to suit your local setup. The following parameters likely need | ||||
|     to be modified: `ExecStart`, `WorkingDirectory`, `ReadWritePaths`. | ||||
| 
 | ||||
| 1.  In `/etc/headscale/config.yaml`, override the default `headscale` unix socket with a path that is writable by the | ||||
|  | ||||
| @ -58,9 +58,6 @@ theme: | ||||
| 
 | ||||
| # Excludes | ||||
| exclude_docs: | | ||||
|   /packaging/README.md | ||||
|   /packaging/postinstall.sh | ||||
|   /packaging/postremove.sh | ||||
|   /requirements.txt | ||||
| 
 | ||||
| # Plugins | ||||
|  | ||||
							
								
								
									
										5
									
								
								packaging/README.md
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										5
									
								
								packaging/README.md
									
									
									
									
									
										Normal file
									
								
							| @ -0,0 +1,5 @@ | ||||
| # Packaging | ||||
| 
 | ||||
| We use [nFPM](https://nfpm.goreleaser.com/) for making `.deb` packages. | ||||
| 
 | ||||
| This folder contains files we need to package with these releases. | ||||
							
								
								
									
										87
									
								
								packaging/deb/postinst
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										87
									
								
								packaging/deb/postinst
									
									
									
									
									
										Normal file
									
								
							| @ -0,0 +1,87 @@ | ||||
| #!/bin/sh | ||||
| # postinst script for headscale. | ||||
| 
 | ||||
| set -e | ||||
| 
 | ||||
| # Summary of how this script can be called: | ||||
| #        * <postinst> 'configure' <most-recently-configured-version> | ||||
| #        * <old-postinst> 'abort-upgrade' <new version> | ||||
| #        * <conflictor's-postinst> 'abort-remove' 'in-favour' <package> | ||||
| #          <new-version> | ||||
| #        * <postinst> 'abort-remove' | ||||
| #        * <deconfigured's-postinst> 'abort-deconfigure' 'in-favour' | ||||
| #          <failed-install-package> <version> 'removing' | ||||
| #          <conflicting-package> <version> | ||||
| # for details, see https://www.debian.org/doc/debian-policy/ or | ||||
| # the debian-policy package. | ||||
| 
 | ||||
| HEADSCALE_USER="headscale" | ||||
| HEADSCALE_GROUP="headscale" | ||||
| HEADSCALE_HOME_DIR="/var/lib/headscale" | ||||
| HEADSCALE_SHELL="/usr/sbin/nologin" | ||||
| HEADSCALE_SERVICE="headscale.service" | ||||
| 
 | ||||
| case "$1" in | ||||
|     configure) | ||||
|       groupadd --force --system "$HEADSCALE_GROUP" | ||||
|       if ! id -u "$HEADSCALE_USER" >/dev/null 2>&1; then | ||||
|         useradd --system --shell "$HEADSCALE_SHELL" \ | ||||
|           --gid "$HEADSCALE_GROUP" --home-dir "$HEADSCALE_HOME_DIR" \ | ||||
|           --comment "headscale default user" "$HEADSCALE_USER" | ||||
|       fi | ||||
| 
 | ||||
|       if dpkg --compare-versions "$2" lt-nl "0.27"; then | ||||
|         # < 0.24.0-beta.1 used /home/headscale as home and /bin/sh as shell. | ||||
|         # The directory /home/headscale was not created by the package or | ||||
|         # useradd but the service always used /var/lib/headscale which was | ||||
|         # always shipped by the package as empty directory. Previous versions | ||||
|         # of the package did not update the user account properties. | ||||
|         usermod --home "$HEADSCALE_HOME_DIR" --shell "$HEADSCALE_SHELL" \ | ||||
|           "$HEADSCALE_USER" >/dev/null | ||||
|       fi | ||||
| 
 | ||||
|       if dpkg --compare-versions "$2" lt-nl "0.27" \ | ||||
|         && [ $(id --user "$HEADSCALE_USER") -ge 1000 ] \ | ||||
|         && [ $(id --group "$HEADSCALE_GROUP") -ge 1000 ]; then | ||||
|         # < 0.26.0-beta.1 created a regular user/group to run headscale. | ||||
|         # Previous versions of the package did not migrate to system uid/gid. | ||||
|         # Assume that the *default* uid/gid range is in use and only run this | ||||
|         # migration when the current uid/gid is allocated in the user range. | ||||
|         # Create a temporary system user/group to guarantee the allocation of a | ||||
|         # uid/gid in the system range. Assign this new uid/gid to the existing | ||||
|         # user and group and remove the temporary user/group afterwards. | ||||
|         tmp_name="headscaletmp" | ||||
|         useradd --system --no-log-init --no-create-home --shell "$HEADSCALE_SHELL" "$tmp_name" | ||||
|         tmp_uid="$(id --user "$tmp_name")" | ||||
|         tmp_gid="$(id --group "$tmp_name")" | ||||
|         usermod --non-unique --uid "$tmp_uid" --gid "$tmp_gid" "$HEADSCALE_USER" | ||||
|         groupmod --non-unique --gid "$tmp_gid" "$HEADSCALE_USER" | ||||
|         userdel --force "$tmp_name" | ||||
|       fi | ||||
| 
 | ||||
|       # Enable service and keep track of its state | ||||
|       if deb-systemd-helper --quiet was-enabled "$HEADSCALE_SERVICE"; then | ||||
|         deb-systemd-helper enable "$HEADSCALE_SERVICE" >/dev/null || true | ||||
|       else | ||||
|         deb-systemd-helper update-state "$HEADSCALE_SERVICE" >/dev/null || true | ||||
|       fi | ||||
| 
 | ||||
|       # Bounce service | ||||
|       if [ -d /run/systemd/system ]; then | ||||
|         systemctl --system daemon-reload >/dev/null || true | ||||
|         if [ -n "$2" ]; then | ||||
|           deb-systemd-invoke restart "$HEADSCALE_SERVICE" >/dev/null || true | ||||
|         else | ||||
|           deb-systemd-invoke start "$HEADSCALE_SERVICE" >/dev/null || true | ||||
|         fi | ||||
|       fi | ||||
|     ;; | ||||
| 
 | ||||
|     abort-upgrade|abort-remove|abort-deconfigure) | ||||
|     ;; | ||||
| 
 | ||||
|     *) | ||||
|         echo "postinst called with unknown argument '$1'" >&2 | ||||
|         exit 1 | ||||
|     ;; | ||||
| esac | ||||
							
								
								
									
										42
									
								
								packaging/deb/postrm
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										42
									
								
								packaging/deb/postrm
									
									
									
									
									
										Normal file
									
								
							| @ -0,0 +1,42 @@ | ||||
| #!/bin/sh | ||||
| # postrm script for headscale. | ||||
| 
 | ||||
| set -e | ||||
| 
 | ||||
| # Summary of how this script can be called: | ||||
| #        * <postrm> 'remove' | ||||
| #        * <postrm> 'purge' | ||||
| #        * <old-postrm> 'upgrade' <new-version> | ||||
| #        * <new-postrm> 'failed-upgrade' <old-version> | ||||
| #        * <new-postrm> 'abort-install' | ||||
| #        * <new-postrm> 'abort-install' <old-version> | ||||
| #        * <new-postrm> 'abort-upgrade' <old-version> | ||||
| #        * <disappearer's-postrm> 'disappear' <overwriter> | ||||
| #          <overwriter-version> | ||||
| # for details, see https://www.debian.org/doc/debian-policy/ or | ||||
| # the debian-policy package. | ||||
| 
 | ||||
| 
 | ||||
| case "$1" in | ||||
|     remove) | ||||
|       if [ -d /run/systemd/system ]; then | ||||
|         systemctl --system daemon-reload >/dev/null || true | ||||
|       fi | ||||
|     ;; | ||||
| 
 | ||||
|     purge) | ||||
|       userdel headscale | ||||
|       rm -rf /var/lib/headscale | ||||
|       if [ -x "/usr/bin/deb-systemd-helper" ]; then | ||||
|         deb-systemd-helper purge headscale.service >/dev/null || true | ||||
|       fi | ||||
|     ;; | ||||
| 
 | ||||
|     upgrade|failed-upgrade|abort-install|abort-upgrade|disappear) | ||||
|     ;; | ||||
| 
 | ||||
|     *) | ||||
|         echo "postrm called with unknown argument '$1'" >&2 | ||||
|         exit 1 | ||||
|     ;; | ||||
| esac | ||||
							
								
								
									
										34
									
								
								packaging/deb/prerm
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										34
									
								
								packaging/deb/prerm
									
									
									
									
									
										Normal file
									
								
							| @ -0,0 +1,34 @@ | ||||
| #!/bin/sh | ||||
| # prerm script for headscale. | ||||
| 
 | ||||
| set -e | ||||
| 
 | ||||
| # Summary of how this script can be called: | ||||
| #        * <prerm> 'remove' | ||||
| #        * <old-prerm> 'upgrade' <new-version> | ||||
| #        * <new-prerm> 'failed-upgrade' <old-version> | ||||
| #        * <conflictor's-prerm> 'remove' 'in-favour' <package> <new-version> | ||||
| #        * <deconfigured's-prerm> 'deconfigure' 'in-favour' | ||||
| #          <package-being-installed> <version> 'removing' | ||||
| #          <conflicting-package> <version> | ||||
| # for details, see https://www.debian.org/doc/debian-policy/ or | ||||
| # the debian-policy package. | ||||
| 
 | ||||
| 
 | ||||
| case "$1" in | ||||
|     remove) | ||||
|       if [ -d /run/systemd/system ]; then | ||||
|           deb-systemd-invoke stop headscale.service >/dev/null || true | ||||
|       fi | ||||
|     ;; | ||||
|     upgrade|deconfigure) | ||||
|     ;; | ||||
| 
 | ||||
|     failed-upgrade) | ||||
|     ;; | ||||
| 
 | ||||
|     *) | ||||
|         echo "prerm called with unknown argument '$1'" >&2 | ||||
|         exit 1 | ||||
|     ;; | ||||
| esac | ||||
		Loading…
	
		Reference in New Issue
	
	Block a user