Skip to content

Commit

Permalink
Merge pull request #3123 from buildkite/notify-when-host-and-bootstra…
Browse files Browse the repository at this point in the history
…p-agent-paths-mismatch

Notify when host and bootstrap agent paths mismatch
  • Loading branch information
jordandcarter authored Dec 16, 2024
2 parents 7e91401 + 05dc08a commit 661d722
Show file tree
Hide file tree
Showing 2 changed files with 50 additions and 0 deletions.
46 changes: 46 additions & 0 deletions clicommand/agent_start.go
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@ import (
"fmt"
"io"
"os"
"os/exec"
"os/signal"
"path/filepath"
"regexp"
Expand Down Expand Up @@ -758,6 +759,18 @@ var AgentStartCommand = cli.Command{
))
defer done()

// Verify that the bootstrap buildkite-agent executable matches the current host agent
// executable. In development builds, it exits on mismatch; otherwise it only logs a warning.
// This is to avoid confusion when making changes to the buildkite-agent but forgetting to
// update the buildkite-agent binary available from $PATH
if err := checkBinaryPaths(); err != nil {
if version.IsDevelopmentBuild() {
return fmt.Errorf("check binary paths: %s", err)
} else {
l.Warn("check binary paths: %s", err)
}
}

// Remove any config env from the environment to prevent them propagating to bootstrap
if err := UnsetConfigFromEnvironment(c); err != nil {
return fmt.Errorf("failed to unset config from environment: %w", err)
Expand Down Expand Up @@ -1257,6 +1270,39 @@ var AgentStartCommand = cli.Command{
},
}

// checkBinaryPaths looks up both the bootstrap and host buildkite-agent paths,
// and returns an error if they do not match or if either cannot be determined.
func checkBinaryPaths() error {
bootstrapPath, err := exec.LookPath("buildkite-agent")
if err != nil {
return fmt.Errorf("failed to locate bootstrap buildkite-agent: %w", err)
}

evalBootstrapPath, err := filepath.EvalSymlinks(bootstrapPath)
if err != nil {
return fmt.Errorf("failed to locate bootstrap buildkite-agent: %w", err)
}

hostPath, err := os.Executable()
if err != nil {
return fmt.Errorf("failed to determine host buildkite-agent executable: %w", err)
}

evalHostPath, err := filepath.EvalSymlinks(hostPath)
if err != nil {
return fmt.Errorf("failed to determine host buildkite-agent executable: %w", err)
}

if evalHostPath != evalBootstrapPath {
return fmt.Errorf(
"mismatched buildkite-agent paths: host=%q bootstrap=%q",
evalHostPath, evalBootstrapPath,
)
}

return nil
}

func parseAndValidateJWKS(ctx context.Context, keysetType, path string) (jwk.Set, error) {
jwksBytes, err := os.ReadFile(path)
if err != nil {
Expand Down
4 changes: 4 additions & 0 deletions version/version.go
Original file line number Diff line number Diff line change
Expand Up @@ -38,6 +38,10 @@ func BuildNumber() string {
return buildNumber
}

func IsDevelopmentBuild() bool {
return buildNumber == "x"
}

// commitInfo returns a string consisting of the commit hash and whether the the build was made in a
// `dirty` working directory or not. A dirty working directory is one that has uncommitted changes
// to files that git would track.
Expand Down

0 comments on commit 661d722

Please sign in to comment.