Skip to content

Commit 265c38c

Browse files
authored
Merge pull request moby#4970 from tonistiigi/improve-dockerfile-reachable
dockerfile: improve detection of reachable stages
2 parents bf968a4 + f55e0de commit 265c38c

File tree

1 file changed

+16
-25
lines changed

1 file changed

+16
-25
lines changed

frontend/dockerfile/dockerfile2llb/convert.go

Lines changed: 16 additions & 25 deletions
Original file line numberDiff line numberDiff line change
@@ -90,7 +90,7 @@ func Dockerfile2LLB(ctx context.Context, dt []byte, opt ConvertOpt) (st *llb.Sta
9090
if ds.ignoreCache {
9191
sbom.IgnoreCache = true
9292
}
93-
for _, dsi := range findReachable(ds) {
93+
for dsi := range allReachableStages(ds) {
9494
if ds != dsi && dsi.scanStage {
9595
sbom.Extras[dsi.stageName] = dsi.state
9696
if dsi.ignoreCache {
@@ -409,11 +409,12 @@ func toDispatchState(ctx context.Context, dt []byte, opt ConvertOpt) (*dispatchS
409409
allStageNames = append(allStageNames, s.stageName)
410410
}
411411
}
412+
allReachable := allReachableStages(target)
412413

413414
baseCtx := ctx
414415
eg, ctx := errgroup.WithContext(ctx)
415416
for i, d := range allDispatchStates.states {
416-
reachable := isReachable(target, d)
417+
_, reachable := allReachable[d]
417418
// resolve image config for every stage
418419
if d.base == nil && !d.noinit {
419420
if d.stage.BaseName == emptyImageName {
@@ -546,7 +547,7 @@ func toDispatchState(ctx context.Context, dt []byte, opt ConvertOpt) (*dispatchS
546547
ctxPaths := map[string]struct{}{}
547548

548549
for _, d := range allDispatchStates.states {
549-
if !isReachable(target, d) || d.noinit {
550+
if _, ok := allReachable[d]; !ok || d.noinit {
550551
continue
551552
}
552553
d.init()
@@ -1724,33 +1725,23 @@ func commitToHistory(img *dockerspec.DockerOCIImage, msg string, withLayer bool,
17241725
return nil
17251726
}
17261727

1727-
func isReachable(from, to *dispatchState) (ret bool) {
1728-
if from == nil {
1729-
return false
1730-
}
1731-
if from == to || isReachable(from.base, to) {
1732-
return true
1733-
}
1734-
for d := range from.deps {
1735-
if isReachable(d, to) {
1736-
return true
1737-
}
1738-
}
1739-
return false
1728+
func allReachableStages(s *dispatchState) map[*dispatchState]struct{} {
1729+
stages := make(map[*dispatchState]struct{})
1730+
addReachableStages(s, stages)
1731+
return stages
17401732
}
17411733

1742-
func findReachable(from *dispatchState) (ret []*dispatchState) {
1743-
if from == nil {
1744-
return nil
1734+
func addReachableStages(s *dispatchState, stages map[*dispatchState]struct{}) {
1735+
if _, ok := stages[s]; ok {
1736+
return
17451737
}
1746-
ret = append(ret, from)
1747-
if from.base != nil {
1748-
ret = append(ret, findReachable(from.base)...)
1738+
stages[s] = struct{}{}
1739+
if s.base != nil {
1740+
addReachableStages(s.base, stages)
17491741
}
1750-
for d := range from.deps {
1751-
ret = append(ret, findReachable(d)...)
1742+
for d := range s.deps {
1743+
addReachableStages(d, stages)
17521744
}
1753-
return ret
17541745
}
17551746

17561747
func validateCircularDependency(states []*dispatchState) error {

0 commit comments

Comments
 (0)