diff options
| author | Claus Lensbøl <claus@tailscale.com> | 2025-08-07 11:51:15 -0400 |
|---|---|---|
| committer | GitHub <noreply@github.com> | 2025-08-07 11:51:15 -0400 |
| commit | 89954fbceb78a2ecff529166da66ebee614e4253 (patch) | |
| tree | 3910d821fe0743f6ca9dc41ca3dca7a4d4717c3a /client | |
| parent | 4666d4ca2af5885329a6546d14c890d08e65c82e (diff) | |
| download | tailscale-89954fbceb78a2ecff529166da66ebee614e4253.tar.xz tailscale-89954fbceb78a2ecff529166da66ebee614e4253.zip | |
client/systray: add startup script generator for systemd (#16801)
Updates #1708
Signed-off-by: Claus Lensbøl <claus@tailscale.com>
Diffstat (limited to 'client')
| -rw-r--r-- | client/systray/startup-creator.go | 76 | ||||
| -rw-r--r-- | client/systray/tailscale-systray.service | 10 |
2 files changed, 86 insertions, 0 deletions
diff --git a/client/systray/startup-creator.go b/client/systray/startup-creator.go new file mode 100644 index 000000000..cb354856d --- /dev/null +++ b/client/systray/startup-creator.go @@ -0,0 +1,76 @@ +// Copyright (c) Tailscale Inc & AUTHORS +// SPDX-License-Identifier: BSD-3-Clause + +//go:build cgo || !darwin + +// Package systray provides a minimal Tailscale systray application. +package systray + +import ( + "bufio" + "bytes" + _ "embed" + "fmt" + "os" + "os/exec" + "path/filepath" + "strings" +) + +//go:embed tailscale-systray.service +var embedSystemd string + +func InstallStartupScript(initSystem string) error { + switch initSystem { + case "systemd": + return installSystemd() + default: + return fmt.Errorf("unsupported init system '%s'", initSystem) + } +} + +func installSystemd() error { + // Find the path to tailscale, just in case it's not where the example file + // has it placed, and replace that before writing the file. + tailscaleBin, err := exec.LookPath("tailscale") + if err != nil { + return fmt.Errorf("failed to find tailscale binary %w", err) + } + + var output bytes.Buffer + scanner := bufio.NewScanner(strings.NewReader(embedSystemd)) + for scanner.Scan() { + line := scanner.Text() + if strings.HasPrefix(line, "ExecStart=") { + line = fmt.Sprintf("ExecStart=%s systray", tailscaleBin) + } + output.WriteString(line + "\n") + } + + configDir, err := os.UserConfigDir() + if err != nil { + homeDir, err := os.UserHomeDir() + if err != nil { + return fmt.Errorf("unable to locate user home: %w", err) + } + configDir = filepath.Join(homeDir, ".config") + } + + systemdDir := filepath.Join(configDir, "systemd", "user") + if err := os.MkdirAll(systemdDir, 0o755); err != nil { + return fmt.Errorf("failed creating systemd uuser dir: %w", err) + } + + serviceFile := filepath.Join(systemdDir, "tailscale-systray.service") + + if err := os.WriteFile(serviceFile, output.Bytes(), 0o755); err != nil { + return fmt.Errorf("failed writing systemd user service: %w", err) + } + + fmt.Printf("Successfully installed systemd service to: %s\n", serviceFile) + fmt.Println("To enable and start the service, run:") + fmt.Println(" systemctl --user daemon-reload") + fmt.Println(" systemctl --user enable --now tailscale-systray") + + return nil +} diff --git a/client/systray/tailscale-systray.service b/client/systray/tailscale-systray.service new file mode 100644 index 000000000..a4d987563 --- /dev/null +++ b/client/systray/tailscale-systray.service @@ -0,0 +1,10 @@ +[Unit] +Description=Tailscale System Tray +After=systemd.service + +[Service] +Type=simple +ExecStart=/usr/bin/tailscale systray + +[Install] +WantedBy=default.target |
