@@ -206,17 +206,17 @@ func toDispatchState(ctx context.Context, dt []byte, opt ConvertOpt) (*dispatchS
206206 return nil , errors .Errorf ("Client and MainContext cannot both be provided" )
207207 }
208208
209- namedContext := func (ctx context. Context , name string , copt dockerui.ContextOpt ) (* llb. State , * dockerspec. DockerOCIImage , error ) {
209+ namedContext := func (name string , copt dockerui.ContextOpt ) (* dockerui. NamedContext , error ) {
210210 if opt .Client == nil {
211- return nil , nil , nil
211+ return nil , nil
212212 }
213213 if ! strings .EqualFold (name , "scratch" ) && ! strings .EqualFold (name , "context" ) {
214214 if copt .Platform == nil {
215215 copt .Platform = opt .TargetPlatform
216216 }
217- return opt .Client .NamedContext (ctx , name , copt )
217+ return opt .Client .NamedContext (name , copt )
218218 }
219- return nil , nil , nil
219+ return nil , nil
220220 }
221221
222222 lint , err := newRuleLinter (dt , & opt )
@@ -349,33 +349,16 @@ func toDispatchState(ctx context.Context, dt []byte, opt ConvertOpt) (*dispatchS
349349 }
350350
351351 if st .Name != "" {
352- s , img , err := namedContext (ctx , st .Name , dockerui.ContextOpt {
352+ nc , err := namedContext (st .Name , dockerui.ContextOpt {
353353 Platform : ds .platform ,
354354 ResolveMode : opt .ImageResolveMode .String (),
355355 AsyncLocalOpts : ds .asyncLocalOpts ,
356356 })
357357 if err != nil {
358358 return nil , err
359359 }
360- if s != nil {
361- ds .dispatched = true
362- ds .state = * s
363- if img != nil {
364- // timestamps are inherited as-is, regardless to SOURCE_DATE_EPOCH
365- // https://github.com/moby/buildkit/issues/4614
366- ds .image = * img
367- if img .Architecture != "" && img .OS != "" {
368- ds .platform = & ocispecs.Platform {
369- OS : img .OS ,
370- Architecture : img .Architecture ,
371- Variant : img .Variant ,
372- OSVersion : img .OSVersion ,
373- }
374- if img .OSFeatures != nil {
375- ds .platform .OSFeatures = append ([]string {}, img .OSFeatures ... )
376- }
377- }
378- }
360+ if nc != nil {
361+ ds .namedContext = nc
379362 allDispatchStates .addState (ds )
380363 ds .base = nil // reset base set by addState
381364 continue
@@ -467,7 +450,7 @@ func toDispatchState(ctx context.Context, dt []byte, opt ConvertOpt) (*dispatchS
467450 // resolve image config for every stage
468451 if d .base == nil && ! d .dispatched && ! d .resolved {
469452 d .resolved = reachable // avoid re-resolving if called again after onbuild
470- if d .stage .BaseName == emptyImageName {
453+ if d .stage .BaseName == emptyImageName && d . namedContext == nil {
471454 d .state = llb .Scratch ()
472455 d .image = emptyImage (platformOpt .targetPlatform )
473456 d .platform = & platformOpt .targetPlatform
@@ -499,25 +482,58 @@ func toDispatchState(ctx context.Context, dt []byte, opt ConvertOpt) (*dispatchS
499482 d .stage .BaseName = reference .TagNameOnly (ref ).String ()
500483
501484 var isScratch bool
502- st , img , err := namedContext (ctx , d .stage .BaseName , dockerui.ContextOpt {
503- ResolveMode : opt .ImageResolveMode .String (),
504- Platform : platform ,
505- AsyncLocalOpts : d .asyncLocalOpts ,
506- })
507- if err != nil {
508- return err
509- }
510- if st != nil {
511- if img != nil {
512- d .image = * img
513- } else {
514- d .image = emptyImage (platformOpt .targetPlatform )
515- }
516- d .state = st .Platform (* platform )
517- d .platform = platform
518- return nil
519- }
520485 if reachable {
486+ // stage was named context
487+ if d .namedContext != nil {
488+ st , img , err := d .namedContext .Load (ctx )
489+ if err != nil {
490+ return err
491+ }
492+ d .dispatched = true
493+ d .state = * st
494+ if img != nil {
495+ // timestamps are inherited as-is, regardless to SOURCE_DATE_EPOCH
496+ // https://github.com/moby/buildkit/issues/4614
497+ d .image = * img
498+ if img .Architecture != "" && img .OS != "" {
499+ d .platform = & ocispecs.Platform {
500+ OS : img .OS ,
501+ Architecture : img .Architecture ,
502+ Variant : img .Variant ,
503+ OSVersion : img .OSVersion ,
504+ }
505+ if img .OSFeatures != nil {
506+ d .platform .OSFeatures = append ([]string {}, img .OSFeatures ... )
507+ }
508+ }
509+ }
510+ return nil
511+ }
512+
513+ // check if base is named context
514+ nc , err := namedContext (d .stage .BaseName , dockerui.ContextOpt {
515+ ResolveMode : opt .ImageResolveMode .String (),
516+ Platform : platform ,
517+ AsyncLocalOpts : d .asyncLocalOpts ,
518+ })
519+ if err != nil {
520+ return err
521+ }
522+ if nc != nil {
523+ st , img , err := nc .Load (ctx )
524+ if err != nil {
525+ return err
526+ }
527+ if img != nil {
528+ d .image = * img
529+ } else {
530+ d .image = emptyImage (platformOpt .targetPlatform )
531+ }
532+ d .state = st .Platform (* platform )
533+ d .platform = platform
534+ return nil
535+ }
536+
521537 prefix := "["
522538 if opt .MultiPlatformRequested && platform != nil {
523539 prefix += platforms .FormatAll (* platform ) + " "
@@ -1015,19 +1031,20 @@ func dispatch(d *dispatchState, cmd command, opt dispatchOpt) error {
10151031}
10161032
10171033type dispatchState struct {
1018- opt dispatchOpt
1019- state llb.State
1020- image dockerspec.DockerOCIImage
1021- platform * ocispecs.Platform
1022- stage instructions.Stage
1023- base * dispatchState
1024- baseImg * dockerspec.DockerOCIImage // immutable, unlike image
1025- dispatched bool
1026- resolved bool // resolved is set to true if base image has been resolved
1027- onBuildInit bool
1028- deps map [* dispatchState ]instructions.Command
1029- buildArgs []instructions.KeyValuePairOptional
1030- commands []command
1034+ opt dispatchOpt
1035+ state llb.State
1036+ image dockerspec.DockerOCIImage
1037+ namedContext * dockerui.NamedContext
1038+ platform * ocispecs.Platform
1039+ stage instructions.Stage
1040+ base * dispatchState
1041+ baseImg * dockerspec.DockerOCIImage // immutable, unlike image
1042+ dispatched bool
1043+ resolved bool // resolved is set to true if base image has been resolved
1044+ onBuildInit bool
1045+ deps map [* dispatchState ]instructions.Command
1046+ buildArgs []instructions.KeyValuePairOptional
1047+ commands []command
10311048 // ctxPaths marks the paths this dispatchState uses from the build context.
10321049 ctxPaths map [string ]struct {}
10331050 // paths marks the paths that are used by this dispatchState.
0 commit comments