dev/sg: fix macos firewall exceptions (#34475)

This commit is contained in:
Robert Lin 2022-04-25 23:35:54 -07:00 committed by GitHub
parent 49e1b5e9dc
commit 0a74ce93bc
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
4 changed files with 76 additions and 25 deletions

View File

@ -13,6 +13,8 @@ import (
"sync"
"time"
"bitbucket.org/creachadair/shell"
"github.com/bitfield/script"
"github.com/grafana/regexp"
"github.com/rjeczalik/notify"
@ -77,7 +79,10 @@ func Commands(ctx context.Context, globalEnv map[string]string, addToMacOSFirewa
}(cmd, chs[i])
}
postInstall := newPostInstall(ctx, cmds, addToMacOSFirewall)
postInstall := func() error { return nil }
if addToMacOSFirewall || runtime.GOOS == "darwin" {
postInstall = addToMacosFirewall(cmds)
}
err = waitForInstallation(cmdNames, installed, failures, okayToStart, postInstall)
if err != nil {
return err
@ -94,38 +99,70 @@ func Commands(ctx context.Context, globalEnv map[string]string, addToMacOSFirewa
}
}
func newPostInstall(ctx context.Context, cmds []Command, addToMacOSFirewall bool) func() error {
if !addToMacOSFirewall || runtime.GOOS != "darwin" {
return func() error { return nil }
}
// addToMacosFirewall returns a callback that is used to add binaries used by the given
// commands to the MacOS firewall.
func addToMacosFirewall(cmds []Command) func() error {
return func() error {
root, err := root.RepositoryRoot()
if err != nil {
return err
}
fwCmdPath := "/usr/libexec/ApplicationFirewall/socketfilterfw"
stdout.Out.WriteLine(output.Linef(output.EmojiWarningSign, output.StyleWarning, "You may be prompted to enter your password to add exceptions to the firewall."))
fcmd := exec.CommandContext(ctx, "sudo", fwCmdPath, "--setglobalstate", "off")
err = fcmd.Run()
if err != nil {
return err
}
// http://www.manpagez.com/man/8/socketfilterfw/
firewallCmdPath := "/usr/libexec/ApplicationFirewall/socketfilterfw"
var needsFirewallRestart bool
// Add binaries in '.bin' to firewall
for _, cmd := range cmds {
if strings.HasPrefix(cmd.Cmd, ".bin/") {
fcmd = exec.CommandContext(ctx, "sudo", fwCmdPath, "--add", filepath.Join(root, cmd.Cmd))
err = fcmd.Run()
// Some commands use env variables that may be from command env or global env,
// so do substitutions and get the binary we want to work with.
args, ok := shell.Split(os.Expand(cmd.Cmd, func(key string) string {
if v, exists := cmd.Env[key]; exists {
return v
}
return os.Getenv(key)
}))
if !ok || len(args) == 0 {
stdout.Out.WriteLine(output.Linef(output.EmojiFailure, output.StyleSuggestion, "%s: invalid command", cmd.Cmd))
continue
}
binary := args[0]
if strings.HasPrefix(binary, ".bin/") || strings.HasPrefix(binary, "./.bin/") {
addException := script.Exec(shell.Join([]string{"sudo", firewallCmdPath, "--add", filepath.Join(root, binary)}))
msg, err := addException.String()
if err != nil {
return err
stdout.Out.WriteLine(output.Linef(output.EmojiFailure, output.StyleBold, "%s: %s", binary, err.Error()))
continue
}
// socketfilterfw helpfully always returns status 0, so we need to check
// the output to determine whether things worked or not. In all cases we
// don't error out becasue we want other commands to go through the firewall
// updates regardless.
switch {
case strings.Contains(msg, "does not exist"):
stdout.Out.WriteLine(output.Linef(output.EmojiFailure, output.StyleWarning, "%s: %s", binary, strings.TrimSpace(msg)))
case strings.Contains(msg, "added to firewall"):
stdout.Out.WriteLine(output.Linef(output.EmojiFailure, output.StyleSuccess, "%s: added to firewall", binary))
needsFirewallRestart = true
default:
stdout.Out.WriteLine(output.Linef("", output.StyleSuggestion, "%s: %s", binary, strings.TrimSpace(msg)))
}
}
}
fcmd = exec.CommandContext(ctx, "sudo", fwCmdPath, "--setglobalstate", "on")
err = fcmd.Run()
if err != nil {
return err
if needsFirewallRestart {
restartFirewall := script.
Exec(shell.Join([]string{"sudo", firewallCmdPath, "--setglobalstate", "off"})).
Exec(shell.Join([]string{"sudo", firewallCmdPath, "--setglobalstate", "on"}))
return restartFirewall.Error()
}
return nil
}
}
@ -172,13 +209,15 @@ func waitForInstallation(cmdNames map[string]struct{}, installed chan string, fa
// Everything installed!
if len(cmdNames) == 0 {
progress.Complete()
stdout.Out.Write("")
stdout.Out.WriteLine(output.Linef(output.EmojiSuccess, output.StyleSuccess, "Everything installed! Booting up the system!"))
stdout.Out.Write("")
err := postInstallCallback()
if err != nil {
return err
}
stdout.Out.Write("")
stdout.Out.WriteLine(output.Linef(output.EmojiSuccess, output.StyleSuccess, "Everything installed! Booting up the system!"))
stdout.Out.Write("")
close(okayToStart)
return nil
}

4
go.mod
View File

@ -3,6 +3,7 @@ module github.com/sourcegraph/sourcegraph
go 1.17
require (
bitbucket.org/creachadair/shell v0.0.7
cloud.google.com/go/kms v1.1.0
cloud.google.com/go/monitoring v1.2.0
cloud.google.com/go/profiler v0.2.0
@ -23,6 +24,7 @@ require (
github.com/aws/aws-sdk-go-v2/service/s3 v1.24.1
github.com/aws/smithy-go v1.11.0
github.com/beevik/etree v1.1.0
github.com/bitfield/script v0.20.0
github.com/boj/redistore v0.0.0-20180917114910-cd5dcc76aeff
github.com/buildkite/go-buildkite/v3 v3.0.1
github.com/cespare/xxhash v1.1.0
@ -204,6 +206,8 @@ require (
github.com/envoyproxy/protoc-gen-validate v0.6.3 // indirect
github.com/hashicorp/go-multierror v1.1.1 // indirect
github.com/huandu/xstrings v1.3.2 // indirect
github.com/itchyny/gojq v0.12.7 // indirect
github.com/itchyny/timefmt-go v0.1.3 // indirect
github.com/lucasb-eyer/go-colorful v1.2.0 // indirect
github.com/mitchellh/copystructure v1.2.0 // indirect
github.com/mitchellh/reflectwalk v1.0.2 // indirect

8
go.sum
View File

@ -1,5 +1,7 @@
bazil.org/fuse v0.0.0-20160811212531-371fbbdaa898/go.mod h1:Xbm+BRKSBEpa4q4hTSxohYNQpsxXPbPry4JJWOB3LB8=
bazil.org/fuse v0.0.0-20180421153158-65cc252bf669/go.mod h1:Xbm+BRKSBEpa4q4hTSxohYNQpsxXPbPry4JJWOB3LB8=
bitbucket.org/creachadair/shell v0.0.7 h1:Z96pB6DkSb7F3Y3BBnJeOZH2gazyMTWlvecSD4vDqfk=
bitbucket.org/creachadair/shell v0.0.7/go.mod h1:oqtXSSvSYr4624lnnabXHaBsYW6RD80caLi2b3hJk0U=
cloud.google.com/go v0.16.0/go.mod h1:aQUYkXzVsufM+DwF1aE+0xfcU+56JwCaLick0ClmMTw=
cloud.google.com/go v0.25.0/go.mod h1:aQUYkXzVsufM+DwF1aE+0xfcU+56JwCaLick0ClmMTw=
cloud.google.com/go v0.26.0/go.mod h1:aQUYkXzVsufM+DwF1aE+0xfcU+56JwCaLick0ClmMTw=
@ -378,6 +380,8 @@ github.com/beorn7/perks v1.0.1/go.mod h1:G2ZrVWU2WbWT9wwq4/hrbKbnv/1ERSJQ0ibhJ6r
github.com/bgentry/go-netrc v0.0.0-20140422174119-9fd32a8b3d3d h1:xDfNPAt8lFiC1UJrqV3uuy861HCTo708pDMbjHHdCas=
github.com/bgentry/go-netrc v0.0.0-20140422174119-9fd32a8b3d3d/go.mod h1:6QX/PXZ00z/TKoufEY6K/a0k6AhaJrQKdFe6OfVXsa4=
github.com/bgentry/speakeasy v0.1.0/go.mod h1:+zsyZBPWlz7T6j88CTgSN5bM796AkVf0kBD4zp0CCIs=
github.com/bitfield/script v0.20.0 h1:dqeNh8LKf3MfKN21fpuuXNNZPzLlrG6WnmScHqOt13I=
github.com/bitfield/script v0.20.0/go.mod h1:l3AZPVAtKQrL03bwh7nlNTUtgrgSWurpJSbtqspYrOA=
github.com/bitly/go-hostpool v0.0.0-20171023180738-a3a6125de932/go.mod h1:NOuUCSz6Q9T7+igc/hlvDOUdtWKryOrtFyIVABv/p7k=
github.com/bitly/go-simplejson v0.5.0/go.mod h1:cXHtHw4XUPsvGaxgjIAn8PhEWG9NfngEKAMDJEczWVA=
github.com/bits-and-blooms/bitset v1.2.0/go.mod h1:gIdJ4wp64HaoK2YrL1Q5/N7Y16edYb8uY+O0FJTyyDA=
@ -1446,6 +1450,10 @@ github.com/iris-contrib/pongo2 v0.0.1/go.mod h1:Ssh+00+3GAZqSQb30AvBRNxBx7rf0Gqw
github.com/iris-contrib/schema v0.0.1/go.mod h1:urYA3uvUNG1TIIjOSCzHr9/LmbQo8LrOcOqfqxa4hXw=
github.com/ishidawataru/sctp v0.0.0-20191218070446-00ab2ac2db07/go.mod h1:co9pwDoBCm1kGxawmb4sPq0cSIOOWNPT4KnHotMP1Zg=
github.com/ishidawataru/sctp v0.0.0-20210226210310-f2269e66cdee/go.mod h1:co9pwDoBCm1kGxawmb4sPq0cSIOOWNPT4KnHotMP1Zg=
github.com/itchyny/gojq v0.12.7 h1:hYPTpeWfrJ1OT+2j6cvBScbhl0TkdwGM4bc66onUSOQ=
github.com/itchyny/gojq v0.12.7/go.mod h1:ZdvNHVlzPgUf8pgjnuDTmGfHA/21KoutQUJ3An/xNuw=
github.com/itchyny/timefmt-go v0.1.3 h1:7M3LGVDsqcd0VZH2U+x393obrzZisp7C0uEe921iRkU=
github.com/itchyny/timefmt-go v0.1.3/go.mod h1:0osSSCQSASBJMsIZnhAaF1C2fCBTJZXrnj37mG8/c+A=
github.com/j-keck/arping v0.0.0-20160618110441-2cf9dc699c56/go.mod h1:ymszkNOg6tORTn+6F6j+Jc8TOr5osrynvN6ivFWZ2GA=
github.com/jackc/chunkreader v1.0.0 h1:4s39bBR8ByfqH+DKm8rQA3E1LHZWB9XWcrz8fqaZbe0=
github.com/jackc/chunkreader v1.0.0/go.mod h1:RT6O25fNZIuasFJRyZ4R/Y2BbhasbmZXF9QQ7T3kePo=

View File

@ -299,7 +299,7 @@ commands:
caddy:
ignoreStdout: true
ignoreStderr: true
cmd: .bin/caddy_${CADDY_VERSION}_$([[ "$(go env GOOS)" = "darwin" ]] && echo "mac" || echo "$(go env GOOS)")_$(go env GOARCH) run --watch --config=dev/Caddyfile
cmd: .bin/caddy_${CADDY_VERSION} run --watch --config=dev/Caddyfile
install: |
case "$(go env GOOS)" in
linux)
@ -310,7 +310,7 @@ commands:
;;
esac
name="caddy_${CADDY_VERSION}_${os}_$(go env GOARCH)"
target="$PWD/.bin/$name"
target="$PWD/.bin/caddy_${CADDY_VERSION}"
url="https://github.com/caddyserver/caddy/releases/download/v${CADDY_VERSION}/${name}.tar.gz"
if [ ! -f "${target}" ]; then