diff --git a/.github/goreleaser.yaml b/.github/goreleaser.yaml index 2df105f6b..d40106fc3 100644 --- a/.github/goreleaser.yaml +++ b/.github/goreleaser.yaml @@ -40,9 +40,6 @@ builds: - cmd: ./scripts/get-envoy.bash env: - TARGET={{ .Os }}-{{ .Arch }} - - DIR={{ dir .Path }} - post: - - cmd: ./scripts/embed-envoy.bash {{ .Path }} - id: pomerium-cli main: ./cmd/pomerium-cli diff --git a/Makefile b/Makefile index a99959fbc..737ab2048 100644 --- a/Makefile +++ b/Makefile @@ -45,7 +45,7 @@ generate-mocks: ## Generate mocks @echo "==> $@" @go run github.com/golang/mock/mockgen -destination internal/directory/auth0/mock_auth0/mock.go github.com/pomerium/pomerium/internal/directory/auth0 RoleManager -.PHONY: build-lint +.PHONY: deps-lint deps-lint: ## Install lint dependencies @echo "==> $@" ./scripts/get-envoy.bash @@ -85,18 +85,16 @@ build: ## Builds dynamic executables and/or packages. @echo "==> $@" ./scripts/get-envoy.bash @CGO_ENABLED=0 GO111MODULE=on $(GO) build -tags "$(BUILDTAGS)" ${GO_LDFLAGS} -o $(BINDIR)/$(NAME) ./cmd/"$(NAME)" - ./scripts/embed-envoy.bash $(BINDIR)/$(NAME) .PHONY: build-debug build-debug: ## Builds binaries appropriate for debugging @echo "==> $@" ./scripts/get-envoy.bash - @CGO_ENABLED=0 GO111MODULE=on $(GO) build -gcflags="all=-N -l" -ldflags="-X github.com/pomerium/pomerium/internal/envoy.Checksum=$$(cat ./bin/envoy.sha256 | tr -d '\n')" -o $(BINDIR)/$(NAME) ./cmd/"$(NAME)" - ./scripts/embed-envoy.bash $(BINDIR)/$(NAME) + @CGO_ENABLED=0 GO111MODULE=on $(GO) build -gcflags="all=-N -l" -o $(BINDIR)/$(NAME) ./cmd/"$(NAME)" .PHONY: lint -lint: ## Verifies `golint` passes. +lint: deps-lint ## Verifies `golint` passes. @echo "==> $@" @golangci-lint run ./... diff --git a/config/envoyconfig/filemgr/filemgr.go b/config/envoyconfig/filemgr/filemgr.go index 59d8f683d..ca6a41e06 100644 --- a/config/envoyconfig/filemgr/filemgr.go +++ b/config/envoyconfig/filemgr/filemgr.go @@ -56,6 +56,10 @@ func (mgr *Manager) BytesDataSource(fileName string, data []byte) *envoy_config_ // ClearCache clears the file cache. func (mgr *Manager) ClearCache() { + if _, err := os.Stat(mgr.cfg.cacheDir); os.IsNotExist(err) { + return + } + err := filepath.Walk(mgr.cfg.cacheDir, func(p string, fi os.FileInfo, err error) error { if err != nil { return err diff --git a/go.mod b/go.mod index 4eb9021de..3d98589b0 100644 --- a/go.mod +++ b/go.mod @@ -32,7 +32,6 @@ require ( github.com/hashicorp/errwrap v1.1.0 // indirect github.com/hashicorp/go-multierror v1.1.1 github.com/hashicorp/golang-lru v0.5.4 - github.com/kardianos/osext v0.0.0-20190222173326-2bc1f35cddc0 // indirect github.com/lithammer/shortuuid/v3 v3.0.7 github.com/martinlindhe/base36 v1.1.0 github.com/mitchellh/hashstructure/v2 v2.0.2 @@ -75,7 +74,6 @@ require ( google.golang.org/grpc v1.38.0 google.golang.org/protobuf v1.26.0 gopkg.in/auth0.v5 v5.18.0 - gopkg.in/cookieo9/resources-go.v2 v2.0.0-20150225115733-d27c04069d0d gopkg.in/ini.v1 v1.62.0 // indirect gopkg.in/yaml.v3 v3.0.0-20210107192922-496545a6307b ) diff --git a/go.sum b/go.sum index de1de20da..f003a5b71 100644 --- a/go.sum +++ b/go.sum @@ -489,8 +489,6 @@ github.com/julienschmidt/httprouter v1.2.0/go.mod h1:SYymIcj16QtmaHHD7aYtjjsJG7V github.com/julienschmidt/httprouter v1.3.0/go.mod h1:JR6WtHb+2LUe8TCKY3cZOxFyyO8IZAc4RVcycCCAKdM= github.com/julz/importas v0.0.0-20210419104244-841f0c0fe66d/go.mod h1:oSFU2R4XK/P7kNBrnL/FEQlDGN1/6WoxXEjSSXO0DV0= github.com/k0kubun/colorstring v0.0.0-20150214042306-9440f1994b88/go.mod h1:3w7q1U84EfirKl04SVQ/s7nPm1ZPhiXd34z40TNz36k= -github.com/kardianos/osext v0.0.0-20190222173326-2bc1f35cddc0 h1:iQTw/8FWTuc7uiaSepXwyf3o52HaUYcV+Tu66S3F5GA= -github.com/kardianos/osext v0.0.0-20190222173326-2bc1f35cddc0/go.mod h1:1NbS8ALrpOvjt0rHPNLyCIeMtbizbir8U//inJ+zuB8= github.com/kisielk/errcheck v1.1.0/go.mod h1:EZBBE59ingxPouuu3KfxchcWSUPOHkagtvWXihfKN4Q= github.com/kisielk/errcheck v1.2.0/go.mod h1:/BMXB+zMLi60iA8Vv6Ksmxu/1UDYcXs4uQLJ+jE2L00= github.com/kisielk/errcheck v1.6.0/go.mod h1:pFxgyoBC7bSaBwPgfKdkLd5X25qrDl4LWUI2bnpBCr8= @@ -1396,8 +1394,6 @@ gopkg.in/check.v1 v1.0.0-20200227125254-8fa46927fb4f h1:BLraFXnmrev5lT+xlilqcH8X gopkg.in/check.v1 v1.0.0-20200227125254-8fa46927fb4f/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0= gopkg.in/cheggaaa/pb.v1 v1.0.25/go.mod h1:V/YB90LKu/1FcN3WVnfiiE5oMCibMjukxqG/qStrOgw= gopkg.in/cheggaaa/pb.v1 v1.0.28/go.mod h1:V/YB90LKu/1FcN3WVnfiiE5oMCibMjukxqG/qStrOgw= -gopkg.in/cookieo9/resources-go.v2 v2.0.0-20150225115733-d27c04069d0d h1:YjTGSRV59gG1DHCq68v2B771I9dGFxvMkugf7OKglpk= -gopkg.in/cookieo9/resources-go.v2 v2.0.0-20150225115733-d27c04069d0d/go.mod h1:kbUs813+JgwKQdecaTv87br/FZUaSEuPj8vbr2vq8sY= gopkg.in/errgo.v2 v2.1.0/go.mod h1:hNsd1EY+bozCKY1Ytp96fpM3vjJbqLJn88ws8XvfDNI= gopkg.in/fsnotify.v1 v1.4.7/go.mod h1:Tz8NjZHkW78fSQdbUxIjBTcgA1z1m8ZHf0WmKUhAMys= gopkg.in/gcfg.v1 v1.2.3/go.mod h1:yesOnuUOFQAhST5vPY4nbZsb/huCgGGXlipJsBn0b3o= diff --git a/internal/cmd/pomerium/pomerium_test.go b/internal/cmd/pomerium/pomerium_test.go index b154d273c..664032b81 100644 --- a/internal/cmd/pomerium/pomerium_test.go +++ b/internal/cmd/pomerium/pomerium_test.go @@ -10,7 +10,6 @@ import ( func Test_run(t *testing.T) { os.Clearenv() - t.Parallel() tests := []struct { name string configFileFlag string diff --git a/internal/envoy/embed.go b/internal/envoy/embed.go index b085dd210..abfb8e3c4 100644 --- a/internal/envoy/embed.go +++ b/internal/envoy/embed.go @@ -1,15 +1,17 @@ package envoy import ( + "bytes" "context" "fmt" "io/fs" "os" "path/filepath" + "sync" "github.com/natefinch/atomic" - resources "gopkg.in/cookieo9/resources-go.v2" + "github.com/pomerium/pomerium/internal/envoy/files" "github.com/pomerium/pomerium/internal/log" ) @@ -18,51 +20,49 @@ const ( embeddedDirectoryPermissions fs.FileMode = 0o755 ) -var embeddedFilesBaseDirectory = filepath.Join(os.TempDir(), "pomerium-embedded-files") +var ( + embeddedFilesBaseDirectory = filepath.Join(os.TempDir(), "pomerium-embedded-files") + extractEmbeddedEnvoyOnce sync.Once +) func extractEmbeddedEnvoy(ctx context.Context) (outPath string, err error) { - exePath, err := resources.ExecutablePath() - if err != nil { - return "", fmt.Errorf("error finding executable path: %w", err) - } - bundle, err := resources.OpenZip(exePath) - if err != nil { - return "", fmt.Errorf("error opening binary zip file: %w", err) - } - defer bundle.Close() + extractEmbeddedEnvoyOnce.Do(func() { + // clean up our base directory before starting + err = os.RemoveAll(embeddedFilesBaseDirectory) + if err != nil { + err = fmt.Errorf("error cleaning embedded file directory: (directory=%s): %w", embeddedFilesBaseDirectory, err) + return + } - rc, err := bundle.Open("envoy") - if err != nil { - return "", fmt.Errorf("error opening embedded envoy binary: %w", err) - } - defer rc.Close() + // create known directory base to clean at startup + err = os.MkdirAll(embeddedFilesBaseDirectory, embeddedDirectoryPermissions) + if err != nil { + err = fmt.Errorf("error creating embedded file directory: (directory=%s): %w", embeddedFilesBaseDirectory, err) + return + } - // clean up our base directory before starting - err = os.RemoveAll(embeddedFilesBaseDirectory) - if err != nil { - return "", fmt.Errorf("error cleaning embedded file directory: (directory=%s): %w", embeddedFilesBaseDirectory, err) - } + // build a random temp directory inside our base directory to guarantee permissions + var tmpDir string + tmpDir, err = os.MkdirTemp(embeddedFilesBaseDirectory, "envoy-") + if err != nil { + err = fmt.Errorf("error creating embedded file tmp directory: (directory=%s): %w", embeddedFilesBaseDirectory, err) + return + } - // create known directory base to clean at startup - err = os.MkdirAll(embeddedFilesBaseDirectory, embeddedDirectoryPermissions) - if err != nil { - return "", fmt.Errorf("error creating embedded file directory: (directory=%s): %w", embeddedFilesBaseDirectory, err) - } + outPath = filepath.Join(tmpDir, "envoy") - // build a random temp directory inside our base directory to guarantee permissions - tmpDir, err := os.MkdirTemp(embeddedFilesBaseDirectory, "envoy-") - outPath = filepath.Join(tmpDir, "envoy") + log.Info(ctx).Str("path", outPath).Msg("extracting envoy binary") + err = atomic.WriteFile(outPath, bytes.NewReader(files.Binary())) + if err != nil { + err = fmt.Errorf("error extracting embedded envoy binary to temporary directory (path=%s): %w", outPath, err) + return + } - log.Info(ctx).Str("path", outPath).Msg("extracting envoy binary") - err = atomic.WriteFile(outPath, rc) - if err != nil { - return "", fmt.Errorf("error extracting embedded envoy binary to temporary directory (path=%s): %w", outPath, err) - } - - err = os.Chmod(outPath, embeddedEnvoyPermissions) - if err != nil { - return "", fmt.Errorf("error chmoding embedded envoy binary: %w", err) - } - - return outPath, nil + err = os.Chmod(outPath, embeddedEnvoyPermissions) + if err != nil { + err = fmt.Errorf("error chmoding embedded envoy binary: %w", err) + return + } + }) + return outPath, err } diff --git a/internal/envoy/envoy.go b/internal/envoy/envoy.go index adebe505a..815e90a16 100644 --- a/internal/envoy/envoy.go +++ b/internal/envoy/envoy.go @@ -121,6 +121,8 @@ func NewServer(ctx context.Context, src config.Source, grpcPort, httpPort string // Close kills any underlying envoy process. func (srv *Server) Close() error { + srv.monitorProcessCancel() + srv.mu.Lock() defer srv.mu.Unlock() diff --git a/internal/envoy/envoy_linux.go b/internal/envoy/envoy_linux.go index be324caa2..a4480c63c 100644 --- a/internal/envoy/envoy_linux.go +++ b/internal/envoy/envoy_linux.go @@ -33,6 +33,7 @@ func (srv *Server) runProcessCollector(ctx context.Context) { if err := view.Register(pc.Views()...); err != nil { log.Error(ctx).Err(err).Msg("failed to register envoy process metric views") } + defer view.Unregister(pc.Views()...) const collectInterval = time.Second * 10 ticker := time.NewTicker(collectInterval) diff --git a/internal/envoy/files/files.go b/internal/envoy/files/files.go index b89c18fc5..05bd16710 100644 --- a/internal/envoy/files/files.go +++ b/internal/envoy/files/files.go @@ -6,11 +6,10 @@ import ( "strings" ) -//go:embed envoy.sha256 -var rawChecksum string - -//go:embed envoy.version -var rawVersion string +// Binary returns the raw envoy binary bytes. +func Binary() []byte { + return rawBinary +} // Checksum returns the checksum for the embedded envoy binary. func Checksum() string { diff --git a/internal/envoy/files/files_darwin.go b/internal/envoy/files/files_darwin.go new file mode 100644 index 000000000..e229092d0 --- /dev/null +++ b/internal/envoy/files/files_darwin.go @@ -0,0 +1,14 @@ +//+build darwin + +package files + +import _ "embed" // embed + +//go:embed envoy-darwin-amd64 +var rawBinary []byte + +//go:embed envoy-darwin-amd64.sha256 +var rawChecksum string + +//go:embed envoy-darwin-amd64.version +var rawVersion string diff --git a/internal/envoy/files/files_linux_amd64.go b/internal/envoy/files/files_linux_amd64.go new file mode 100644 index 000000000..71eede83e --- /dev/null +++ b/internal/envoy/files/files_linux_amd64.go @@ -0,0 +1,14 @@ +//+build linux,amd64 + +package files + +import _ "embed" // embed + +//go:embed envoy-linux-amd64 +var rawBinary []byte + +//go:embed envoy-linux-amd64.sha256 +var rawChecksum string + +//go:embed envoy-linux-amd64.version +var rawVersion string diff --git a/internal/envoy/files/files_linux_arm64.go b/internal/envoy/files/files_linux_arm64.go new file mode 100644 index 000000000..239d99b16 --- /dev/null +++ b/internal/envoy/files/files_linux_arm64.go @@ -0,0 +1,14 @@ +//+build linux,arm64 + +package files + +import _ "embed" // embed + +//go:embed envoy-linux-arm64 +var rawBinary []byte + +//go:embed envoy-linux-arm64.sha256 +var rawChecksum string + +//go:embed envoy-linux-arm64.version +var rawVersion string diff --git a/scripts/embed-envoy.bash b/scripts/embed-envoy.bash deleted file mode 100755 index 6485bf3cd..000000000 --- a/scripts/embed-envoy.bash +++ /dev/null @@ -1,17 +0,0 @@ -#!/bin/bash -set -euo pipefail - -BINARY=$1 -DIR=$(dirname "${BINARY}") - -( - cd "$DIR" - zip envoy.zip envoy -) - -echo "appending $DIR/envoy.zip to ${BINARY}" - -if [ "$(unzip -z -qq "$BINARY" 2>&1)" != "" ]; then - cat "$DIR/envoy.zip" >>"${BINARY}" -fi -zip -A "${BINARY}" diff --git a/scripts/get-envoy.bash b/scripts/get-envoy.bash index 5e727f24b..0ed0d94f1 100755 --- a/scripts/get-envoy.bash +++ b/scripts/get-envoy.bash @@ -6,7 +6,7 @@ export PATH _project_root="$(cd "$(dirname "${BASH_SOURCE[0]}")" >/dev/null 2>&1 && pwd)/.." _envoy_version=1.17.3 -_dir="${DIR:-"$_project_root/bin"}" +_dir="$_project_root/internal/envoy/files" _target="${TARGET:-"$(go env GOOS)-$(go env GOARCH)"}" # until m1 macs are supported, fallback to x86 and use rosetta @@ -16,31 +16,20 @@ fi _url="https://github.com/pomerium/envoy-binaries/releases/download/v${_envoy_version}/envoy-${_target}" -# create the directory if it doesn't exist -mkdir -p "$_dir" - -# download the shasum of the binary curl \ --compressed \ --silent \ --location \ + --time-cond "$_dir/envoy-$_target" \ + --output "$_dir/envoy-$_target" \ + "$_url" + +curl \ + --compressed \ + --silent \ + --location \ + --time-cond "$_dir/envoy-$_target.sha256" \ --output "$_dir/envoy-$_target.sha256" \ "$_url.sha256" -# if the shasum doesn't match (or the binary doesn't exist), re-download -if ! (cd "$_dir" && shasum -c "envoy-$_target.sha256" >/dev/null 2>&1) ; then - curl \ - --compressed \ - --silent \ - --location \ - --output "$_dir/envoy-$_target" \ - "$_url" -fi - -# save the bare name -cp -f "$_dir/envoy-$_target" "$_dir/envoy" -cp -f "$_dir/envoy-$_target.sha256" "$_dir/envoy.sha256" - -# save to the embedded files in the envoy package -cp -f "$_dir/envoy-$_target.sha256" "$_project_root/internal/envoy/files/envoy.sha256" -echo "$_envoy_version" > "$_project_root/internal/envoy/files/envoy.version" +echo "$_envoy_version" > "$_dir/envoy-$_target.version"