diff options
| author | Nick Khyl <nickk@tailscale.com> | 2024-12-05 13:16:48 -0600 |
|---|---|---|
| committer | Nick Khyl <nickk@tailscale.com> | 2024-12-05 13:16:48 -0600 |
| commit | 0267fe83b200f1702a2fa0a395442c02a053fadb (patch) | |
| tree | 63654c55225eeb834de59a5a0bc8d19033c6145b /release | |
| parent | 87546a5edf6b6503a87eeb2d666baba57398a066 (diff) | |
| download | tailscale-1.78.0.tar.xz tailscale-1.78.0.zip | |
VERSION.txt: this is v1.78.0v1.78.0
Signed-off-by: Nick Khyl <nickk@tailscale.com>
Diffstat (limited to 'release')
21 files changed, 985 insertions, 985 deletions
diff --git a/release/deb/debian.postrm.sh b/release/deb/debian.postrm.sh index f4dd4ed9c..93d90b0ea 100755 --- a/release/deb/debian.postrm.sh +++ b/release/deb/debian.postrm.sh @@ -1,17 +1,17 @@ -#!/bin/sh -set -e -if [ -d /run/systemd/system ] ; then - systemctl --system daemon-reload >/dev/null || true -fi - -if [ -x "/usr/bin/deb-systemd-helper" ]; then - if [ "$1" = "remove" ]; then - deb-systemd-helper mask 'tailscaled.service' >/dev/null || true - fi - - if [ "$1" = "purge" ]; then - deb-systemd-helper purge 'tailscaled.service' >/dev/null || true - deb-systemd-helper unmask 'tailscaled.service' >/dev/null || true - rm -rf /var/lib/tailscale - fi -fi +#!/bin/sh
+set -e
+if [ -d /run/systemd/system ] ; then
+ systemctl --system daemon-reload >/dev/null || true
+fi
+
+if [ -x "/usr/bin/deb-systemd-helper" ]; then
+ if [ "$1" = "remove" ]; then
+ deb-systemd-helper mask 'tailscaled.service' >/dev/null || true
+ fi
+
+ if [ "$1" = "purge" ]; then
+ deb-systemd-helper purge 'tailscaled.service' >/dev/null || true
+ deb-systemd-helper unmask 'tailscaled.service' >/dev/null || true
+ rm -rf /var/lib/tailscale
+ fi
+fi
diff --git a/release/deb/debian.prerm.sh b/release/deb/debian.prerm.sh index 9be58ede4..a712a08c8 100755 --- a/release/deb/debian.prerm.sh +++ b/release/deb/debian.prerm.sh @@ -1,7 +1,7 @@ -#!/bin/sh -set -e -if [ "$1" = "remove" ]; then - if [ -d /run/systemd/system ]; then - deb-systemd-invoke stop 'tailscaled.service' >/dev/null || true - fi -fi +#!/bin/sh
+set -e
+if [ "$1" = "remove" ]; then
+ if [ -d /run/systemd/system ]; then
+ deb-systemd-invoke stop 'tailscaled.service' >/dev/null || true
+ fi
+fi
diff --git a/release/dist/memoize.go b/release/dist/memoize.go index 0927ac0a8..f148cd2b7 100644 --- a/release/dist/memoize.go +++ b/release/dist/memoize.go @@ -1,86 +1,86 @@ -// Copyright (c) Tailscale Inc & AUTHORS -// SPDX-License-Identifier: BSD-3-Clause - -package dist - -import ( - "sync" - - "tailscale.com/util/deephash" -) - -// MemoizedFn is a function that memoize.Do can call. -type MemoizedFn[T any] func() (T, error) - -// Memoize runs MemoizedFns and remembers their results. -type Memoize[O any] struct { - mu sync.Mutex - cond *sync.Cond - outs map[deephash.Sum]O - errs map[deephash.Sum]error - inflight map[deephash.Sum]bool -} - -// Do runs fn and returns its result. -// fn is only run once per unique key. Subsequent Do calls with the same key -// return the memoized result of the first call, even if fn is a different -// function. -func (m *Memoize[O]) Do(key any, fn MemoizedFn[O]) (ret O, err error) { - m.mu.Lock() - defer m.mu.Unlock() - if m.cond == nil { - m.cond = sync.NewCond(&m.mu) - m.outs = map[deephash.Sum]O{} - m.errs = map[deephash.Sum]error{} - m.inflight = map[deephash.Sum]bool{} - } - - k := deephash.Hash(&key) - - for m.inflight[k] { - m.cond.Wait() - } - if err := m.errs[k]; err != nil { - var ret O - return ret, err - } - if ret, ok := m.outs[k]; ok { - return ret, nil - } - - m.inflight[k] = true - m.mu.Unlock() - defer func() { - m.mu.Lock() - delete(m.inflight, k) - if err != nil { - m.errs[k] = err - } else { - m.outs[k] = ret - } - m.cond.Broadcast() - }() - - ret, err = fn() - if err != nil { - var ret O - return ret, err - } - return ret, nil -} - -// once is like memoize, but for functions that don't return non-error values. -type once struct { - m Memoize[any] -} - -// Do runs fn. -// fn is only run once per unique key. Subsequent Do calls with the same key -// return the memoized result of the first call, even if fn is a different -// function. -func (o *once) Do(key any, fn func() error) error { - _, err := o.m.Do(key, func() (any, error) { - return nil, fn() - }) - return err -} +// Copyright (c) Tailscale Inc & AUTHORS
+// SPDX-License-Identifier: BSD-3-Clause
+
+package dist
+
+import (
+ "sync"
+
+ "tailscale.com/util/deephash"
+)
+
+// MemoizedFn is a function that memoize.Do can call.
+type MemoizedFn[T any] func() (T, error)
+
+// Memoize runs MemoizedFns and remembers their results.
+type Memoize[O any] struct {
+ mu sync.Mutex
+ cond *sync.Cond
+ outs map[deephash.Sum]O
+ errs map[deephash.Sum]error
+ inflight map[deephash.Sum]bool
+}
+
+// Do runs fn and returns its result.
+// fn is only run once per unique key. Subsequent Do calls with the same key
+// return the memoized result of the first call, even if fn is a different
+// function.
+func (m *Memoize[O]) Do(key any, fn MemoizedFn[O]) (ret O, err error) {
+ m.mu.Lock()
+ defer m.mu.Unlock()
+ if m.cond == nil {
+ m.cond = sync.NewCond(&m.mu)
+ m.outs = map[deephash.Sum]O{}
+ m.errs = map[deephash.Sum]error{}
+ m.inflight = map[deephash.Sum]bool{}
+ }
+
+ k := deephash.Hash(&key)
+
+ for m.inflight[k] {
+ m.cond.Wait()
+ }
+ if err := m.errs[k]; err != nil {
+ var ret O
+ return ret, err
+ }
+ if ret, ok := m.outs[k]; ok {
+ return ret, nil
+ }
+
+ m.inflight[k] = true
+ m.mu.Unlock()
+ defer func() {
+ m.mu.Lock()
+ delete(m.inflight, k)
+ if err != nil {
+ m.errs[k] = err
+ } else {
+ m.outs[k] = ret
+ }
+ m.cond.Broadcast()
+ }()
+
+ ret, err = fn()
+ if err != nil {
+ var ret O
+ return ret, err
+ }
+ return ret, nil
+}
+
+// once is like memoize, but for functions that don't return non-error values.
+type once struct {
+ m Memoize[any]
+}
+
+// Do runs fn.
+// fn is only run once per unique key. Subsequent Do calls with the same key
+// return the memoized result of the first call, even if fn is a different
+// function.
+func (o *once) Do(key any, fn func() error) error {
+ _, err := o.m.Do(key, func() (any, error) {
+ return nil, fn()
+ })
+ return err
+}
diff --git a/release/dist/synology/files/Tailscale.sc b/release/dist/synology/files/Tailscale.sc index 707ac6bb0..f3bb1f0bd 100644 --- a/release/dist/synology/files/Tailscale.sc +++ b/release/dist/synology/files/Tailscale.sc @@ -1,6 +1,6 @@ -[Tailscale] -title="Tailscale" -desc="Tailscale VPN" -port_forward="no" -src.ports="41641/udp" +[Tailscale]
+title="Tailscale"
+desc="Tailscale VPN"
+port_forward="no"
+src.ports="41641/udp"
dst.ports="41641/udp"
\ No newline at end of file diff --git a/release/dist/synology/files/config b/release/dist/synology/files/config index 4dbc48dfb..1cf1a6cfa 100644 --- a/release/dist/synology/files/config +++ b/release/dist/synology/files/config @@ -1,11 +1,11 @@ -{ - ".url": { - "SYNO.SDS.Tailscale": { - "type": "url", - "title": "Tailscale", - "icon": "PACKAGE_ICON_256.PNG", - "url": "webman/3rdparty/Tailscale/index.cgi/", - "urlTarget": "_syno_tailscale" - } - } -} +{
+ ".url": {
+ "SYNO.SDS.Tailscale": {
+ "type": "url",
+ "title": "Tailscale",
+ "icon": "PACKAGE_ICON_256.PNG",
+ "url": "webman/3rdparty/Tailscale/index.cgi/",
+ "urlTarget": "_syno_tailscale"
+ }
+ }
+}
diff --git a/release/dist/synology/files/index.cgi b/release/dist/synology/files/index.cgi index 2c1990cfd..996160d1d 100755 --- a/release/dist/synology/files/index.cgi +++ b/release/dist/synology/files/index.cgi @@ -1,2 +1,2 @@ -#! /bin/sh -exec /var/packages/Tailscale/target/bin/tailscale web -cgi -prefix="/webman/3rdparty/Tailscale/index.cgi/" +#! /bin/sh
+exec /var/packages/Tailscale/target/bin/tailscale web -cgi -prefix="/webman/3rdparty/Tailscale/index.cgi/"
diff --git a/release/dist/synology/files/logrotate-dsm6 b/release/dist/synology/files/logrotate-dsm6 index 2df64283a..a52a6ba24 100644 --- a/release/dist/synology/files/logrotate-dsm6 +++ b/release/dist/synology/files/logrotate-dsm6 @@ -1,8 +1,8 @@ -/var/packages/Tailscale/etc/tailscaled.stdout.log { - size 10M - rotate 3 - missingok - copytruncate - compress - notifempty -} +/var/packages/Tailscale/etc/tailscaled.stdout.log {
+ size 10M
+ rotate 3
+ missingok
+ copytruncate
+ compress
+ notifempty
+}
diff --git a/release/dist/synology/files/logrotate-dsm7 b/release/dist/synology/files/logrotate-dsm7 index 7020dc925..3fe677510 100644 --- a/release/dist/synology/files/logrotate-dsm7 +++ b/release/dist/synology/files/logrotate-dsm7 @@ -1,8 +1,8 @@ -/var/packages/Tailscale/var/tailscaled.stdout.log { - size 10M - rotate 3 - missingok - copytruncate - compress - notifempty -} +/var/packages/Tailscale/var/tailscaled.stdout.log {
+ size 10M
+ rotate 3
+ missingok
+ copytruncate
+ compress
+ notifempty
+}
diff --git a/release/dist/synology/files/privilege-dsm6 b/release/dist/synology/files/privilege-dsm6 index 4b6fe093a..c638528d1 100644 --- a/release/dist/synology/files/privilege-dsm6 +++ b/release/dist/synology/files/privilege-dsm6 @@ -1,7 +1,7 @@ -{ - "defaults":{ - "run-as": "root" - }, - "username": "tailscale", - "groupname": "tailscale" -} +{
+ "defaults":{
+ "run-as": "root"
+ },
+ "username": "tailscale",
+ "groupname": "tailscale"
+}
diff --git a/release/dist/synology/files/privilege-dsm7 b/release/dist/synology/files/privilege-dsm7 index 93a9c4f7d..4eca66cff 100644 --- a/release/dist/synology/files/privilege-dsm7 +++ b/release/dist/synology/files/privilege-dsm7 @@ -1,7 +1,7 @@ -{ - "defaults":{ - "run-as": "package" - }, - "username": "tailscale", - "groupname": "tailscale" -} +{
+ "defaults":{
+ "run-as": "package"
+ },
+ "username": "tailscale",
+ "groupname": "tailscale"
+}
diff --git a/release/dist/synology/files/privilege-dsm7.for-package-center b/release/dist/synology/files/privilege-dsm7.for-package-center index db1468346..b2f93cee1 100644 --- a/release/dist/synology/files/privilege-dsm7.for-package-center +++ b/release/dist/synology/files/privilege-dsm7.for-package-center @@ -1,13 +1,13 @@ -{ - "defaults":{ - "run-as": "package" - }, - "username": "tailscale", - "groupname": "tailscale", - "tool": [{ - "relpath": "bin/tailscaled", - "user": "package", - "group": "package", - "capabilities": "cap_net_admin,cap_chown,cap_net_raw" - }] -} +{
+ "defaults":{
+ "run-as": "package"
+ },
+ "username": "tailscale",
+ "groupname": "tailscale",
+ "tool": [{
+ "relpath": "bin/tailscaled",
+ "user": "package",
+ "group": "package",
+ "capabilities": "cap_net_admin,cap_chown,cap_net_raw"
+ }]
+}
diff --git a/release/dist/synology/files/resource b/release/dist/synology/files/resource index 0da0002ef..706c97671 100644 --- a/release/dist/synology/files/resource +++ b/release/dist/synology/files/resource @@ -1,11 +1,11 @@ -{ - "port-config": { - "protocol-file": "conf/Tailscale.sc" - }, - "usr-local-linker": { - "bin": ["bin/tailscale"] - }, - "syslog-config": { - "logrotate-relpath": "conf/logrotate.conf" - } +{
+ "port-config": {
+ "protocol-file": "conf/Tailscale.sc"
+ },
+ "usr-local-linker": {
+ "bin": ["bin/tailscale"]
+ },
+ "syslog-config": {
+ "logrotate-relpath": "conf/logrotate.conf"
+ }
}
\ No newline at end of file diff --git a/release/dist/synology/files/scripts/postupgrade b/release/dist/synology/files/scripts/postupgrade index 92b94c40c..2a7fba5b6 100644 --- a/release/dist/synology/files/scripts/postupgrade +++ b/release/dist/synology/files/scripts/postupgrade @@ -1,3 +1,3 @@ -#!/bin/sh - +#!/bin/sh
+
exit 0
\ No newline at end of file diff --git a/release/dist/synology/files/scripts/preupgrade b/release/dist/synology/files/scripts/preupgrade index 92b94c40c..2a7fba5b6 100644 --- a/release/dist/synology/files/scripts/preupgrade +++ b/release/dist/synology/files/scripts/preupgrade @@ -1,3 +1,3 @@ -#!/bin/sh - +#!/bin/sh
+
exit 0
\ No newline at end of file diff --git a/release/dist/synology/files/scripts/start-stop-status b/release/dist/synology/files/scripts/start-stop-status index e6ece04e3..311f9293b 100755 --- a/release/dist/synology/files/scripts/start-stop-status +++ b/release/dist/synology/files/scripts/start-stop-status @@ -1,129 +1,129 @@ -#!/bin/bash - -SERVICE_NAME="tailscale" - -if [ "${SYNOPKG_DSM_VERSION_MAJOR}" -eq "6" ]; then - PKGVAR="/var/packages/Tailscale/etc" -else - PKGVAR="${SYNOPKG_PKGVAR}" -fi - -PID_FILE="${PKGVAR}/tailscaled.pid" -LOG_FILE="${PKGVAR}/tailscaled.stdout.log" -STATE_FILE="${PKGVAR}/tailscaled.state" -SOCKET_FILE="${PKGVAR}/tailscaled.sock" -PORT="41641" - -SERVICE_COMMAND="${SYNOPKG_PKGDEST}/bin/tailscaled \ ---state=${STATE_FILE} \ ---socket=${SOCKET_FILE} \ ---port=$PORT" - -if [ "${SYNOPKG_DSM_VERSION_MAJOR}" -eq "7" -a ! -e "/dev/net/tun" ]; then - # TODO(maisem/crawshaw): Disable the tun device in DSM7 for now. - SERVICE_COMMAND="${SERVICE_COMMAND} --tun=userspace-networking" -fi - -if [ "${SYNOPKG_DSM_VERSION_MAJOR}" -eq "6" ]; then - chown -R tailscale:tailscale "${PKGVAR}/" -fi - -start_daemon() { - local ts=$(date --iso-8601=second) - echo "${ts} Starting ${SERVICE_NAME} with: ${SERVICE_COMMAND}" >${LOG_FILE} - STATE_DIRECTORY=${PKGVAR} ${SERVICE_COMMAND} 2>&1 | sed -u '1,200p;201s,.*,[further tailscaled logs suppressed],p;d' >>${LOG_FILE} & - # We pipe tailscaled's output to sed, so "$!" retrieves the PID of sed not tailscaled. - # Use jobs -p to retrieve the PID of the most recent process group leader. - jobs -p >"${PID_FILE}" -} - -stop_daemon() { - if [ -r "${PID_FILE}" ]; then - local PID=$(cat "${PID_FILE}") - local ts=$(date --iso-8601=second) - echo "${ts} Stopping ${SERVICE_NAME} service PID=${PID}" >>${LOG_FILE} - kill -TERM $PID >>${LOG_FILE} 2>&1 - wait_for_status 1 || kill -KILL $PID >>${LOG_FILE} 2>&1 - rm -f "${PID_FILE}" >/dev/null - fi -} - -daemon_status() { - if [ -r "${PID_FILE}" ]; then - local PID=$(cat "${PID_FILE}") - if ps -o pid -p ${PID} > /dev/null; then - return - fi - rm -f "${PID_FILE}" >/dev/null - fi - return 1 -} - -wait_for_status() { - # 20 tries - # sleeps for 1 second after each try - local counter=20 - while [ ${counter} -gt 0 ]; do - daemon_status - [ $? -eq $1 ] && return - counter=$((counter - 1)) - sleep 1 - done - return 1 -} - -ensure_tun_created() { - if [ "${SYNOPKG_DSM_VERSION_MAJOR}" -eq "7" ]; then - # TODO(maisem/crawshaw): Disable the tun device in DSM7 for now. - return - fi - # Create the necessary file structure for /dev/net/tun - if ([ ! -c /dev/net/tun ]); then - if ([ ! -d /dev/net ]); then - mkdir -m 755 /dev/net - fi - mknod /dev/net/tun c 10 200 - chmod 0755 /dev/net/tun - fi - - # Load the tun module if not already loaded - if (!(lsmod | grep -q "^tun\s")); then - insmod /lib/modules/tun.ko - fi -} - -case $1 in -start) - if daemon_status; then - exit 0 - else - ensure_tun_created - start_daemon - exit $? - fi - ;; -stop) - if daemon_status; then - stop_daemon - exit $? - else - exit 0 - fi - ;; -status) - if daemon_status; then - echo "${SERVICE_NAME} is running" - exit 0 - else - echo "${SERVICE_NAME} is not running" - exit 3 - fi - ;; -log) - exit 0 - ;; -*) - echo "command $1 is not implemented" - exit 0 - ;; -esac +#!/bin/bash
+
+SERVICE_NAME="tailscale"
+
+if [ "${SYNOPKG_DSM_VERSION_MAJOR}" -eq "6" ]; then
+ PKGVAR="/var/packages/Tailscale/etc"
+else
+ PKGVAR="${SYNOPKG_PKGVAR}"
+fi
+
+PID_FILE="${PKGVAR}/tailscaled.pid"
+LOG_FILE="${PKGVAR}/tailscaled.stdout.log"
+STATE_FILE="${PKGVAR}/tailscaled.state"
+SOCKET_FILE="${PKGVAR}/tailscaled.sock"
+PORT="41641"
+
+SERVICE_COMMAND="${SYNOPKG_PKGDEST}/bin/tailscaled \
+--state=${STATE_FILE} \
+--socket=${SOCKET_FILE} \
+--port=$PORT"
+
+if [ "${SYNOPKG_DSM_VERSION_MAJOR}" -eq "7" -a ! -e "/dev/net/tun" ]; then
+ # TODO(maisem/crawshaw): Disable the tun device in DSM7 for now.
+ SERVICE_COMMAND="${SERVICE_COMMAND} --tun=userspace-networking"
+fi
+
+if [ "${SYNOPKG_DSM_VERSION_MAJOR}" -eq "6" ]; then
+ chown -R tailscale:tailscale "${PKGVAR}/"
+fi
+
+start_daemon() {
+ local ts=$(date --iso-8601=second)
+ echo "${ts} Starting ${SERVICE_NAME} with: ${SERVICE_COMMAND}" >${LOG_FILE}
+ STATE_DIRECTORY=${PKGVAR} ${SERVICE_COMMAND} 2>&1 | sed -u '1,200p;201s,.*,[further tailscaled logs suppressed],p;d' >>${LOG_FILE} &
+ # We pipe tailscaled's output to sed, so "$!" retrieves the PID of sed not tailscaled.
+ # Use jobs -p to retrieve the PID of the most recent process group leader.
+ jobs -p >"${PID_FILE}"
+}
+
+stop_daemon() {
+ if [ -r "${PID_FILE}" ]; then
+ local PID=$(cat "${PID_FILE}")
+ local ts=$(date --iso-8601=second)
+ echo "${ts} Stopping ${SERVICE_NAME} service PID=${PID}" >>${LOG_FILE}
+ kill -TERM $PID >>${LOG_FILE} 2>&1
+ wait_for_status 1 || kill -KILL $PID >>${LOG_FILE} 2>&1
+ rm -f "${PID_FILE}" >/dev/null
+ fi
+}
+
+daemon_status() {
+ if [ -r "${PID_FILE}" ]; then
+ local PID=$(cat "${PID_FILE}")
+ if ps -o pid -p ${PID} > /dev/null; then
+ return
+ fi
+ rm -f "${PID_FILE}" >/dev/null
+ fi
+ return 1
+}
+
+wait_for_status() {
+ # 20 tries
+ # sleeps for 1 second after each try
+ local counter=20
+ while [ ${counter} -gt 0 ]; do
+ daemon_status
+ [ $? -eq $1 ] && return
+ counter=$((counter - 1))
+ sleep 1
+ done
+ return 1
+}
+
+ensure_tun_created() {
+ if [ "${SYNOPKG_DSM_VERSION_MAJOR}" -eq "7" ]; then
+ # TODO(maisem/crawshaw): Disable the tun device in DSM7 for now.
+ return
+ fi
+ # Create the necessary file structure for /dev/net/tun
+ if ([ ! -c /dev/net/tun ]); then
+ if ([ ! -d /dev/net ]); then
+ mkdir -m 755 /dev/net
+ fi
+ mknod /dev/net/tun c 10 200
+ chmod 0755 /dev/net/tun
+ fi
+
+ # Load the tun module if not already loaded
+ if (!(lsmod | grep -q "^tun\s")); then
+ insmod /lib/modules/tun.ko
+ fi
+}
+
+case $1 in
+start)
+ if daemon_status; then
+ exit 0
+ else
+ ensure_tun_created
+ start_daemon
+ exit $?
+ fi
+ ;;
+stop)
+ if daemon_status; then
+ stop_daemon
+ exit $?
+ else
+ exit 0
+ fi
+ ;;
+status)
+ if daemon_status; then
+ echo "${SERVICE_NAME} is running"
+ exit 0
+ else
+ echo "${SERVICE_NAME} is not running"
+ exit 3
+ fi
+ ;;
+log)
+ exit 0
+ ;;
+*)
+ echo "command $1 is not implemented"
+ exit 0
+ ;;
+esac
diff --git a/release/dist/unixpkgs/pkgs.go b/release/dist/unixpkgs/pkgs.go index bad6ce572..60a038eb4 100644 --- a/release/dist/unixpkgs/pkgs.go +++ b/release/dist/unixpkgs/pkgs.go @@ -1,472 +1,472 @@ -// Copyright (c) Tailscale Inc & AUTHORS -// SPDX-License-Identifier: BSD-3-Clause - -// Package unixpkgs contains dist Targets for building unix Tailscale packages. -package unixpkgs - -import ( - "archive/tar" - "compress/gzip" - "errors" - "fmt" - "io" - "log" - "os" - "path/filepath" - "strings" - - "github.com/goreleaser/nfpm/v2" - "github.com/goreleaser/nfpm/v2/files" - "tailscale.com/release/dist" -) - -type tgzTarget struct { - filenameArch string // arch to use in filename instead of deriving from goEnv["GOARCH"] - goEnv map[string]string - signer dist.Signer -} - -func (t *tgzTarget) arch() string { - if t.filenameArch != "" { - return t.filenameArch - } - return t.goEnv["GOARCH"] -} - -func (t *tgzTarget) os() string { - return t.goEnv["GOOS"] -} - -func (t *tgzTarget) String() string { - return fmt.Sprintf("%s/%s/tgz", t.os(), t.arch()) -} - -func (t *tgzTarget) Build(b *dist.Build) ([]string, error) { - var filename string - if t.goEnv["GOOS"] == "linux" { - // Linux used to be the only tgz architecture, so we didn't put the OS - // name in the filename. - filename = fmt.Sprintf("tailscale_%s_%s.tgz", b.Version.Short, t.arch()) - } else { - filename = fmt.Sprintf("tailscale_%s_%s_%s.tgz", b.Version.Short, t.os(), t.arch()) - } - if err := b.BuildWebClientAssets(); err != nil { - return nil, err - } - ts, err := b.BuildGoBinary("tailscale.com/cmd/tailscale", t.goEnv) - if err != nil { - return nil, err - } - tsd, err := b.BuildGoBinary("tailscale.com/cmd/tailscaled", t.goEnv) - if err != nil { - return nil, err - } - - log.Printf("Building %s", filename) - - out := filepath.Join(b.Out, filename) - f, err := os.Create(out) - if err != nil { - return nil, err - } - defer f.Close() - gw := gzip.NewWriter(f) - defer gw.Close() - tw := tar.NewWriter(gw) - defer tw.Close() - - addFile := func(src, dst string, mode int64) error { - f, err := os.Open(src) - if err != nil { - return err - } - defer f.Close() - fi, err := f.Stat() - if err != nil { - return err - } - hdr := &tar.Header{ - Name: dst, - Size: fi.Size(), - Mode: mode, - ModTime: b.Time, - Uid: 0, - Gid: 0, - Uname: "root", - Gname: "root", - } - if err := tw.WriteHeader(hdr); err != nil { - return err - } - if _, err = io.Copy(tw, f); err != nil { - return err - } - return nil - } - addDir := func(name string) error { - hdr := &tar.Header{ - Name: name + "/", - Mode: 0755, - ModTime: b.Time, - Uid: 0, - Gid: 0, - Uname: "root", - Gname: "root", - } - return tw.WriteHeader(hdr) - } - dir := strings.TrimSuffix(filename, ".tgz") - if err := addDir(dir); err != nil { - return nil, err - } - if err := addFile(tsd, filepath.Join(dir, "tailscaled"), 0755); err != nil { - return nil, err - } - if err := addFile(ts, filepath.Join(dir, "tailscale"), 0755); err != nil { - return nil, err - } - if t.os() == "linux" { - dir = filepath.Join(dir, "systemd") - if err := addDir(dir); err != nil { - return nil, err - } - tailscaledDir, err := b.GoPkg("tailscale.com/cmd/tailscaled") - if err != nil { - return nil, err - } - if err := addFile(filepath.Join(tailscaledDir, "tailscaled.service"), filepath.Join(dir, "tailscaled.service"), 0644); err != nil { - return nil, err - } - if err := addFile(filepath.Join(tailscaledDir, "tailscaled.defaults"), filepath.Join(dir, "tailscaled.defaults"), 0644); err != nil { - return nil, err - } - } - if err := tw.Close(); err != nil { - return nil, err - } - if err := gw.Close(); err != nil { - return nil, err - } - if err := f.Close(); err != nil { - return nil, err - } - - files := []string{filename} - - if t.signer != nil { - outSig := out + ".sig" - if err := t.signer.SignFile(out, outSig); err != nil { - return nil, err - } - files = append(files, filepath.Base(outSig)) - } - - return files, nil -} - -type debTarget struct { - goEnv map[string]string -} - -func (t *debTarget) os() string { - return t.goEnv["GOOS"] -} - -func (t *debTarget) arch() string { - return t.goEnv["GOARCH"] -} - -func (t *debTarget) String() string { - return fmt.Sprintf("linux/%s/deb", t.goEnv["GOARCH"]) -} - -func (t *debTarget) Build(b *dist.Build) ([]string, error) { - if t.os() != "linux" { - return nil, errors.New("deb only supported on linux") - } - - if err := b.BuildWebClientAssets(); err != nil { - return nil, err - } - ts, err := b.BuildGoBinary("tailscale.com/cmd/tailscale", t.goEnv) - if err != nil { - return nil, err - } - tsd, err := b.BuildGoBinary("tailscale.com/cmd/tailscaled", t.goEnv) - if err != nil { - return nil, err - } - - tailscaledDir, err := b.GoPkg("tailscale.com/cmd/tailscaled") - if err != nil { - return nil, err - } - repoDir, err := b.GoPkg("tailscale.com") - if err != nil { - return nil, err - } - - arch := debArch(t.arch()) - contents, err := files.PrepareForPackager(files.Contents{ - &files.Content{ - Type: files.TypeFile, - Source: ts, - Destination: "/usr/bin/tailscale", - }, - &files.Content{ - Type: files.TypeFile, - Source: tsd, - Destination: "/usr/sbin/tailscaled", - }, - &files.Content{ - Type: files.TypeFile, - Source: filepath.Join(tailscaledDir, "tailscaled.service"), - Destination: "/lib/systemd/system/tailscaled.service", - }, - &files.Content{ - Type: files.TypeConfigNoReplace, - Source: filepath.Join(tailscaledDir, "tailscaled.defaults"), - Destination: "/etc/default/tailscaled", - }, - }, 0, "deb", false) - if err != nil { - return nil, err - } - info := nfpm.WithDefaults(&nfpm.Info{ - Name: "tailscale", - Arch: arch, - Platform: "linux", - Version: b.Version.Short, - Maintainer: "Tailscale Inc <info@tailscale.com>", - Description: "The easiest, most secure, cross platform way to use WireGuard + oauth2 + 2FA/SSO", - Homepage: "https://www.tailscale.com", - License: "MIT", - Section: "net", - Priority: "extra", - Overridables: nfpm.Overridables{ - Contents: contents, - Scripts: nfpm.Scripts{ - PostInstall: filepath.Join(repoDir, "release/deb/debian.postinst.sh"), - PreRemove: filepath.Join(repoDir, "release/deb/debian.prerm.sh"), - PostRemove: filepath.Join(repoDir, "release/deb/debian.postrm.sh"), - }, - Depends: []string{ - // iptables is almost always required but not strictly needed. - // Even if you can technically run Tailscale without it (by - // manually configuring nftables or userspace mode), we still - // mark this as "Depends" because our previous experiment in - // https://github.com/tailscale/tailscale/issues/9236 of making - // it only Recommends caused too many problems. Until our - // nftables table is more mature, we'd rather err on the side of - // wasting a little disk by including iptables for people who - // might not need it rather than handle reports of it being - // missing. - "iptables", - }, - Recommends: []string{ - "tailscale-archive-keyring (>= 1.35.181)", - // The "ip" command isn't needed since 2021-11-01 in - // 408b0923a61972ed but kept as an option as of - // 2021-11-18 in d24ed3f68e35e802d531371. See - // https://github.com/tailscale/tailscale/issues/391. - // We keep it recommended because it's usually - // installed anyway and it's useful for debugging. But - // we can live without it, so it's not Depends. - "iproute2", - }, - Replaces: []string{"tailscale-relay"}, - Conflicts: []string{"tailscale-relay"}, - }, - }) - pkg, err := nfpm.Get("deb") - if err != nil { - return nil, err - } - - filename := fmt.Sprintf("tailscale_%s_%s.deb", b.Version.Short, arch) - log.Printf("Building %s", filename) - f, err := os.Create(filepath.Join(b.Out, filename)) - if err != nil { - return nil, err - } - defer f.Close() - if err := pkg.Package(info, f); err != nil { - return nil, err - } - if err := f.Close(); err != nil { - return nil, err - } - - return []string{filename}, nil -} - -type rpmTarget struct { - goEnv map[string]string - signer dist.Signer -} - -func (t *rpmTarget) os() string { - return t.goEnv["GOOS"] -} - -func (t *rpmTarget) arch() string { - return t.goEnv["GOARCH"] -} - -func (t *rpmTarget) String() string { - return fmt.Sprintf("linux/%s/rpm", t.arch()) -} - -func (t *rpmTarget) Build(b *dist.Build) ([]string, error) { - if t.os() != "linux" { - return nil, errors.New("rpm only supported on linux") - } - - if err := b.BuildWebClientAssets(); err != nil { - return nil, err - } - ts, err := b.BuildGoBinary("tailscale.com/cmd/tailscale", t.goEnv) - if err != nil { - return nil, err - } - tsd, err := b.BuildGoBinary("tailscale.com/cmd/tailscaled", t.goEnv) - if err != nil { - return nil, err - } - - tailscaledDir, err := b.GoPkg("tailscale.com/cmd/tailscaled") - if err != nil { - return nil, err - } - repoDir, err := b.GoPkg("tailscale.com") - if err != nil { - return nil, err - } - - arch := rpmArch(t.arch()) - contents, err := files.PrepareForPackager(files.Contents{ - &files.Content{ - Type: files.TypeFile, - Source: ts, - Destination: "/usr/bin/tailscale", - }, - &files.Content{ - Type: files.TypeFile, - Source: tsd, - Destination: "/usr/sbin/tailscaled", - }, - &files.Content{ - Type: files.TypeFile, - Source: filepath.Join(tailscaledDir, "tailscaled.service"), - Destination: "/lib/systemd/system/tailscaled.service", - }, - &files.Content{ - Type: files.TypeConfigNoReplace, - Source: filepath.Join(tailscaledDir, "tailscaled.defaults"), - Destination: "/etc/default/tailscaled", - }, - // SELinux policy on e.g. CentOS 8 forbids writing to /var/cache. - // Creating an empty directory at install time resolves this issue. - &files.Content{ - Type: files.TypeDir, - Destination: "/var/cache/tailscale", - }, - }, 0, "rpm", false) - if err != nil { - return nil, err - } - info := nfpm.WithDefaults(&nfpm.Info{ - Name: "tailscale", - Arch: arch, - Platform: "linux", - Version: b.Version.Short, - Maintainer: "Tailscale Inc <info@tailscale.com>", - Description: "The easiest, most secure, cross platform way to use WireGuard + oauth2 + 2FA/SSO", - Homepage: "https://www.tailscale.com", - License: "MIT", - Overridables: nfpm.Overridables{ - Contents: contents, - Scripts: nfpm.Scripts{ - PostInstall: filepath.Join(repoDir, "release/rpm/rpm.postinst.sh"), - PreRemove: filepath.Join(repoDir, "release/rpm/rpm.prerm.sh"), - PostRemove: filepath.Join(repoDir, "release/rpm/rpm.postrm.sh"), - }, - Depends: []string{"iptables", "iproute"}, - Replaces: []string{"tailscale-relay"}, - Conflicts: []string{"tailscale-relay"}, - RPM: nfpm.RPM{ - Group: "Network", - Signature: nfpm.RPMSignature{ - PackageSignature: nfpm.PackageSignature{ - SignFn: t.signer, - }, - }, - }, - }, - }) - pkg, err := nfpm.Get("rpm") - if err != nil { - return nil, err - } - - filename := fmt.Sprintf("tailscale_%s_%s.rpm", b.Version.Short, arch) - log.Printf("Building %s", filename) - - f, err := os.Create(filepath.Join(b.Out, filename)) - if err != nil { - return nil, err - } - defer f.Close() - if err := pkg.Package(info, f); err != nil { - return nil, err - } - if err := f.Close(); err != nil { - return nil, err - } - - return []string{filename}, nil -} - -// debArch returns the debian arch name for the given Go arch name. -// nfpm also does this translation internally, but we need to do it outside nfpm -// because we also need the filename to be correct. -func debArch(arch string) string { - switch arch { - case "386": - return "i386" - case "arm": - // TODO: this is supposed to be "armel" for GOARM=5, and "armhf" for - // GOARM=6 and 7. But we have some tech debt to pay off here before we - // can ship more than 1 ARM deb, so for now match redo's behavior of - // shipping armv5 binaries in an armv7 trenchcoat. - return "armhf" - case "mipsle": - return "mipsel" - case "mips64le": - return "mips64el" - default: - return arch - } -} - -// rpmArch returns the RPM arch name for the given Go arch name. -// nfpm also does this translation internally, but we need to do it outside nfpm -// because we also need the filename to be correct. -func rpmArch(arch string) string { - switch arch { - case "amd64": - return "x86_64" - case "386": - return "i386" - case "arm": - return "armv7hl" - case "arm64": - return "aarch64" - case "mipsle": - return "mipsel" - case "mips64le": - return "mips64el" - default: - return arch - } -} +// Copyright (c) Tailscale Inc & AUTHORS
+// SPDX-License-Identifier: BSD-3-Clause
+
+// Package unixpkgs contains dist Targets for building unix Tailscale packages.
+package unixpkgs
+
+import (
+ "archive/tar"
+ "compress/gzip"
+ "errors"
+ "fmt"
+ "io"
+ "log"
+ "os"
+ "path/filepath"
+ "strings"
+
+ "github.com/goreleaser/nfpm/v2"
+ "github.com/goreleaser/nfpm/v2/files"
+ "tailscale.com/release/dist"
+)
+
+type tgzTarget struct {
+ filenameArch string // arch to use in filename instead of deriving from goEnv["GOARCH"]
+ goEnv map[string]string
+ signer dist.Signer
+}
+
+func (t *tgzTarget) arch() string {
+ if t.filenameArch != "" {
+ return t.filenameArch
+ }
+ return t.goEnv["GOARCH"]
+}
+
+func (t *tgzTarget) os() string {
+ return t.goEnv["GOOS"]
+}
+
+func (t *tgzTarget) String() string {
+ return fmt.Sprintf("%s/%s/tgz", t.os(), t.arch())
+}
+
+func (t *tgzTarget) Build(b *dist.Build) ([]string, error) {
+ var filename string
+ if t.goEnv["GOOS"] == "linux" {
+ // Linux used to be the only tgz architecture, so we didn't put the OS
+ // name in the filename.
+ filename = fmt.Sprintf("tailscale_%s_%s.tgz", b.Version.Short, t.arch())
+ } else {
+ filename = fmt.Sprintf("tailscale_%s_%s_%s.tgz", b.Version.Short, t.os(), t.arch())
+ }
+ if err := b.BuildWebClientAssets(); err != nil {
+ return nil, err
+ }
+ ts, err := b.BuildGoBinary("tailscale.com/cmd/tailscale", t.goEnv)
+ if err != nil {
+ return nil, err
+ }
+ tsd, err := b.BuildGoBinary("tailscale.com/cmd/tailscaled", t.goEnv)
+ if err != nil {
+ return nil, err
+ }
+
+ log.Printf("Building %s", filename)
+
+ out := filepath.Join(b.Out, filename)
+ f, err := os.Create(out)
+ if err != nil {
+ return nil, err
+ }
+ defer f.Close()
+ gw := gzip.NewWriter(f)
+ defer gw.Close()
+ tw := tar.NewWriter(gw)
+ defer tw.Close()
+
+ addFile := func(src, dst string, mode int64) error {
+ f, err := os.Open(src)
+ if err != nil {
+ return err
+ }
+ defer f.Close()
+ fi, err := f.Stat()
+ if err != nil {
+ return err
+ }
+ hdr := &tar.Header{
+ Name: dst,
+ Size: fi.Size(),
+ Mode: mode,
+ ModTime: b.Time,
+ Uid: 0,
+ Gid: 0,
+ Uname: "root",
+ Gname: "root",
+ }
+ if err := tw.WriteHeader(hdr); err != nil {
+ return err
+ }
+ if _, err = io.Copy(tw, f); err != nil {
+ return err
+ }
+ return nil
+ }
+ addDir := func(name string) error {
+ hdr := &tar.Header{
+ Name: name + "/",
+ Mode: 0755,
+ ModTime: b.Time,
+ Uid: 0,
+ Gid: 0,
+ Uname: "root",
+ Gname: "root",
+ }
+ return tw.WriteHeader(hdr)
+ }
+ dir := strings.TrimSuffix(filename, ".tgz")
+ if err := addDir(dir); err != nil {
+ return nil, err
+ }
+ if err := addFile(tsd, filepath.Join(dir, "tailscaled"), 0755); err != nil {
+ return nil, err
+ }
+ if err := addFile(ts, filepath.Join(dir, "tailscale"), 0755); err != nil {
+ return nil, err
+ }
+ if t.os() == "linux" {
+ dir = filepath.Join(dir, "systemd")
+ if err := addDir(dir); err != nil {
+ return nil, err
+ }
+ tailscaledDir, err := b.GoPkg("tailscale.com/cmd/tailscaled")
+ if err != nil {
+ return nil, err
+ }
+ if err := addFile(filepath.Join(tailscaledDir, "tailscaled.service"), filepath.Join(dir, "tailscaled.service"), 0644); err != nil {
+ return nil, err
+ }
+ if err := addFile(filepath.Join(tailscaledDir, "tailscaled.defaults"), filepath.Join(dir, "tailscaled.defaults"), 0644); err != nil {
+ return nil, err
+ }
+ }
+ if err := tw.Close(); err != nil {
+ return nil, err
+ }
+ if err := gw.Close(); err != nil {
+ return nil, err
+ }
+ if err := f.Close(); err != nil {
+ return nil, err
+ }
+
+ files := []string{filename}
+
+ if t.signer != nil {
+ outSig := out + ".sig"
+ if err := t.signer.SignFile(out, outSig); err != nil {
+ return nil, err
+ }
+ files = append(files, filepath.Base(outSig))
+ }
+
+ return files, nil
+}
+
+type debTarget struct {
+ goEnv map[string]string
+}
+
+func (t *debTarget) os() string {
+ return t.goEnv["GOOS"]
+}
+
+func (t *debTarget) arch() string {
+ return t.goEnv["GOARCH"]
+}
+
+func (t *debTarget) String() string {
+ return fmt.Sprintf("linux/%s/deb", t.goEnv["GOARCH"])
+}
+
+func (t *debTarget) Build(b *dist.Build) ([]string, error) {
+ if t.os() != "linux" {
+ return nil, errors.New("deb only supported on linux")
+ }
+
+ if err := b.BuildWebClientAssets(); err != nil {
+ return nil, err
+ }
+ ts, err := b.BuildGoBinary("tailscale.com/cmd/tailscale", t.goEnv)
+ if err != nil {
+ return nil, err
+ }
+ tsd, err := b.BuildGoBinary("tailscale.com/cmd/tailscaled", t.goEnv)
+ if err != nil {
+ return nil, err
+ }
+
+ tailscaledDir, err := b.GoPkg("tailscale.com/cmd/tailscaled")
+ if err != nil {
+ return nil, err
+ }
+ repoDir, err := b.GoPkg("tailscale.com")
+ if err != nil {
+ return nil, err
+ }
+
+ arch := debArch(t.arch())
+ contents, err := files.PrepareForPackager(files.Contents{
+ &files.Content{
+ Type: files.TypeFile,
+ Source: ts,
+ Destination: "/usr/bin/tailscale",
+ },
+ &files.Content{
+ Type: files.TypeFile,
+ Source: tsd,
+ Destination: "/usr/sbin/tailscaled",
+ },
+ &files.Content{
+ Type: files.TypeFile,
+ Source: filepath.Join(tailscaledDir, "tailscaled.service"),
+ Destination: "/lib/systemd/system/tailscaled.service",
+ },
+ &files.Content{
+ Type: files.TypeConfigNoReplace,
+ Source: filepath.Join(tailscaledDir, "tailscaled.defaults"),
+ Destination: "/etc/default/tailscaled",
+ },
+ }, 0, "deb", false)
+ if err != nil {
+ return nil, err
+ }
+ info := nfpm.WithDefaults(&nfpm.Info{
+ Name: "tailscale",
+ Arch: arch,
+ Platform: "linux",
+ Version: b.Version.Short,
+ Maintainer: "Tailscale Inc <info@tailscale.com>",
+ Description: "The easiest, most secure, cross platform way to use WireGuard + oauth2 + 2FA/SSO",
+ Homepage: "https://www.tailscale.com",
+ License: "MIT",
+ Section: "net",
+ Priority: "extra",
+ Overridables: nfpm.Overridables{
+ Contents: contents,
+ Scripts: nfpm.Scripts{
+ PostInstall: filepath.Join(repoDir, "release/deb/debian.postinst.sh"),
+ PreRemove: filepath.Join(repoDir, "release/deb/debian.prerm.sh"),
+ PostRemove: filepath.Join(repoDir, "release/deb/debian.postrm.sh"),
+ },
+ Depends: []string{
+ // iptables is almost always required but not strictly needed.
+ // Even if you can technically run Tailscale without it (by
+ // manually configuring nftables or userspace mode), we still
+ // mark this as "Depends" because our previous experiment in
+ // https://github.com/tailscale/tailscale/issues/9236 of making
+ // it only Recommends caused too many problems. Until our
+ // nftables table is more mature, we'd rather err on the side of
+ // wasting a little disk by including iptables for people who
+ // might not need it rather than handle reports of it being
+ // missing.
+ "iptables",
+ },
+ Recommends: []string{
+ "tailscale-archive-keyring (>= 1.35.181)",
+ // The "ip" command isn't needed since 2021-11-01 in
+ // 408b0923a61972ed but kept as an option as of
+ // 2021-11-18 in d24ed3f68e35e802d531371. See
+ // https://github.com/tailscale/tailscale/issues/391.
+ // We keep it recommended because it's usually
+ // installed anyway and it's useful for debugging. But
+ // we can live without it, so it's not Depends.
+ "iproute2",
+ },
+ Replaces: []string{"tailscale-relay"},
+ Conflicts: []string{"tailscale-relay"},
+ },
+ })
+ pkg, err := nfpm.Get("deb")
+ if err != nil {
+ return nil, err
+ }
+
+ filename := fmt.Sprintf("tailscale_%s_%s.deb", b.Version.Short, arch)
+ log.Printf("Building %s", filename)
+ f, err := os.Create(filepath.Join(b.Out, filename))
+ if err != nil {
+ return nil, err
+ }
+ defer f.Close()
+ if err := pkg.Package(info, f); err != nil {
+ return nil, err
+ }
+ if err := f.Close(); err != nil {
+ return nil, err
+ }
+
+ return []string{filename}, nil
+}
+
+type rpmTarget struct {
+ goEnv map[string]string
+ signer dist.Signer
+}
+
+func (t *rpmTarget) os() string {
+ return t.goEnv["GOOS"]
+}
+
+func (t *rpmTarget) arch() string {
+ return t.goEnv["GOARCH"]
+}
+
+func (t *rpmTarget) String() string {
+ return fmt.Sprintf("linux/%s/rpm", t.arch())
+}
+
+func (t *rpmTarget) Build(b *dist.Build) ([]string, error) {
+ if t.os() != "linux" {
+ return nil, errors.New("rpm only supported on linux")
+ }
+
+ if err := b.BuildWebClientAssets(); err != nil {
+ return nil, err
+ }
+ ts, err := b.BuildGoBinary("tailscale.com/cmd/tailscale", t.goEnv)
+ if err != nil {
+ return nil, err
+ }
+ tsd, err := b.BuildGoBinary("tailscale.com/cmd/tailscaled", t.goEnv)
+ if err != nil {
+ return nil, err
+ }
+
+ tailscaledDir, err := b.GoPkg("tailscale.com/cmd/tailscaled")
+ if err != nil {
+ return nil, err
+ }
+ repoDir, err := b.GoPkg("tailscale.com")
+ if err != nil {
+ return nil, err
+ }
+
+ arch := rpmArch(t.arch())
+ contents, err := files.PrepareForPackager(files.Contents{
+ &files.Content{
+ Type: files.TypeFile,
+ Source: ts,
+ Destination: "/usr/bin/tailscale",
+ },
+ &files.Content{
+ Type: files.TypeFile,
+ Source: tsd,
+ Destination: "/usr/sbin/tailscaled",
+ },
+ &files.Content{
+ Type: files.TypeFile,
+ Source: filepath.Join(tailscaledDir, "tailscaled.service"),
+ Destination: "/lib/systemd/system/tailscaled.service",
+ },
+ &files.Content{
+ Type: files.TypeConfigNoReplace,
+ Source: filepath.Join(tailscaledDir, "tailscaled.defaults"),
+ Destination: "/etc/default/tailscaled",
+ },
+ // SELinux policy on e.g. CentOS 8 forbids writing to /var/cache.
+ // Creating an empty directory at install time resolves this issue.
+ &files.Content{
+ Type: files.TypeDir,
+ Destination: "/var/cache/tailscale",
+ },
+ }, 0, "rpm", false)
+ if err != nil {
+ return nil, err
+ }
+ info := nfpm.WithDefaults(&nfpm.Info{
+ Name: "tailscale",
+ Arch: arch,
+ Platform: "linux",
+ Version: b.Version.Short,
+ Maintainer: "Tailscale Inc <info@tailscale.com>",
+ Description: "The easiest, most secure, cross platform way to use WireGuard + oauth2 + 2FA/SSO",
+ Homepage: "https://www.tailscale.com",
+ License: "MIT",
+ Overridables: nfpm.Overridables{
+ Contents: contents,
+ Scripts: nfpm.Scripts{
+ PostInstall: filepath.Join(repoDir, "release/rpm/rpm.postinst.sh"),
+ PreRemove: filepath.Join(repoDir, "release/rpm/rpm.prerm.sh"),
+ PostRemove: filepath.Join(repoDir, "release/rpm/rpm.postrm.sh"),
+ },
+ Depends: []string{"iptables", "iproute"},
+ Replaces: []string{"tailscale-relay"},
+ Conflicts: []string{"tailscale-relay"},
+ RPM: nfpm.RPM{
+ Group: "Network",
+ Signature: nfpm.RPMSignature{
+ PackageSignature: nfpm.PackageSignature{
+ SignFn: t.signer,
+ },
+ },
+ },
+ },
+ })
+ pkg, err := nfpm.Get("rpm")
+ if err != nil {
+ return nil, err
+ }
+
+ filename := fmt.Sprintf("tailscale_%s_%s.rpm", b.Version.Short, arch)
+ log.Printf("Building %s", filename)
+
+ f, err := os.Create(filepath.Join(b.Out, filename))
+ if err != nil {
+ return nil, err
+ }
+ defer f.Close()
+ if err := pkg.Package(info, f); err != nil {
+ return nil, err
+ }
+ if err := f.Close(); err != nil {
+ return nil, err
+ }
+
+ return []string{filename}, nil
+}
+
+// debArch returns the debian arch name for the given Go arch name.
+// nfpm also does this translation internally, but we need to do it outside nfpm
+// because we also need the filename to be correct.
+func debArch(arch string) string {
+ switch arch {
+ case "386":
+ return "i386"
+ case "arm":
+ // TODO: this is supposed to be "armel" for GOARM=5, and "armhf" for
+ // GOARM=6 and 7. But we have some tech debt to pay off here before we
+ // can ship more than 1 ARM deb, so for now match redo's behavior of
+ // shipping armv5 binaries in an armv7 trenchcoat.
+ return "armhf"
+ case "mipsle":
+ return "mipsel"
+ case "mips64le":
+ return "mips64el"
+ default:
+ return arch
+ }
+}
+
+// rpmArch returns the RPM arch name for the given Go arch name.
+// nfpm also does this translation internally, but we need to do it outside nfpm
+// because we also need the filename to be correct.
+func rpmArch(arch string) string {
+ switch arch {
+ case "amd64":
+ return "x86_64"
+ case "386":
+ return "i386"
+ case "arm":
+ return "armv7hl"
+ case "arm64":
+ return "aarch64"
+ case "mipsle":
+ return "mipsel"
+ case "mips64le":
+ return "mips64el"
+ default:
+ return arch
+ }
+}
diff --git a/release/dist/unixpkgs/targets.go b/release/dist/unixpkgs/targets.go index 42bab6d3b..f87c56d31 100644 --- a/release/dist/unixpkgs/targets.go +++ b/release/dist/unixpkgs/targets.go @@ -1,127 +1,127 @@ -// Copyright (c) Tailscale Inc & AUTHORS -// SPDX-License-Identifier: BSD-3-Clause - -package unixpkgs - -import ( - "fmt" - "sort" - "strings" - - "tailscale.com/release/dist" - - _ "github.com/goreleaser/nfpm/v2/deb" - _ "github.com/goreleaser/nfpm/v2/rpm" -) - -type Signers struct { - Tarball dist.Signer - RPM dist.Signer -} - -func Targets(signers Signers) []dist.Target { - var ret []dist.Target - for goosgoarch := range tarballs { - goos, goarch := splitGoosGoarch(goosgoarch) - ret = append(ret, &tgzTarget{ - goEnv: map[string]string{ - "GOOS": goos, - "GOARCH": goarch, - }, - signer: signers.Tarball, - }) - } - for goosgoarch := range debs { - goos, goarch := splitGoosGoarch(goosgoarch) - ret = append(ret, &debTarget{ - goEnv: map[string]string{ - "GOOS": goos, - "GOARCH": goarch, - }, - }) - } - for goosgoarch := range rpms { - goos, goarch := splitGoosGoarch(goosgoarch) - ret = append(ret, &rpmTarget{ - goEnv: map[string]string{ - "GOOS": goos, - "GOARCH": goarch, - }, - signer: signers.RPM, - }) - } - - // Special case: AMD Geode is 386 with softfloat. Tarballs only since it's - // an ancient architecture. - ret = append(ret, &tgzTarget{ - filenameArch: "geode", - goEnv: map[string]string{ - "GOOS": "linux", - "GOARCH": "386", - "GO386": "softfloat", - }, - signer: signers.Tarball, - }) - - sort.Slice(ret, func(i, j int) bool { - return ret[i].String() < ret[j].String() - }) - - return ret -} - -var ( - tarballs = map[string]bool{ - "linux/386": true, - "linux/amd64": true, - "linux/arm": true, - "linux/arm64": true, - "linux/mips64": true, - "linux/mips64le": true, - "linux/mips": true, - "linux/mipsle": true, - "linux/riscv64": true, - // TODO: more tarballs we could distribute, but don't currently. Leaving - // out for initial parity with redo. - // "darwin/amd64": true, - // "darwin/arm64": true, - // "freebsd/amd64": true, - // "openbsd/amd64": true, - } - - debs = map[string]bool{ - "linux/386": true, - "linux/amd64": true, - "linux/arm": true, - "linux/arm64": true, - "linux/riscv64": true, - "linux/mipsle": true, - "linux/mips64le": true, - "linux/mips": true, - // Debian does not support big endian mips64. Leave that out until we know - // we need it. - // "linux/mips64": true, - } - - rpms = map[string]bool{ - "linux/386": true, - "linux/amd64": true, - "linux/arm": true, - "linux/arm64": true, - "linux/riscv64": true, - "linux/mipsle": true, - "linux/mips64le": true, - // Fedora only supports little endian mipses. Maybe some other distribution - // supports big-endian? Leave them out for now. - // "linux/mips": true, - // "linux/mips64": true, - } -) - -func splitGoosGoarch(s string) (string, string) { - goos, goarch, ok := strings.Cut(s, "/") - if !ok { - panic(fmt.Sprintf("invalid target %q", s)) - } - return goos, goarch -} +// Copyright (c) Tailscale Inc & AUTHORS
+// SPDX-License-Identifier: BSD-3-Clause
+
+package unixpkgs
+
+import (
+ "fmt"
+ "sort"
+ "strings"
+
+ "tailscale.com/release/dist"
+
+ _ "github.com/goreleaser/nfpm/v2/deb"
+ _ "github.com/goreleaser/nfpm/v2/rpm"
+)
+
+type Signers struct {
+ Tarball dist.Signer
+ RPM dist.Signer
+}
+
+func Targets(signers Signers) []dist.Target {
+ var ret []dist.Target
+ for goosgoarch := range tarballs {
+ goos, goarch := splitGoosGoarch(goosgoarch)
+ ret = append(ret, &tgzTarget{
+ goEnv: map[string]string{
+ "GOOS": goos,
+ "GOARCH": goarch,
+ },
+ signer: signers.Tarball,
+ })
+ }
+ for goosgoarch := range debs {
+ goos, goarch := splitGoosGoarch(goosgoarch)
+ ret = append(ret, &debTarget{
+ goEnv: map[string]string{
+ "GOOS": goos,
+ "GOARCH": goarch,
+ },
+ })
+ }
+ for goosgoarch := range rpms {
+ goos, goarch := splitGoosGoarch(goosgoarch)
+ ret = append(ret, &rpmTarget{
+ goEnv: map[string]string{
+ "GOOS": goos,
+ "GOARCH": goarch,
+ },
+ signer: signers.RPM,
+ })
+ }
+
+ // Special case: AMD Geode is 386 with softfloat. Tarballs only since it's
+ // an ancient architecture.
+ ret = append(ret, &tgzTarget{
+ filenameArch: "geode",
+ goEnv: map[string]string{
+ "GOOS": "linux",
+ "GOARCH": "386",
+ "GO386": "softfloat",
+ },
+ signer: signers.Tarball,
+ })
+
+ sort.Slice(ret, func(i, j int) bool {
+ return ret[i].String() < ret[j].String()
+ })
+
+ return ret
+}
+
+var (
+ tarballs = map[string]bool{
+ "linux/386": true,
+ "linux/amd64": true,
+ "linux/arm": true,
+ "linux/arm64": true,
+ "linux/mips64": true,
+ "linux/mips64le": true,
+ "linux/mips": true,
+ "linux/mipsle": true,
+ "linux/riscv64": true,
+ // TODO: more tarballs we could distribute, but don't currently. Leaving
+ // out for initial parity with redo.
+ // "darwin/amd64": true,
+ // "darwin/arm64": true,
+ // "freebsd/amd64": true,
+ // "openbsd/amd64": true,
+ }
+
+ debs = map[string]bool{
+ "linux/386": true,
+ "linux/amd64": true,
+ "linux/arm": true,
+ "linux/arm64": true,
+ "linux/riscv64": true,
+ "linux/mipsle": true,
+ "linux/mips64le": true,
+ "linux/mips": true,
+ // Debian does not support big endian mips64. Leave that out until we know
+ // we need it.
+ // "linux/mips64": true,
+ }
+
+ rpms = map[string]bool{
+ "linux/386": true,
+ "linux/amd64": true,
+ "linux/arm": true,
+ "linux/arm64": true,
+ "linux/riscv64": true,
+ "linux/mipsle": true,
+ "linux/mips64le": true,
+ // Fedora only supports little endian mipses. Maybe some other distribution
+ // supports big-endian? Leave them out for now.
+ // "linux/mips": true,
+ // "linux/mips64": true,
+ }
+)
+
+func splitGoosGoarch(s string) (string, string) {
+ goos, goarch, ok := strings.Cut(s, "/")
+ if !ok {
+ panic(fmt.Sprintf("invalid target %q", s))
+ }
+ return goos, goarch
+}
diff --git a/release/release.go b/release/release.go index a8d0e6b62..638635b6d 100644 --- a/release/release.go +++ b/release/release.go @@ -1,15 +1,15 @@ -// Copyright (c) Tailscale Inc & AUTHORS -// SPDX-License-Identifier: BSD-3-Clause - -// Package release provides functionality for building client releases. -package release - -import "embed" - -// This contains all files in the release directory, -// notably the files needed for deb, rpm, and similar packages. -// Because we assign this to the blank identifier, it does not actually embed the files. -// However, this does cause `go mod vendor` to include the files when vendoring the package. -// -//go:embed * -var _ embed.FS +// Copyright (c) Tailscale Inc & AUTHORS
+// SPDX-License-Identifier: BSD-3-Clause
+
+// Package release provides functionality for building client releases.
+package release
+
+import "embed"
+
+// This contains all files in the release directory,
+// notably the files needed for deb, rpm, and similar packages.
+// Because we assign this to the blank identifier, it does not actually embed the files.
+// However, this does cause `go mod vendor` to include the files when vendoring the package.
+//
+//go:embed *
+var _ embed.FS
diff --git a/release/rpm/rpm.postinst.sh b/release/rpm/rpm.postinst.sh index 3d264c5f6..f9c1fddfd 100755 --- a/release/rpm/rpm.postinst.sh +++ b/release/rpm/rpm.postinst.sh @@ -1,41 +1,41 @@ -# $1 == 1 for initial installation. -# $1 == 2 for upgrades. - -if [ $1 -eq 1 ] ; then - # Normally, the tailscale-relay package would request shutdown of - # its service before uninstallation. Unfortunately, the - # tailscale-relay package we distributed doesn't have those - # scriptlets. We definitely want relaynode to be stopped when - # installing tailscaled though, so we blindly try to turn off - # relaynode here. - # - # However, we also want this package installation to look like an - # upgrade from relaynode! Therefore, if relaynode is currently - # enabled, we want to also enable tailscaled. If relaynode is - # currently running, we also want to start tailscaled. - # - # If there doesn't seem to be an active or enabled relaynode on - # the system, we follow the RPM convention for package installs, - # which is to not enable or start the service. - relaynode_enabled=0 - relaynode_running=0 - if systemctl is-enabled tailscale-relay.service >/dev/null 2>&1; then - relaynode_enabled=1 - fi - if systemctl is-active tailscale-relay.service >/dev/null 2>&1; then - relaynode_running=1 - fi - - systemctl --no-reload disable tailscale-relay.service >/dev/null 2>&1 || : - systemctl stop tailscale-relay.service >/dev/null 2>&1 || : - - if [ $relaynode_enabled -eq 1 ]; then - systemctl enable tailscaled.service >/dev/null 2>&1 || : - else - systemctl preset tailscaled.service >/dev/null 2>&1 || : - fi - - if [ $relaynode_running -eq 1 ]; then - systemctl start tailscaled.service >/dev/null 2>&1 || : - fi -fi +# $1 == 1 for initial installation.
+# $1 == 2 for upgrades.
+
+if [ $1 -eq 1 ] ; then
+ # Normally, the tailscale-relay package would request shutdown of
+ # its service before uninstallation. Unfortunately, the
+ # tailscale-relay package we distributed doesn't have those
+ # scriptlets. We definitely want relaynode to be stopped when
+ # installing tailscaled though, so we blindly try to turn off
+ # relaynode here.
+ #
+ # However, we also want this package installation to look like an
+ # upgrade from relaynode! Therefore, if relaynode is currently
+ # enabled, we want to also enable tailscaled. If relaynode is
+ # currently running, we also want to start tailscaled.
+ #
+ # If there doesn't seem to be an active or enabled relaynode on
+ # the system, we follow the RPM convention for package installs,
+ # which is to not enable or start the service.
+ relaynode_enabled=0
+ relaynode_running=0
+ if systemctl is-enabled tailscale-relay.service >/dev/null 2>&1; then
+ relaynode_enabled=1
+ fi
+ if systemctl is-active tailscale-relay.service >/dev/null 2>&1; then
+ relaynode_running=1
+ fi
+
+ systemctl --no-reload disable tailscale-relay.service >/dev/null 2>&1 || :
+ systemctl stop tailscale-relay.service >/dev/null 2>&1 || :
+
+ if [ $relaynode_enabled -eq 1 ]; then
+ systemctl enable tailscaled.service >/dev/null 2>&1 || :
+ else
+ systemctl preset tailscaled.service >/dev/null 2>&1 || :
+ fi
+
+ if [ $relaynode_running -eq 1 ]; then
+ systemctl start tailscaled.service >/dev/null 2>&1 || :
+ fi
+fi
diff --git a/release/rpm/rpm.postrm.sh b/release/rpm/rpm.postrm.sh index d74f7e9de..e19a7305c 100755 --- a/release/rpm/rpm.postrm.sh +++ b/release/rpm/rpm.postrm.sh @@ -1,8 +1,8 @@ -# $1 == 0 for uninstallation. -# $1 == 1 for removing old package during upgrade. - -systemctl daemon-reload >/dev/null 2>&1 || : -if [ $1 -ge 1 ] ; then - # Package upgrade, not uninstall - systemctl try-restart tailscaled.service >/dev/null 2>&1 || : -fi +# $1 == 0 for uninstallation.
+# $1 == 1 for removing old package during upgrade.
+
+systemctl daemon-reload >/dev/null 2>&1 || :
+if [ $1 -ge 1 ] ; then
+ # Package upgrade, not uninstall
+ systemctl try-restart tailscaled.service >/dev/null 2>&1 || :
+fi
diff --git a/release/rpm/rpm.prerm.sh b/release/rpm/rpm.prerm.sh index 682c01bd5..eeabf3b58 100755 --- a/release/rpm/rpm.prerm.sh +++ b/release/rpm/rpm.prerm.sh @@ -1,8 +1,8 @@ -# $1 == 0 for uninstallation. -# $1 == 1 for removing old package during upgrade. - -if [ $1 -eq 0 ] ; then - # Package removal, not upgrade - systemctl --no-reload disable tailscaled.service > /dev/null 2>&1 || : - systemctl stop tailscaled.service > /dev/null 2>&1 || : -fi +# $1 == 0 for uninstallation.
+# $1 == 1 for removing old package during upgrade.
+
+if [ $1 -eq 0 ] ; then
+ # Package removal, not upgrade
+ systemctl --no-reload disable tailscaled.service > /dev/null 2>&1 || :
+ systemctl stop tailscaled.service > /dev/null 2>&1 || :
+fi
|
