@ -14,14 +14,12 @@ import (
"github.com/docker/buildx/bake/hclparser"
"github.com/docker/buildx/build"
cbuild "github.com/docker/buildx/controller/build"
controllerapi "github.com/docker/buildx/controller/pb"
"github.com/docker/buildx/util/buildflags"
"github.com/docker/buildx/util/platformutil"
"github.com/docker/cli/cli/config"
"github.com/docker/docker/builder/remotecontext/urlutil"
hcl "github.com/hashicorp/hcl/v2"
"github.com/moby/buildkit/client/llb"
"github.com/moby/buildkit/session/auth/authprovider"
"github.com/pkg/errors"
)
@ -782,7 +780,11 @@ func (t *Target) AddOverrides(overrides map[string]Override) error {
func TargetsToBuildOpt ( m map [ string ] * Target , inp * Input ) ( map [ string ] build . Options , error ) {
m2 := make ( map [ string ] build . Options , len ( m ) )
for k , v := range m {
bo , err := toBuildOpt ( v , inp )
opts , err := toControllerOpt ( v , inp )
if err != nil {
return nil , err
}
bo , err := cbuild . ToBuildOpts ( * opts , nil )
if err != nil {
return nil , err
}
@ -791,14 +793,14 @@ func TargetsToBuildOpt(m map[string]*Target, inp *Input) (map[string]build.Optio
return m2 , nil
}
func updateContext ( t * build . Inputs , inp * Input ) {
func updateContext ( t * controllerapi . Inputs , inp * Input ) error {
if inp == nil || inp . State == nil {
return
return nil
}
for k , v := range t . NamedContexts {
if v . Path == "." {
t . NamedContexts [ k ] = build . NamedContext { Path : inp . URL }
t . NamedContexts [ k ] = & controllerapi . NamedContext { Path : inp . URL }
}
if strings . HasPrefix ( v . Path , "cwd://" ) || strings . HasPrefix ( v . Path , "target:" ) || strings . HasPrefix ( v . Path , "docker-image:" ) {
continue
@ -807,27 +809,36 @@ func updateContext(t *build.Inputs, inp *Input) {
continue
}
st := llb . Scratch ( ) . File ( llb . Copy ( * inp . State , v . Path , "/" ) , llb . WithCustomNamef ( "set context %s to %s" , k , v . Path ) )
t . NamedContexts [ k ] = build . NamedContext { State : & st }
def , err := st . Marshal ( context . TODO ( ) )
if err != nil {
return err
}
t . NamedContexts [ k ] = & controllerapi . NamedContext { Definition : def . ToPB ( ) }
}
if t . ContextPath == "." {
t . ContextPath = inp . URL
return
return nil
}
if strings . HasPrefix ( t . ContextPath , "cwd://" ) {
return
return nil
}
if IsRemoteURL ( t . ContextPath ) {
return
return nil
}
st := llb . Scratch ( ) . File ( llb . Copy ( * inp . State , t . ContextPath , "/" ) , llb . WithCustomNamef ( "set context to %s" , t . ContextPath ) )
t . ContextState = & st
def , err := st . Marshal ( context . TODO ( ) )
if err != nil {
return err
}
t . ContextDefinition = def . ToPB ( )
return nil
}
// validateContextsEntitlements is a basic check to ensure contexts do not
// escape local directories when loaded from remote sources. This is to be
// replaced with proper entitlements support in the future.
func validateContextsEntitlements ( t build . Inputs , inp * Input ) error {
func validateContextsEntitlements ( t controllerapi . Inputs , inp * Input ) error {
if inp == nil || inp . State == nil {
return nil
}
@ -836,13 +847,13 @@ func validateContextsEntitlements(t build.Inputs, inp *Input) error {
return nil
}
}
if t . Context State == nil {
if t . Context Definition == nil {
if err := checkPath ( t . ContextPath ) ; err != nil {
return err
}
}
for _ , v := range t . NamedContexts {
if v . State != nil {
if v . Definition != nil {
continue
}
if err := checkPath ( v . Path ) ; err != nil {
@ -877,7 +888,7 @@ func checkPath(p string) error {
return nil
}
func to Build Opt( t * Target , inp * Input ) ( * build. Options, error ) {
func to Controller Opt( t * Target , inp * Input ) ( * controllerapi. Build Options, error ) {
if v := t . Context ; v != nil && * v == "-" {
return nil , errors . Errorf ( "context from stdin not allowed in bake" )
}
@ -930,9 +941,9 @@ func toBuildOpt(t *Target, inp *Input) (*build.Options, error) {
networkMode = * t . NetworkMode
}
bi := build . Inputs {
bi := controllerapi . Inputs {
ContextPath : contextPath ,
Dockerfile Path : dockerfilePath ,
Dockerfile Name : dockerfilePath ,
NamedContexts : toNamedContexts ( t . Contexts ) ,
}
if t . DockerfileInline != nil {
@ -944,7 +955,7 @@ func toBuildOpt(t *Target, inp *Input) (*build.Options, error) {
}
for k , v := range bi . NamedContexts {
if strings . HasPrefix ( v . Path , "cwd://" ) {
bi . NamedContexts [ k ] = build . NamedContext { Path : path . Clean ( strings . TrimPrefix ( v . Path , "cwd://" ) ) }
bi . NamedContexts [ k ] = & controllerapi . NamedContext { Path : path . Clean ( strings . TrimPrefix ( v . Path , "cwd://" ) ) }
}
}
@ -954,82 +965,55 @@ func toBuildOpt(t *Target, inp *Input) (*build.Options, error) {
t . Context = & bi . ContextPath
bo := & build . Options{
Inputs : bi ,
opts := & controllerapi . Build Options{
Inputs : & bi ,
Tags : t . Tags ,
BuildArgs : args ,
Labels : labels ,
NoCache : noCache ,
NoCacheFilter : t . NoCacheFilter ,
Pull : pull ,
NetworkMode : networkMode ,
Linked : t . linked ,
Opts : & controllerapi . CommonOptions {
NoCache : noCache ,
Pull : pull ,
Linked : t . linked ,
} ,
Platforms : t . Platforms ,
}
var err error
platforms , err := platformutil . Parse ( t . Platforms )
if err != nil {
return nil , err
}
bo . Platforms = platforms
dockerConfig := config . LoadDefaultConfigFile ( os . Stderr )
bo . Session = append ( bo . Session , authprovider . NewDockerAuthProvider ( dockerConfig ) )
secrets , err := buildflags . ParseSecretSpecs ( t . Secrets )
if err != nil {
return nil , err
}
secretAttachment , err := controllerapi . CreateSecrets ( secrets )
if err != nil {
return nil , err
if t . Target != nil {
opts . Target = * t . Target
}
bo . Session = append ( bo . Session , secretAttachment )
sshSpecs, err := buildflags . ParseSSHSpecs ( t . SSH )
opts . Secrets , err = buildflags . ParseSecretSpecs ( t . Secrets )
if err != nil {
return nil , err
}
if len ( sshSpecs ) == 0 && buildflags . IsGitSSH ( contextPath ) {
sshSpecs = append ( sshSpecs , & controllerapi . SSH { ID : "default" } )
}
sshAttachment , err := controllerapi . CreateSSH ( sshSpecs )
opts . SSH , err = buildflags . ParseSSHSpecs ( t . SSH )
if err != nil {
return nil , err
}
bo . Session = append ( bo . Session , sshAttachment )
if t . Target != nil {
bo . Target = * t . Target
}
cacheImports, err : = buildflags . ParseCacheEntry ( t . CacheFrom )
opts . CacheFrom , err = buildflags . ParseCacheEntry ( t . CacheFrom )
if err != nil {
return nil , err
}
bo . CacheFrom = controllerapi . CreateCaches ( cacheImports )
cacheExports , err := buildflags . ParseCacheEntry ( t . CacheTo )
opts . CacheTo , err = buildflags . ParseCacheEntry ( t . CacheTo )
if err != nil {
return nil , err
}
bo . CacheTo = controllerapi . CreateCaches ( cacheExports )
outputs , err := buildflags . ParseExports ( t . Outputs )
if err != nil {
return nil , err
}
bo . Exports , err = controllerapi . CreateExports ( outputs )
opts . Exports , err = buildflags . ParseExports ( t . Outputs )
if err != nil {
return nil , err
}
attests, err : = buildflags . ParseAttests ( t . Attest )
opts. Attests , err = buildflags . ParseAttests ( t . Attest )
if err != nil {
return nil , err
}
bo . Attests = controllerapi . CreateAttestations ( attests )
return b o, nil
return opts , nil
}
func defaultTarget ( ) * Target {
@ -1102,10 +1086,10 @@ func sliceEqual(s1, s2 []string) bool {
return true
}
func toNamedContexts ( m map [ string ] string ) map [ string ] build . NamedContext {
m2 := make ( map [ string ] build . NamedContext , len ( m ) )
func toNamedContexts ( m map [ string ] string ) map [ string ] * controllerapi . NamedContext {
m2 := make ( map [ string ] * controllerapi . NamedContext , len ( m ) )
for k , v := range m {
m2 [ k ] = build . NamedContext { Path : v }
m2 [ k ] = & controllerapi . NamedContext { Path : v }
}
return m2
}