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 |     vendor: headscale | ||||||
|     maintainer: Kristoffer Dalby <kristoffer@dalby.cc> |     maintainer: Kristoffer Dalby <kristoffer@dalby.cc> | ||||||
|     homepage: https://github.com/juanfont/headscale |     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 |     bindir: /usr/bin | ||||||
|  |     section: net | ||||||
|     formats: |     formats: | ||||||
|       - deb |       - deb | ||||||
|     contents: |     contents: | ||||||
| @ -74,15 +81,21 @@ nfpms: | |||||||
|         type: config|noreplace |         type: config|noreplace | ||||||
|         file_info: |         file_info: | ||||||
|           mode: 0644 |           mode: 0644 | ||||||
|       - src: ./docs/packaging/headscale.systemd.service |       - src: ./packaging/systemd/headscale.service | ||||||
|         dst: /usr/lib/systemd/system/headscale.service |         dst: /usr/lib/systemd/system/headscale.service | ||||||
|       - dst: /var/lib/headscale |       - dst: /var/lib/headscale | ||||||
|         type: dir |         type: dir | ||||||
|       - dst: /var/run/headscale |       - src: LICENSE | ||||||
|         type: dir |         dst: /usr/share/doc/headscale/copyright | ||||||
|     scripts: |     scripts: | ||||||
|       postinstall: ./docs/packaging/postinstall.sh |       postinstall: ./packaging/deb/postinst | ||||||
|       postremove: ./docs/packaging/postremove.sh |       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: | kos: | ||||||
|   - id: ghcr |   - 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 |     sudo nano /etc/headscale/config.yaml | ||||||
|     ``` |     ``` | ||||||
| 
 | 
 | ||||||
| 1.  Copy [headscale's systemd service file](../../packaging/headscale.systemd.service) to | 1.  Copy [headscale's systemd service file](https://github.com/juanfont/headscale/blob/main/packaging/systemd/headscale.service) | ||||||
|     `/etc/systemd/system/headscale.service` and adjust it to suit your local setup. The following parameters likely need |     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`. |     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 | 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 | # Excludes | ||||||
| exclude_docs: | | exclude_docs: | | ||||||
|   /packaging/README.md |  | ||||||
|   /packaging/postinstall.sh |  | ||||||
|   /packaging/postremove.sh |  | ||||||
|   /requirements.txt |   /requirements.txt | ||||||
| 
 | 
 | ||||||
| # Plugins | # 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