Merge pull request #2363 from crazy-max/bake-remote-token

bake: git auth support for remote definitions
This commit is contained in:
CrazyMax 2024-04-04 19:37:16 +02:00 committed by GitHub
commit 59cc10767e
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
3 changed files with 101 additions and 7 deletions

View File

@ -4,6 +4,8 @@ import (
"archive/tar"
"bytes"
"context"
"os"
"strings"
"github.com/docker/buildx/builder"
controllerapi "github.com/docker/buildx/controller/pb"
@ -23,13 +25,34 @@ type Input struct {
}
func ReadRemoteFiles(ctx context.Context, nodes []builder.Node, url string, names []string, pw progress.Writer) ([]File, *Input, error) {
var session []session.Attachable
var sessions []session.Attachable
var filename string
st, ok := dockerui.DetectGitContext(url, false)
if ok {
ssh, err := controllerapi.CreateSSH([]*controllerapi.SSH{{ID: "default"}})
if err == nil {
session = append(session, ssh)
if ssh, err := controllerapi.CreateSSH([]*controllerapi.SSH{{
ID: "default",
Paths: strings.Split(os.Getenv("BUILDX_BAKE_GIT_SSH"), ","),
}}); err == nil {
sessions = append(sessions, ssh)
}
var gitAuthSecrets []*controllerapi.Secret
if _, ok := os.LookupEnv("BUILDX_BAKE_GIT_AUTH_TOKEN"); ok {
gitAuthSecrets = append(gitAuthSecrets, &controllerapi.Secret{
ID: llb.GitAuthTokenKey,
Env: "BUILDX_BAKE_GIT_AUTH_TOKEN",
})
}
if _, ok := os.LookupEnv("BUILDX_BAKE_GIT_AUTH_HEADER"); ok {
gitAuthSecrets = append(gitAuthSecrets, &controllerapi.Secret{
ID: llb.GitAuthHeaderKey,
Env: "BUILDX_BAKE_GIT_AUTH_HEADER",
})
}
if len(gitAuthSecrets) > 0 {
if secrets, err := controllerapi.CreateSecrets(gitAuthSecrets); err == nil {
sessions = append(sessions, secrets)
}
}
} else {
st, filename, ok = dockerui.DetectHTTPContext(url)
@ -59,7 +82,7 @@ func ReadRemoteFiles(ctx context.Context, nodes []builder.Node, url string, name
ch, done := progress.NewChannel(pw)
defer func() { <-done }()
_, err = c.Build(ctx, client.SolveOpt{Session: session, Internal: true}, "buildx", func(ctx context.Context, c gwclient.Client) (*gwclient.Result, error) {
_, err = c.Build(ctx, client.SolveOpt{Session: sessions, Internal: true}, "buildx", func(ctx context.Context, c gwclient.Client) (*gwclient.Result, error) {
def, err := st.Marshal(ctx)
if err != nil {
return nil, err

View File

@ -29,6 +29,7 @@ var bakeTests = []func(t *testing.T, sb integration.Sandbox){
testBakeLocal,
testBakeLocalMulti,
testBakeRemote,
testBakeRemoteAuth,
testBakeRemoteCmdContext,
testBakeRemoteLocalOverride,
testBakeLocalCwdOverride,
@ -144,6 +145,41 @@ EOT
require.FileExists(t, filepath.Join(dirDest, "foo"))
}
func testBakeRemoteAuth(t *testing.T, sb integration.Sandbox) {
bakefile := []byte(`
target "default" {
dockerfile-inline = <<EOT
FROM scratch
COPY foo /foo
EOT
}
`)
dir := tmpdir(
t,
fstest.CreateFile("docker-bake.hcl", bakefile, 0600),
fstest.CreateFile("foo", []byte("foo"), 0600),
)
dirDest := t.TempDir()
git, err := gitutil.New(gitutil.WithWorkingDir(dir))
require.NoError(t, err)
gitutil.GitInit(git, t)
gitutil.GitAdd(git, t, "docker-bake.hcl", "foo")
gitutil.GitCommit(git, t, "initial commit")
token := identity.NewID()
addr := gitutil.GitServeHTTP(git, t, gitutil.WithAccessToken(token))
out, err := bakeCmd(sb, withDir(dir),
withEnv("BUILDX_BAKE_GIT_AUTH_TOKEN="+token),
withArgs(addr, "--set", "*.output=type=local,dest="+dirDest),
)
require.NoError(t, err, out)
require.FileExists(t, filepath.Join(dirDest, "foo"))
}
func testBakeRemoteLocalOverride(t *testing.T, sb integration.Sandbox) {
remoteBakefile := []byte(`
target "default" {

View File

@ -10,11 +10,28 @@ import (
"github.com/stretchr/testify/require"
)
func GitServeHTTP(c *Git, t testing.TB) (url string) {
type gitServe struct {
token string
}
type GitServeOpt func(*gitServe)
func WithAccessToken(token string) GitServeOpt {
return func(s *gitServe) {
s.token = token
}
}
func GitServeHTTP(c *Git, t testing.TB, opts ...GitServeOpt) (url string) {
t.Helper()
gitUpdateServerInfo(c, t)
ctx, cancel := context.WithCancel(context.TODO())
gs := &gitServe{}
for _, opt := range opts {
opt(gs)
}
ready := make(chan struct{})
done := make(chan struct{})
@ -28,7 +45,25 @@ func GitServeHTTP(c *Git, t testing.TB) (url string) {
go func() {
mux := http.NewServeMux()
prefix := fmt.Sprintf("/%s/", name)
mux.Handle(prefix, http.StripPrefix(prefix, http.FileServer(http.Dir(dir))))
handler := func(next http.Handler) http.Handler {
var tokenChecked bool
return http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
if gs.token != "" && !tokenChecked {
t.Logf("git access token to check: %q", gs.token)
user, pass, _ := r.BasicAuth()
t.Logf("basic auth: user=%q pass=%q", user, pass)
if pass != gs.token {
http.Error(w, "Unauthorized", http.StatusUnauthorized)
return
}
tokenChecked = true
}
next.ServeHTTP(w, r)
})
}
mux.Handle(prefix, handler(http.StripPrefix(prefix, http.FileServer(http.Dir(dir)))))
l, err := net.Listen("tcp", "localhost:0")
if err != nil {
panic(err)