Compare commits

...

6 Commits

Author SHA1 Message Date
Mike Kramlich 9d3cb8780f brew: added TODO; revised README; added to formula caveats and test
Several tweaks:
  * added correct 'services start' msg via formula caveats method added
  * added 'tailscaled -version' to formula test block
  * added TODO file, extracted from author's private Tailscale brew TODO notes
  * added more brew notes to README

Signed-off-by: Mike Kramlich <groglogic@gmail.com>
2021-02-27 11:31:34 -07:00
Mike Kramlich 06116b566e build_dist.sh: added comment on Homebrew version consistency
Signed-off-by: Mike Kramlich <groglogic@gmail.com>
2021-02-26 12:30:01 -07:00
Mike Kramlich ed0080eac5 brew: formulae audits clean, restored (it required only refactors)
WIP

Signed-off-by: Mike Kramlich <groglogic@gmail.com>
2021-02-26 12:05:54 -07:00
Mike Kramlich 63e4034211 brew/README: changed branch of preview from mkramlich/macos-brew to mkramlich/macos-brew2
WIP

Signed-off-by: Mike Kramlich <groglogic@gmail.com>
2021-02-26 10:59:39 -07:00
Mike Kramlich 7c16062a53 brew: formula go builds embed version props into the tailscale{d} exes
it is now done correctly, and is exactly compatible to build_dist.sh

(WIP)

Signed-off-by: Mike Kramlich <groglogic@gmail.com>
2021-02-25 17:29:49 -07:00
Mike Kramlich d2eeba5adb Homebrew packaging of the non-IPNExtension, unsandboxed tailscale{d} releases for macOS/darwin.
So the public can "brew install" tailscale and start it as a global boot daemon via brew services.

supported: Homebrew 3.0, go1.15 darwin/amd64, macOS Catalina 10.15.3, Intel 64-bit
probably also but unconfirmed: BigSur 11 and Apple M1 ARM64

NOTE: lots of upgrades and polish since 1st squashed WIP PR, and applies most prior feedback

Part of #177. (WIP)

Signed-off-by: Mike Kramlich <groglogic@gmail.com>
2021-02-24 02:09:39 -07:00
21 changed files with 1062 additions and 1 deletions

35
TODO 100644
View File

@ -0,0 +1,35 @@
TODO for Tailscale Mac Homebrew
This is a grab bag of ideas, issues, tasks, bugs and upgrades.
Ordered starting roughly with the most important or ideally next.
Not rigorous. Not limited to it. Subjective. Revised as we go.
-----------------------------------------------------------------
( ) in formula set version tag value properly
( ) in formula test block, assert versions reported by running installed tailscale{d} match expected
( ) in formula after built or installed, calc "shasum -a256" of the tailscale{d} and print it. helpful for security conscious folks afterward to ensure the binaries have not changed when unexpected (since they provide a VPN and run as root)
( ) for the tarball variants (most especially for tb-github), define the tarball's expected sha256 (the "want") in the proper way; dl-tarball-sha.sh uses only a placeholder technique for WIP
( ) correct or suppress this (default and automatic?) message by brew during install, because sudo required:
To have launchd start tailscale now and restart at login:
brew services start tailscale
( ) make scripts learn what tun value was picked by tailscaled (likely utun<NUM>)
(X) added correct message via formula caveat:
To have launchd start tailscale now and restart at boot:
sudo brew services start tailscale
( ) write/confirm test after reboot
( ) README: make it clear this is not an official/company Tailscale package
( ) retest the tarball versions, make sure they work right; esp the version stuff
( ) tailcfg Hostinfo.Package: control/controlclient/direct.go packageType(): either inject an ENVVAR, or have it decide by exe/path?
( ) fix that 1.5-vs-1.4.4 FIXME bug in the "global, tb-github" test case in install* (after log msg "checking exe location and diffs...")
( ) shrink the gap to ideal minimum (via refactors anywhere) between our formulae plists and Brad's daemon install plist, the latter being in: cmd/tailscaled/install_darwin.go
( ) ideally eliminate all TODOs from formula and scripts and README; or, just remove/satisfy as many as you can soon in upcoming sessions
( ) can pass extra args at brew install time, and inside your formula they are readable from ARGV.value. BEST/ONLY if they become stable/perm -- embedded in the installed-for-launchd-plist version
( ) print log location by formula when brew installed (ideally also the state file, sock and utun); via caveats method?
( ) discuss paths in README
( ) document or automate-away the $PWD path assumption deviance issue in make-test-source-tarball.sh
( ) stop script: TODO the installed plist is gone?
( ) stop script: TODO wipeout brew git checkout cache and/or add test for with-vs-without
( ) has the master-vs-main bug come back? since I twiddle the tag/branch/head stuff in formula to fix that other bug
( ) add test variants for other brew tool versions?
( ) in future: think about documenting the plist EnvironmentVariables key, as a way for user to set Tailscale-specific ENVVARS for tailscaled to read (like for debugging or testing)
( ) in future: maybe maybe play with the plist's ProcessType key, as a way to tune cpu/io and battery use

1
brew/.gitignore vendored 100644
View File

@ -0,0 +1 @@
local/

102
brew/README.md 100644
View File

@ -0,0 +1,102 @@
# Tailscale Mac Homebrew Maintainer Guide
***********
*** WIP ***
***********
Homebrew packaging of the non-IPNExtension, unsandboxed tailscale{d} releases for macOS/darwin.
So the public can "brew install" tailscale and start it as a global boot daemon via brew services.
## Platforms Supported
These platform versions and permutations have been tested and are known to work well:
| role | brew | golang | os | arch | repo |
| ----------- | --------------------------- | --------------------- | ---------------------- | ------------------ | ---------- |
| maintainer: | Homebrew 3.0.1-120-g5ca03ab | go1.15.8 darwin/amd64 | macOS Catalina 10.15.3 | Intel 64-bit | |
| | w/ ruby 2.6.3p62 | | macOS Big Sur 11.x (?) | Apple M1 ARM64 (?) | |
| | | | | | |
| | | | | | |
| pkg target: | Homebrew 3.0.1-120-g5ca03ab | go1.15.8 darwin/amd64 | macOS Catalina 10.15.3 | Intel 64-bit | tailscale: |
| | w/ ruby 2.6.3p62 | | macOS Big Sur 11.x (?) | Apple M1 ARM64 (?) | 188bb14269 |
| | | | | | HEAD |
| | | | | | likely 1.5 |
## Directory Contents
| type | name | purpose |
| ------------------ | ---------------------------- | -------------------------------------------------------------- |
| formulae | tailscale.rb | The default packaging "formula" in Ruby, based on a |
| | | a pinned commit from the tailscale/tailscale GitHub repo |
| | | |
| | tailscale.*.rb | Alternate formulae (mainly used for testing now, |
| | | and includes some variants based on tagged release source |
| | | tarballs, and local test standin candidates) |
| | | |
| maintainer scripts | vars.sh | role for brew like version/version.sh for build_dist.sh |
| | generate-formulae.sh | regenerates all formulae (default, plus some alternates) |
| | generate-formula.sh | generates formula from an embedded template, to stdout |
| | make-test-source-tarball.sh | |
| | serve-tarball.sh | |
| | dl-tarball-sha.sh | |
| | test.sh | tests all supported permutations |
| | install-start-with-checks.sh | install test run for maintainer |
| | up.sh | |
| | status.sh | |
| | stop-uninstall-wipe.sh | closing counterpart to the install*.sh script |
| | search-interesting.sh | nice to keep these on maintainer's radar |
| | | |
| subdirs | brew/local/ | .gitignored tree created and used during brew maintenance work |
## Use Cases
For the ultimate endusers (ONLY ONCE READY & AVAIL)...
```
brew install tailscale
sudo brew services start tailscale
```
TODO(mkramlich): add context, details, variants to the above
For an early adopter who wants to try an unofficial sneak preview of a local brew install of the WIP formula:
```
git clone https://github.com/mkramlich/tailscale
cd tailscale
git switch mkramlich/macos-brew2
brew install --formula brew/tailscale.rb # default formula draws from a recent good commit from tailscale/tailscale
sudo brew services start tailscale
# tailscaled is now running and registered as a global boot daemon (via launchctl/launchd)
brew/up.sh # then do your auth
# tailscaled is now authorized and providing normal service to your VPN
```
For maintainers...
All scripts assume you are in the cloned repo root, just above brew/
(EXCEPT make-test-source-tarball.sh, TODO)
To edit the formula source, regen and retest:
```
# modify the template fragments inside generate-formula.sh
# and/or the var values in brew/vars.sh or brew/generate-formulae.sh
brew/generate-formulae.sh
brew/serve-tarball.sh # ensure running in background; only needed for the local source tarball test in test.sh
brew/test.sh # this is very WIP, but generally the goal is if it exits 0 then the tests are green
```
A brew audit of a formula candidate can fail and its possible for it to 'brew install' and tailscale start successfully. A clean brew audit is only required (or strongly recommended) for submission to the Homebrew Core repository.
A "clean" brew doctor on the maintainer's host is not required, but its helpful to ensure no unnecessary problems arise with brew testing downstream. And helps ensure that no quirks of the maintainer's host cause the formula to "works on my box!" but then fail on other's machines. Majority of issues it reports will have no impact, but ideally it should be kept silent and exit 0.
A quirk of brew is that it likes to autoupdate under the hood, in reaction to (and not strictly needed to carry out) the user's express commands. This can cause unexpected delays (especially if bandwidth is your bottleneck) during package maintainer testing workflows. And makes it a challenge to achieve perfectly strict idempotency and deterministic installs. It appears to be a known trade-off call made by the Homebrew tool devs.
TODO(mkramlich): flesh out much further; topics: formula vs bottle, sudo vs not, prefix diffs, local vs public ts tap vs core, testing, submission and bumping

View File

@ -0,0 +1,10 @@
#!/usr/bin/env sh
set -eu
eval $(brew/vars.sh)
#URLBASE=https://github.com
URLBASE=http://localhost
TARBALL=v$TS_VER.tar.gz
curl -OL $URLBASE/tailscale/tailscale/archive/$TARBALL
shasum -a256 ./$TARBALL # TODO(mkramlich): not the proper point in lifecycle to calc this

View File

@ -0,0 +1,132 @@
#!/usr/bin/env sh
#set -u # TODO(mkramlich): recreate
# TODO(mkramlich): in form where the url is a .git, the url can also have a tag arg, like: tag: "v1.5.0"
cat <<TEMPLATE
# typed: false
# frozen_string_literal: true
# Homebrew formula for Tailscale
class Tailscale < Formula
desc "Easiest, secure, crossplatform WireGuard Go-based VPN w/oauth2, 2FA/SSO"
homepage "https://www.tailscale.com"
TEMPLATE
if [ "$FORMULA_TYPE" = "tarball" ]; then
cat <<TEMPLATE2
url "$URL"
sha256 "$SHA256"
TEMPLATE2
elif [ "$FORMULA_TYPE" = "commit" ]; then
cat <<TEMPLATE3
url "$URL",
revision: "$REVISION"
version "$VERSION" # TODO(mkramlich): WIP, so not necessarily; brew required a version
TEMPLATE3
else
exit 1
fi
cat <<TEMPLATE4
license "BSD-3-Clause"
head "$HEAD",
branch: "$BRANCH"
depends_on "go" => :build
def install
ENV["GOPATH"] = buildpath
tailscale_path = buildpath/"src/github.com/tailscale/tailscale"
tailscale_path.install buildpath.children
cd tailscale_path do
# build the exes with version strings equiv to the tailscale repo's build_dist.sh:
ldflags = prepare_ldflags
system "go", "build", "-o", ".", "-tags", "xversion", "-ldflags", ldflags, "tailscale.com/cmd/tailscale"
system "go", "build", "-o", ".", "-tags", "xversion", "-ldflags", ldflags, "tailscale.com/cmd/tailscaled"
bin.install "tailscale"
bin.install "tailscaled"
end
end
def prepare_ldflags
ver_props = prepare_ver_props
vl = ver_props["VERSION_LONG"]
vs = ver_props["VERSION_SHORT"]
vgh = ver_props["VERSION_GIT_HASH"]
vl = "tailscale.com/version.Long=#{vl}"
vs = "tailscale.com/version.Short=#{vs}"
vgh = "tailscale.com/version.GitCommit=#{vgh}"
"-X #{vl} -X #{vs} -X #{vgh}"
end
def prepare_ver_props
distvers = Utils.safe_popen_read("./version/version.sh")
lines = distvers.split("\n")
ver_props = {}
lines.each do |line|
parts = line.split("=")
key = parts.at(0)
val = parts.at(1).delete('"') # cuz version.sh emits each prop with double-quotes enclosing each val
# system "echo adding to ver_props for go builds: key #{key}, val #{val}"
ver_props[key] = val
end
ver_props
end
def post_install
(var/"run/tailscale").mkpath
(var/"lib/tailscale").mkpath
end
def caveats
<<~EOS
To have launchd start tailscale now and restart at boot:
sudo brew services start tailscale
NOTE: The caveat message below with 'restart at login' is incorrect, but we can't suppress it. Requires sudo.
EOS
end
plist_options manual: "sudo tailscaled --socket=#{HOMEBREW_PREFIX}/run/tailscale/tailscaled.sock --state=#{HOMEBREW_PREFIX}/lib/tailscale/tailscaled.state"
def plist
<<~EOS
<?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>KeepAlive</key>
<dict>
<key>SuccessfulExit</key>
<false/>
<key>NetworkState</key>
<true/>
</dict>
<key>Label</key>
<string>#{plist_name}</string>
<key>ProgramArguments</key>
<array>
<string>#{opt_bin}/tailscaled</string>
<string>--socket=#{var}/run/tailscale/tailscaled.sock</string>
<string>--state=#{var}/lib/tailscale/tailscaled.state</string>
</array>
<key>RunAtLoad</key>
<true/>
<key>WorkingDirectory</key>
<string>#{var}/lib/tailscale</string>
<key>StandardErrorPath</key>
<string>#{var}/log/tailscale/tailscaled-stderr.log</string>
<key>StandardOutPath</key>
<string>#{var}/log/tailscale/tailscaled-stdout.log</string>
</dict>
</plist>
EOS
end
test do
system bin/"tailscale", "version"
system bin/"tailscaled", "-version"
system bin/"tailscale", "netcheck"
end
end
TEMPLATE4

View File

@ -0,0 +1,19 @@
#!/usr/bin/env sh
set -eu
eval $(brew/vars.sh)
GIT_URL=https://github.com/tailscale/tailscale.git
BRANCH=main
VERSION=$TS_VER # TODO(mkramlich): WIP. do this right
# default formula (pinned against a commmit in the Tailscale GitHub repo)
FORMULA_TYPE=commit URL=$GIT_URL BRANCH=$BRANCH REVISION=$TS_COMMIT_PIN HEAD=$GIT_URL BRANCH=$BRANCH VERSION=$VERSION brew/generate-formula.sh > brew/tailscale.commit-pin.rb
# alt formula using local HTTP source tarball of a release standin/mock
FORMULA_TYPE=tarball URL="http://localhost:$TS_TARBALL_PORT/tailscale/tailscale/archive/v1.5.0.tar.gz" SHA256="a62caf2eb5c84d2d1775cd8a17eeb0e8ad3b8dbc9453399862d908227e0af721" HEAD=$GIT_URL BRANCH=$BRANCH VERSION=$VERSION brew/generate-formula.sh > brew/tailscale.tb-local.rb
# alt formula using Tailscale GitHub HTTPS source tarball of a release tag -- the LATEST tag
FORMULA_TYPE=tarball URL="https://github.com/tailscale/tailscale/archive/v1.4.4.tar.gz" SHA256="5312c6d075a32049912e0932a89269869def9ac8ea9d0fdccc6b41db60fc2d4c" HEAD=$GIT_URL BRANCH=$BRANCH VERSION=$VERSION brew/generate-formula.sh > brew/tailscale.tb-github.rb
cp brew/tailscale{.commit-pin,}.rb

View File

@ -0,0 +1,100 @@
#!/usr/bin/env sh
set -eu
eval $(brew/vars.sh)
echo
echo SUDO is $SUDO
echo
echo versions...
brew --version
brew config
go version
echo maintainer VERSION.txt: `cat VERSION.TXT`
echo maintainer script version/version.sh exec:
version/version.sh # we don't truly use this (yet?), just print here as helpful info for later analysis
# TODO(mkramlich) make distinction clear between maintainer script source ver and target package vers
echo
echo brew doctor...
set +e # to turn -e off (relax this only for time being)
brew doctor # TODO(mkramlich): for brew maintainer, best if have no findings and exit 0
set -e # to turn back on
echo
echo audit formula...
# requires Internet access for some audit checks:
brew audit --strict --online --formula $TS_FORMULA # keep this run exit 0 (NOTE: Homebrew can be noisy if updates)
echo
echo installing...
#brew install -v --build-from-source $TS_FORMULA
brew install -v --formula $TS_FORMULA
echo
echo checking exe location and diffs...
diff $TS_BIN/tailscale $TS_CELLAR/$TS_VER/bin/tailscale # TODO(mkramlich): FIXME in test case global,tb-github; want 1.5.0, got 1.4.4, SHOULD want 1.4.4 cuz 1.4.4 correct
diff $TS_BIN/tailscaled $TS_CELLAR/$TS_VER/bin/tailscaled
echo
echo check if brew has formula...
brew list tailscale
echo
echo check if installed formula matches orig...
diff $TS_FORMULA $TS_CELLAR/$TS_VER/.$TS_FORMULA
echo
echo lint of the generated launchctl plist for homebrew tailscale...
# should print "<filepath>: OK" and exit 0; brew services (or launchctl) below
# might reject (or silently allow) any given !0 case so better to catch an issue
# early/wider than not, and automate extra clues for maintainer
plutil -lint $TS_CELLAR/$TS_VER/$TS_PLIST
echo
echo brew test before starting...
brew test $TS_FORMULA
echo
echo starting...
$SUDO brew services start tailscale
echo
echo pausing as tailscaled starts...
sleep 8
echo
echo checking that our registered Global Daemons plist matches expected...
diff $TS_CELLAR/$TS_VER/$TS_PLIST $INSTALLED_PLIST_DIR/$TS_PLIST
echo
echo brew service shows tailscale as started...
$SUDO brew services list | grep tailscale
echo
echo launchctl lists tailscale...
$SUDO launchctl list | grep tailscale
echo
echo tailscale version...
$TS_BIN/tailscale --version # should be found, executable and exit 0
echo
echo tailscale netcheck...
$TS_BIN/tailscale netcheck # should be found, executable and exit 0
echo
echo tailscale up \(and wait for human to do the auth dance if needed\)...
brew/up.sh # this will block, displaying the auth url, if it needs to auth. then/or proceed once happy
echo
echo list all tailscale files installed or generated...
$SUDO find $BREW | grep -i tailscale
echo
echo pausing to give tailscaled enough time to finish post-auth setup...
sleep 15 # otherwise some of my early status pings sometimes fail (esp hello.ipn.dev; then work on all subsequent attempts)
echo
echo status...
brew/status.sh

View File

@ -0,0 +1,17 @@
#!/usr/bin/env sh
set -eu
# does not create an official release source tarball per GitHub. creates a standin for it, for brew test purposes only
eval $(tailscale/brew/vars.sh) # TODO(mkramlich): doc the path deviance or automate away
TARBALL_ARCHIVE=tailscale/brew/local/tarball-serve-root/tailscale/tailscale/archive
mkdir -p $TARBALL_ARCHIVE
TARBALL=$TARBALL_ARCHIVE/v$TS_VER.tar.gz
# assume a repo is cloned at that dir tree location, and its file state is what we want
echo making $TARBALL
tar -czf $TARBALL tailscale-$TS_VER/.gitignore tailscale-$TS_VER/.github/* tailscale-$TS_VER/.gitattributes tailscale-$TS_VER/*
shasum -a256 ./$TARBALL

View File

@ -0,0 +1,6 @@
#!/usr/bin/env sh
brew search tailscale
brew search wireguard
brew search vpn
brew search golang

View File

@ -0,0 +1,14 @@
#!/usr/bin/env sh
set -eu
# only for Tailscale brew maintainer, to local-only serve a source tarball standin, during brew testing
eval $(brew/vars.sh)
python3 -m http.server --directory brew/local/tarball-serve-root --bind localhost $TS_TARBALL_PORT
# why the above? during one formula/release test brew may expect to fetch a tarball from (w/version varying):
# http://localhost:$TS_TARBALL_PORT/tailscale/tailscale/archive/v$TS_VER.tar.gz
# where $TS_VER is like 1.5.0
# therefore under tarball-serve-root/ that file should be in:
# tailscale/tailscale/archive/

83
brew/status.sh 100755
View File

@ -0,0 +1,83 @@
#!/usr/bin/env sh
set -u
eval $(brew/vars.sh)
# everything you see below is not expected to be rigorous, or decisive or even always relevant,
# but gives useful data and a nice smoke test of a candidate install for the brew maintainer
echo file checks \(exes, state, socket\)...
ls -la $TS_BIN/tailscale*
ls -l $TS_STATE
ls -l $TS_SOCK
echo
$TS_BIN/tailscale version
echo
$TS_BIN/tailscale netcheck
echo
echo tailscale status:
sudo $TS_BIN/tailscale -socket=$TS_SOCK status
echo
ifconfig -r en0
# TODO(mkramlich): learn the utun<NUM> it picked and handle tun/gateway right everywhere below
echo
ifconfig -r utun5
echo Routing\\n
echo \(Destination Gateway Flags Netif Expire\):
netstat -r -n -f inet | grep utun
echo IPv4 routes:
netstat -r -n -f inet -ll
echo IPv4 route stats:
netstat -r -n -f inet -s
echo IPv6 routes:
netstat -r -n -f inet6 -ll
echo IPv6 route stats:
netstat -r -n -f inet6 -s
echo
echo checking if host IP forwarding is enabled...
sysctl -a | grep forward
echo
echo pinging the TS login/coord server...
ping -c1 login.tailscale.com # only to help rule out other issues during a brew test
echo
echo pinging the TS log server...
ping -c1 log.tailscale.io
echo
echo pinging the common hello node by name...
ping -c1 hello.ipn.dev # a nice smoke test
echo ... by tailscale ping DNS...
sudo $TS_BIN/tailscale -socket=$TS_SOCK ping -c 1 hello.ipn.dev
echo ... by ping IPv4...
ping -c1 100.101.102.103
echo ... by tailscale ping IPv4...
sudo $TS_BIN/tailscale -socket=$TS_SOCK ping -c 1 100.101.102.103
echo ... by ping6 IPv6...
ping6 -c1 fd7a:115c:a1e0:ab12:4843:cd96:6265:6667 # TODO(mkramlich): do right or drop
# TODO(mkramlich): below is personal node Ts addr, so either drop or make overridable by maintainer
echo
echo pinging my android node...
ping -c1 100.119.147.125
sudo $TS_BIN/tailscale -socket=$TS_SOCK ping -c 1 100.119.147.125
ping6 -c1 fd7a:115c:a1e0:ab12:4843:cd96:6277:937d
echo
echo check stderr log for any recent error, warn, fail, missing or weird...
# NOTE we dont do a 'set -e' style fail assert on this error log tail here because this is for human consumption,
# plus, not quite sure/ready about what specifc messages are scary enough to potentially fail a test
#sudo grep -i -e error -e warn -e fail -e missing -e weird $TS_LOG_DIR/tailscaled-stderr.log
sudo tail -100 $TS_LOG_DIR/tailscaled-stderr.log | grep -i -e error -e warn -e fail -e missing -e weird

View File

@ -0,0 +1,33 @@
#!/usr/bin/env sh
set -u # also -e?
eval $(brew/vars.sh)
echo
echo SUDO is $SUDO
echo
echo stopping...
$SUDO brew services stop tailscale
$SUDO brew services list | grep tailscale
ps -ef | grep tailscaled | grep -v "grep tailscaled" # TODO(mkramlich): do better
# TODO(mkramlich): the installed plist is gone?
echo
echo uninstalling...
brew uninstall --force tailscale
$SUDO brew services list | grep tailscale
echo
echo deleting...
$SUDO rm -rf $TS_CELLAR/$TS_VER
$SUDO rm -f $BREW/var/lib/tailscale/*
$SUDO rm -f $TS_LOG_DIR/*
rmdir $BREW/var/lib/tailscale
rmdir $TS_LOG_DIR
rmdir $BREW/var/run/tailscale
rm $BREW/opt/tailscale # was symlink to $TS_CELLAR/$TS_VER
rmdir $TS_CELLAR
find $BREW | grep -i tailscale
find /opt | grep -i tailscale
# TODO(mkramlich): wipeout brew git checkout cache and/or add test for with-vs-without

View File

@ -0,0 +1,110 @@
# typed: false
# frozen_string_literal: true
# Homebrew formula for Tailscale
class Tailscale < Formula
desc "Easiest, secure, crossplatform WireGuard Go-based VPN w/oauth2, 2FA/SSO"
homepage "https://www.tailscale.com"
url "https://github.com/tailscale/tailscale.git",
revision: "188bb142691c8b97673a9cb2aebd9f1521e9bb12"
version "1.5.0" # TODO(mkramlich): WIP, so not necessarily; brew required a version
license "BSD-3-Clause"
head "https://github.com/tailscale/tailscale.git",
branch: "main"
depends_on "go" => :build
def install
ENV["GOPATH"] = buildpath
tailscale_path = buildpath/"src/github.com/tailscale/tailscale"
tailscale_path.install buildpath.children
cd tailscale_path do
# build the exes with version strings equiv to the tailscale repo's build_dist.sh:
ldflags = prepare_ldflags
system "go", "build", "-o", ".", "-tags", "xversion", "-ldflags", ldflags, "tailscale.com/cmd/tailscale"
system "go", "build", "-o", ".", "-tags", "xversion", "-ldflags", ldflags, "tailscale.com/cmd/tailscaled"
bin.install "tailscale"
bin.install "tailscaled"
end
end
def prepare_ldflags
ver_props = prepare_ver_props
vl = ver_props["VERSION_LONG"]
vs = ver_props["VERSION_SHORT"]
vgh = ver_props["VERSION_GIT_HASH"]
vl = "tailscale.com/version.Long=#{vl}"
vs = "tailscale.com/version.Short=#{vs}"
vgh = "tailscale.com/version.GitCommit=#{vgh}"
"-X #{vl} -X #{vs} -X #{vgh}"
end
def prepare_ver_props
distvers = Utils.safe_popen_read("./version/version.sh")
lines = distvers.split("\n")
ver_props = {}
lines.each do |line|
parts = line.split("=")
key = parts.at(0)
val = parts.at(1).delete('"') # cuz version.sh emits each prop with double-quotes enclosing each val
# system "echo adding to ver_props for go builds: key #{key}, val #{val}"
ver_props[key] = val
end
ver_props
end
def post_install
(var/"run/tailscale").mkpath
(var/"lib/tailscale").mkpath
end
def caveats
<<~EOS
To have launchd start tailscale now and restart at boot:
sudo brew services start tailscale
NOTE: The caveat message below with 'restart at login' is incorrect, but we can't suppress it. Requires sudo.
EOS
end
plist_options manual: "sudo tailscaled --socket=#{HOMEBREW_PREFIX}/run/tailscale/tailscaled.sock --state=#{HOMEBREW_PREFIX}/lib/tailscale/tailscaled.state"
def plist
<<~EOS
<?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>KeepAlive</key>
<dict>
<key>SuccessfulExit</key>
<false/>
<key>NetworkState</key>
<true/>
</dict>
<key>Label</key>
<string>#{plist_name}</string>
<key>ProgramArguments</key>
<array>
<string>#{opt_bin}/tailscaled</string>
<string>--socket=#{var}/run/tailscale/tailscaled.sock</string>
<string>--state=#{var}/lib/tailscale/tailscaled.state</string>
</array>
<key>RunAtLoad</key>
<true/>
<key>WorkingDirectory</key>
<string>#{var}/lib/tailscale</string>
<key>StandardErrorPath</key>
<string>#{var}/log/tailscale/tailscaled-stderr.log</string>
<key>StandardOutPath</key>
<string>#{var}/log/tailscale/tailscaled-stdout.log</string>
</dict>
</plist>
EOS
end
test do
system bin/"tailscale", "version"
system bin/"tailscaled", "-version"
system bin/"tailscale", "netcheck"
end
end

110
brew/tailscale.rb 100644
View File

@ -0,0 +1,110 @@
# typed: false
# frozen_string_literal: true
# Homebrew formula for Tailscale
class Tailscale < Formula
desc "Easiest, secure, crossplatform WireGuard Go-based VPN w/oauth2, 2FA/SSO"
homepage "https://www.tailscale.com"
url "https://github.com/tailscale/tailscale.git",
revision: "188bb142691c8b97673a9cb2aebd9f1521e9bb12"
version "1.5.0" # TODO(mkramlich): WIP, so not necessarily; brew required a version
license "BSD-3-Clause"
head "https://github.com/tailscale/tailscale.git",
branch: "main"
depends_on "go" => :build
def install
ENV["GOPATH"] = buildpath
tailscale_path = buildpath/"src/github.com/tailscale/tailscale"
tailscale_path.install buildpath.children
cd tailscale_path do
# build the exes with version strings equiv to the tailscale repo's build_dist.sh:
ldflags = prepare_ldflags
system "go", "build", "-o", ".", "-tags", "xversion", "-ldflags", ldflags, "tailscale.com/cmd/tailscale"
system "go", "build", "-o", ".", "-tags", "xversion", "-ldflags", ldflags, "tailscale.com/cmd/tailscaled"
bin.install "tailscale"
bin.install "tailscaled"
end
end
def prepare_ldflags
ver_props = prepare_ver_props
vl = ver_props["VERSION_LONG"]
vs = ver_props["VERSION_SHORT"]
vgh = ver_props["VERSION_GIT_HASH"]
vl = "tailscale.com/version.Long=#{vl}"
vs = "tailscale.com/version.Short=#{vs}"
vgh = "tailscale.com/version.GitCommit=#{vgh}"
"-X #{vl} -X #{vs} -X #{vgh}"
end
def prepare_ver_props
distvers = Utils.safe_popen_read("./version/version.sh")
lines = distvers.split("\n")
ver_props = {}
lines.each do |line|
parts = line.split("=")
key = parts.at(0)
val = parts.at(1).delete('"') # cuz version.sh emits each prop with double-quotes enclosing each val
# system "echo adding to ver_props for go builds: key #{key}, val #{val}"
ver_props[key] = val
end
ver_props
end
def post_install
(var/"run/tailscale").mkpath
(var/"lib/tailscale").mkpath
end
def caveats
<<~EOS
To have launchd start tailscale now and restart at boot:
sudo brew services start tailscale
NOTE: The caveat message below with 'restart at login' is incorrect, but we can't suppress it. Requires sudo.
EOS
end
plist_options manual: "sudo tailscaled --socket=#{HOMEBREW_PREFIX}/run/tailscale/tailscaled.sock --state=#{HOMEBREW_PREFIX}/lib/tailscale/tailscaled.state"
def plist
<<~EOS
<?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>KeepAlive</key>
<dict>
<key>SuccessfulExit</key>
<false/>
<key>NetworkState</key>
<true/>
</dict>
<key>Label</key>
<string>#{plist_name}</string>
<key>ProgramArguments</key>
<array>
<string>#{opt_bin}/tailscaled</string>
<string>--socket=#{var}/run/tailscale/tailscaled.sock</string>
<string>--state=#{var}/lib/tailscale/tailscaled.state</string>
</array>
<key>RunAtLoad</key>
<true/>
<key>WorkingDirectory</key>
<string>#{var}/lib/tailscale</string>
<key>StandardErrorPath</key>
<string>#{var}/log/tailscale/tailscaled-stderr.log</string>
<key>StandardOutPath</key>
<string>#{var}/log/tailscale/tailscaled-stdout.log</string>
</dict>
</plist>
EOS
end
test do
system bin/"tailscale", "version"
system bin/"tailscaled", "-version"
system bin/"tailscale", "netcheck"
end
end

View File

@ -0,0 +1,109 @@
# typed: false
# frozen_string_literal: true
# Homebrew formula for Tailscale
class Tailscale < Formula
desc "Easiest, secure, crossplatform WireGuard Go-based VPN w/oauth2, 2FA/SSO"
homepage "https://www.tailscale.com"
url "https://github.com/tailscale/tailscale/archive/v1.4.4.tar.gz"
sha256 "5312c6d075a32049912e0932a89269869def9ac8ea9d0fdccc6b41db60fc2d4c"
license "BSD-3-Clause"
head "https://github.com/tailscale/tailscale.git",
branch: "main"
depends_on "go" => :build
def install
ENV["GOPATH"] = buildpath
tailscale_path = buildpath/"src/github.com/tailscale/tailscale"
tailscale_path.install buildpath.children
cd tailscale_path do
# build the exes with version strings equiv to the tailscale repo's build_dist.sh:
ldflags = prepare_ldflags
system "go", "build", "-o", ".", "-tags", "xversion", "-ldflags", ldflags, "tailscale.com/cmd/tailscale"
system "go", "build", "-o", ".", "-tags", "xversion", "-ldflags", ldflags, "tailscale.com/cmd/tailscaled"
bin.install "tailscale"
bin.install "tailscaled"
end
end
def prepare_ldflags
ver_props = prepare_ver_props
vl = ver_props["VERSION_LONG"]
vs = ver_props["VERSION_SHORT"]
vgh = ver_props["VERSION_GIT_HASH"]
vl = "tailscale.com/version.Long=#{vl}"
vs = "tailscale.com/version.Short=#{vs}"
vgh = "tailscale.com/version.GitCommit=#{vgh}"
"-X #{vl} -X #{vs} -X #{vgh}"
end
def prepare_ver_props
distvers = Utils.safe_popen_read("./version/version.sh")
lines = distvers.split("\n")
ver_props = {}
lines.each do |line|
parts = line.split("=")
key = parts.at(0)
val = parts.at(1).delete('"') # cuz version.sh emits each prop with double-quotes enclosing each val
# system "echo adding to ver_props for go builds: key #{key}, val #{val}"
ver_props[key] = val
end
ver_props
end
def post_install
(var/"run/tailscale").mkpath
(var/"lib/tailscale").mkpath
end
def caveats
<<~EOS
To have launchd start tailscale now and restart at boot:
sudo brew services start tailscale
NOTE: The caveat message below with 'restart at login' is incorrect, but we can't suppress it. Requires sudo.
EOS
end
plist_options manual: "sudo tailscaled --socket=#{HOMEBREW_PREFIX}/run/tailscale/tailscaled.sock --state=#{HOMEBREW_PREFIX}/lib/tailscale/tailscaled.state"
def plist
<<~EOS
<?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>KeepAlive</key>
<dict>
<key>SuccessfulExit</key>
<false/>
<key>NetworkState</key>
<true/>
</dict>
<key>Label</key>
<string>#{plist_name}</string>
<key>ProgramArguments</key>
<array>
<string>#{opt_bin}/tailscaled</string>
<string>--socket=#{var}/run/tailscale/tailscaled.sock</string>
<string>--state=#{var}/lib/tailscale/tailscaled.state</string>
</array>
<key>RunAtLoad</key>
<true/>
<key>WorkingDirectory</key>
<string>#{var}/lib/tailscale</string>
<key>StandardErrorPath</key>
<string>#{var}/log/tailscale/tailscaled-stderr.log</string>
<key>StandardOutPath</key>
<string>#{var}/log/tailscale/tailscaled-stdout.log</string>
</dict>
</plist>
EOS
end
test do
system bin/"tailscale", "version"
system bin/"tailscaled", "-version"
system bin/"tailscale", "netcheck"
end
end

View File

@ -0,0 +1,109 @@
# typed: false
# frozen_string_literal: true
# Homebrew formula for Tailscale
class Tailscale < Formula
desc "Easiest, secure, crossplatform WireGuard Go-based VPN w/oauth2, 2FA/SSO"
homepage "https://www.tailscale.com"
url "http://localhost:8901/tailscale/tailscale/archive/v1.5.0.tar.gz"
sha256 "a62caf2eb5c84d2d1775cd8a17eeb0e8ad3b8dbc9453399862d908227e0af721"
license "BSD-3-Clause"
head "https://github.com/tailscale/tailscale.git",
branch: "main"
depends_on "go" => :build
def install
ENV["GOPATH"] = buildpath
tailscale_path = buildpath/"src/github.com/tailscale/tailscale"
tailscale_path.install buildpath.children
cd tailscale_path do
# build the exes with version strings equiv to the tailscale repo's build_dist.sh:
ldflags = prepare_ldflags
system "go", "build", "-o", ".", "-tags", "xversion", "-ldflags", ldflags, "tailscale.com/cmd/tailscale"
system "go", "build", "-o", ".", "-tags", "xversion", "-ldflags", ldflags, "tailscale.com/cmd/tailscaled"
bin.install "tailscale"
bin.install "tailscaled"
end
end
def prepare_ldflags
ver_props = prepare_ver_props
vl = ver_props["VERSION_LONG"]
vs = ver_props["VERSION_SHORT"]
vgh = ver_props["VERSION_GIT_HASH"]
vl = "tailscale.com/version.Long=#{vl}"
vs = "tailscale.com/version.Short=#{vs}"
vgh = "tailscale.com/version.GitCommit=#{vgh}"
"-X #{vl} -X #{vs} -X #{vgh}"
end
def prepare_ver_props
distvers = Utils.safe_popen_read("./version/version.sh")
lines = distvers.split("\n")
ver_props = {}
lines.each do |line|
parts = line.split("=")
key = parts.at(0)
val = parts.at(1).delete('"') # cuz version.sh emits each prop with double-quotes enclosing each val
# system "echo adding to ver_props for go builds: key #{key}, val #{val}"
ver_props[key] = val
end
ver_props
end
def post_install
(var/"run/tailscale").mkpath
(var/"lib/tailscale").mkpath
end
def caveats
<<~EOS
To have launchd start tailscale now and restart at boot:
sudo brew services start tailscale
NOTE: The caveat message below with 'restart at login' is incorrect, but we can't suppress it. Requires sudo.
EOS
end
plist_options manual: "sudo tailscaled --socket=#{HOMEBREW_PREFIX}/run/tailscale/tailscaled.sock --state=#{HOMEBREW_PREFIX}/lib/tailscale/tailscaled.state"
def plist
<<~EOS
<?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>KeepAlive</key>
<dict>
<key>SuccessfulExit</key>
<false/>
<key>NetworkState</key>
<true/>
</dict>
<key>Label</key>
<string>#{plist_name}</string>
<key>ProgramArguments</key>
<array>
<string>#{opt_bin}/tailscaled</string>
<string>--socket=#{var}/run/tailscale/tailscaled.sock</string>
<string>--state=#{var}/lib/tailscale/tailscaled.state</string>
</array>
<key>RunAtLoad</key>
<true/>
<key>WorkingDirectory</key>
<string>#{var}/lib/tailscale</string>
<key>StandardErrorPath</key>
<string>#{var}/log/tailscale/tailscaled-stderr.log</string>
<key>StandardOutPath</key>
<string>#{var}/log/tailscale/tailscaled-stdout.log</string>
</dict>
</plist>
EOS
end
test do
system bin/"tailscale", "version"
system bin/"tailscaled", "-version"
system bin/"tailscale", "netcheck"
end
end

39
brew/test.sh 100755
View File

@ -0,0 +1,39 @@
#!/usr/bin/env sh
set -eu
# TODO(mkramlich):
# dl-tarball-sha.sh
# make-test-source-tarball.sh
echo test variant: global, tb-local
#TODO(mkramlich): for the tb-local tests, server-tarball.sh should be running, with tarball in place
cp brew/tailscale{.tb-local,}.rb
# brew services (via launchd) start as a global boot daemon (in /Library/LaunchDaemons), running as root
# TODO(mkramlich): confirm at reboot starts & works
SUDO="sudo" INSTALLED_PLIST_DIR=/Library/LaunchDaemons brew/install-start-with-checks.sh
SUDO="sudo" INSTALLED_PLIST_DIR=/Library/LaunchDaemons brew/stop-uninstall-wipe.sh
echo test variant: global, tb-github
cp brew/tailscale{.tb-github,}.rb
# brew services (via launchd) start as a global boot daemon (in /Library/LaunchDaemons), running as root
# TODO(mkramlich): confirm at reboot starts & works
SUDO="sudo" INSTALLED_PLIST_DIR=/Library/LaunchDaemons brew/install-start-with-checks.sh
SUDO="sudo" INSTALLED_PLIST_DIR=/Library/LaunchDaemons brew/stop-uninstall-wipe.sh
echo test variant: global, commit-pin
cp brew/tailscale{.commit-pin,}.rb
# brew services (via launchd) start as a global boot daemon (in /Library/LaunchDaemons), running as root
# TODO(mkramlich): confirm at reboot starts & works
SUDO="sudo" INSTALLED_PLIST_DIR=/Library/LaunchDaemons brew/install-start-with-checks.sh
SUDO="sudo" INSTALLED_PLIST_DIR=/Library/LaunchDaemons brew/stop-uninstall-wipe.sh
#####################################
# brew services (via launchd) start as a user login agent (in ~/Library/LaunchAgents), BUT runs as sudo
# TODO(mkramlich): just a WIP POC, much lower priority than boot perm, might drop
#SUDO="" INSTALLED_PLIST_DIR=~/Library/LaunchAgents brew/install-start-with-checks.sh
#SUDO="" INSTALLED_PLIST_DIR=~/Library/LaunchAgents brew/stop-uninstall-wipe.sh

6
brew/up.sh 100755
View File

@ -0,0 +1,6 @@
#!/usr/bin/env sh
set -eu
eval $(brew/vars.sh)
sudo $TS_BIN/tailscale -socket=$TS_SOCK up

23
brew/vars.sh 100755
View File

@ -0,0 +1,23 @@
#!/usr/bin/env sh
set -eu
# TODO(mkramlich): elim redundancy with or otherwise maybe take advantage of version/version.sh
BREW=`brew --prefix` # because varies; /usr/local on Intel, /opt/homebrew on ARM64/M1/AppleSilicon
# TODO(mkramlich): Cellar
cat <<EOF
TS_VER=1.5.0
TS_COMMIT_PIN=188bb142691c8b97673a9cb2aebd9f1521e9bb12
TS_BIN=$BREW/bin
TS_SOCK=$BREW/var/run/tailscale/tailscaled.sock
TS_STATE=$BREW/var/lib/tailscale/tailscaled.state
TS_LOG_DIR=$BREW/var/log/tailscale
TS_CELLAR=$BREW/Cellar/tailscale
TS_PLIST=homebrew.mxcl.tailscale.plist
TS_TARBALL_PORT=8901
TS_FORMULA=brew/tailscale.rb
BREW=$BREW
INSTALLED_PLIST_DIR=/Library/LaunchDaemons
EOF

View File

@ -8,6 +8,9 @@
# If you're packaging Tailscale for a distro, please consider using
# this script, or executing equivalent commands in your
# distro-specific build system.
#
# Homebrew: if the version embed mechanism changes here, please
# also change it in brew/generate-formula.sh, to keep identical.
set -eu

View File

@ -187,7 +187,7 @@ func packageType() string {
}
case "darwin":
// Using tailscaled or IPNExtension?
exe, _ := os.Executable()
exe, _ := os.Executable() // TODO(mkramlich): for tailscaled, distinguish if brew
return filepath.Base(exe)
}
return ""