mirror of
https://github.com/tailscale/tailscale.git
synced 2024-12-01 22:15:51 +00:00
1db46919ab
Due to a bug in Go (golang/go#51778), cmd/go doesn't warn about your Go version being older than the go.mod's declared Go version in that case that package loading fails before the build starts, such as when you use packages that are only in the current version of Go, like our use of net/netip. This change works around that Go bug by adding build tags and a pre-Go1.18-only file that will cause Go 1.17 and earlier to fail like: $ ~/sdk/go1.17/bin/go install ./cmd/tailscaled # tailscale.com/cmd/tailscaled ./required_version.go:11:2: undefined: you_need_Go_1_18_to_compile_Tailscale note: module requires Go 1.18 Change-Id: I39f5820de646703e19dde448dd86a7022252f75c Signed-off-by: Brad Fitzpatrick <bradfitz@tailscale.com>
159 lines
3.6 KiB
Go
159 lines
3.6 KiB
Go
// Copyright (c) 2021 Tailscale Inc & AUTHORS All rights reserved.
|
|
// Use of this source code is governed by a BSD-style
|
|
// license that can be found in the LICENSE file.
|
|
|
|
//go:build go1.18
|
|
// +build go1.18
|
|
|
|
package main
|
|
|
|
import (
|
|
"errors"
|
|
"fmt"
|
|
"io"
|
|
"io/ioutil"
|
|
"os"
|
|
"os/exec"
|
|
"path/filepath"
|
|
)
|
|
|
|
func init() {
|
|
installSystemDaemon = installSystemDaemonDarwin
|
|
uninstallSystemDaemon = uninstallSystemDaemonDarwin
|
|
}
|
|
|
|
// darwinLaunchdPlist is the launchd.plist that's written to
|
|
// /Library/LaunchDaemons/com.tailscale.tailscaled.plist or (in the
|
|
// future) a user-specific location.
|
|
//
|
|
// See man launchd.plist.
|
|
const darwinLaunchdPlist = `
|
|
<?xml version="1.0" encoding="UTF-8"?>
|
|
<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
|
|
<plist version="1.0">
|
|
<dict>
|
|
|
|
<key>Label</key>
|
|
<string>com.tailscale.tailscaled</string>
|
|
|
|
<key>ProgramArguments</key>
|
|
<array>
|
|
<string>/usr/local/bin/tailscaled</string>
|
|
</array>
|
|
|
|
<key>RunAtLoad</key>
|
|
<true/>
|
|
|
|
</dict>
|
|
</plist>
|
|
`
|
|
|
|
const sysPlist = "/Library/LaunchDaemons/com.tailscale.tailscaled.plist"
|
|
const targetBin = "/usr/local/bin/tailscaled"
|
|
const service = "com.tailscale.tailscaled"
|
|
|
|
func uninstallSystemDaemonDarwin(args []string) (ret error) {
|
|
if len(args) > 0 {
|
|
return errors.New("uninstall subcommand takes no arguments")
|
|
}
|
|
|
|
plist, err := exec.Command("launchctl", "list", "com.tailscale.tailscaled").Output()
|
|
_ = plist // parse it? https://github.com/DHowett/go-plist if we need something.
|
|
running := err == nil
|
|
|
|
if running {
|
|
out, err := exec.Command("launchctl", "stop", "com.tailscale.tailscaled").CombinedOutput()
|
|
if err != nil {
|
|
fmt.Printf("launchctl stop com.tailscale.tailscaled: %v, %s\n", err, out)
|
|
ret = err
|
|
}
|
|
out, err = exec.Command("launchctl", "unload", sysPlist).CombinedOutput()
|
|
if err != nil {
|
|
fmt.Printf("launchctl unload %s: %v, %s\n", sysPlist, err, out)
|
|
if ret == nil {
|
|
ret = err
|
|
}
|
|
}
|
|
}
|
|
|
|
if err := os.Remove(sysPlist); err != nil {
|
|
if os.IsNotExist(err) {
|
|
err = nil
|
|
}
|
|
if ret == nil {
|
|
ret = err
|
|
}
|
|
}
|
|
if err := os.Remove(targetBin); err != nil {
|
|
if os.IsNotExist(err) {
|
|
err = nil
|
|
}
|
|
if ret == nil {
|
|
ret = err
|
|
}
|
|
}
|
|
return ret
|
|
}
|
|
|
|
func installSystemDaemonDarwin(args []string) (err error) {
|
|
if len(args) > 0 {
|
|
return errors.New("install subcommand takes no arguments")
|
|
}
|
|
defer func() {
|
|
if err != nil && os.Getuid() != 0 {
|
|
err = fmt.Errorf("%w; try running tailscaled with sudo", err)
|
|
}
|
|
}()
|
|
|
|
// Best effort:
|
|
uninstallSystemDaemonDarwin(nil)
|
|
|
|
// Copy ourselves to /usr/local/bin/tailscaled.
|
|
if err := os.MkdirAll(filepath.Dir(targetBin), 0755); err != nil {
|
|
return err
|
|
}
|
|
exe, err := os.Executable()
|
|
if err != nil {
|
|
return fmt.Errorf("failed to find our own executable path: %w", err)
|
|
}
|
|
tmpBin := targetBin + ".tmp"
|
|
f, err := os.Create(tmpBin)
|
|
if err != nil {
|
|
return err
|
|
}
|
|
self, err := os.Open(exe)
|
|
if err != nil {
|
|
f.Close()
|
|
return err
|
|
}
|
|
_, err = io.Copy(f, self)
|
|
self.Close()
|
|
if err != nil {
|
|
f.Close()
|
|
return err
|
|
}
|
|
if err := f.Close(); err != nil {
|
|
return err
|
|
}
|
|
if err := os.Chmod(tmpBin, 0755); err != nil {
|
|
return err
|
|
}
|
|
if err := os.Rename(tmpBin, targetBin); err != nil {
|
|
return err
|
|
}
|
|
|
|
if err := ioutil.WriteFile(sysPlist, []byte(darwinLaunchdPlist), 0700); err != nil {
|
|
return err
|
|
}
|
|
|
|
if out, err := exec.Command("launchctl", "load", sysPlist).CombinedOutput(); err != nil {
|
|
return fmt.Errorf("error running launchctl load %s: %v, %s", sysPlist, err, out)
|
|
}
|
|
|
|
if out, err := exec.Command("launchctl", "start", service).CombinedOutput(); err != nil {
|
|
return fmt.Errorf("error running launchctl start %s: %v, %s", service, err, out)
|
|
}
|
|
|
|
return nil
|
|
}
|