Skip to content

Commit 1910fed

Browse files
fix: cache: serialize legacy import field (#603)
Fixes #592 by serializing the `wasLegacyImport` field to ensure that the cache records the correct value when an image has it set. Includes a test based on Serge's description in #592. The symptom is an error "cache miss because layer definition was changed" when the definition could not have changed since build. This happens during multi file builds in builds with dependencies, and in build-then-publish flows, where the build will be fine but the publish will fail with the same error. Using `--debug` to show the cache mismatch shows that somewhere along the line, the layer is being serialized with the wrong default value when writing to the cache. Needs to change currentCacheVersion to ensure compatibility, see the TestCacheEntryChanged function comment for more info. Signed-off-by: Michael McCracken <mikmccra@cisco.com>
1 parent f3a8d3b commit 1910fed

File tree

6 files changed

+42
-12
lines changed

6 files changed

+42
-12
lines changed

pkg/stacker/build.go

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -118,7 +118,7 @@ func (b *Builder) updateOCIConfigForOutput(sf *types.Stackerfile, s types.Storag
118118
}
119119

120120
inDir := types.InternalStackerDir
121-
if l.WasLegacyImport() {
121+
if l.WasLegacyImport {
122122
inDir = types.LegacyInternalStackerDir
123123
}
124124

@@ -372,7 +372,9 @@ func (b *Builder) build(s types.Storage, file string) error {
372372

373373
log.Infof("preparing image %s...", name)
374374
inDir := types.InternalStackerDir
375-
if l.WasLegacyImport() {
375+
if l.WasLegacyImport {
376+
log.Debugf("image %s uses legacy import syntax, will also mount imports at %s",
377+
name, types.LegacyInternalStackerDir)
376378
inDir = types.LegacyInternalStackerDir
377379
}
378380

pkg/stacker/cache.go

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -22,7 +22,7 @@ import (
2222
"stackerbuild.io/stacker/pkg/types"
2323
)
2424

25-
const currentCacheVersion = 13
25+
const currentCacheVersion = 14
2626

2727
type ImportType int
2828

pkg/stacker/cache_test.go

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -125,5 +125,5 @@ func TestCacheEntryChanged(t *testing.T) {
125125
// This test works because the type information is included in the
126126
// hashstructure hash above, so using a zero valued CacheEntry is
127127
// enough to capture changes in types.
128-
assert.Equal(uint64(0x4ef432528243e356), h)
128+
assert.Equal(uint64(0xa26696f335211127), h)
129129
}

pkg/types/layer.go

Lines changed: 2 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -260,7 +260,7 @@ type Layer struct {
260260
OS *string `yaml:"os" json:"os,omitempty"`
261261
Arch *string `yaml:"arch" json:"arch,omitempty"`
262262
Bom *Bom `yaml:"bom" json:"bom,omitempty"`
263-
wasLegacyImport bool
263+
WasLegacyImport bool `yaml:"was_legacy_import" json:"was_legacy_import,omitempty"`
264264
}
265265

266266
func parseLayers(referenceDirectory string, lms yaml.MapSlice, requireHash bool) (map[string]Layer, error) {
@@ -369,7 +369,7 @@ func parseLayers(referenceDirectory string, lms yaml.MapSlice, requireHash bool)
369369
if len(layer.LegacyImport) != 0 {
370370
layer.Imports = layer.LegacyImport
371371
layer.LegacyImport = nil
372-
layer.wasLegacyImport = true
372+
layer.WasLegacyImport = true
373373
}
374374

375375
ret[name], err = layer.absolutify(referenceDirectory)
@@ -442,11 +442,6 @@ func (l Layer) absolutify(referenceDirectory string) (Layer, error) {
442442
return ret, nil
443443
}
444444

445-
// WasLegacyImport - return true if this layer used legacy 'import' directive.
446-
func (l Layer) WasLegacyImport() bool {
447-
return l.wasLegacyImport
448-
}
449-
450445
func requireImportHash(imports Imports) error {
451446
for _, imp := range imports {
452447
url, err := NewDockerishUrl(imp.Path)

pkg/types/stackerfile.go

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -269,7 +269,7 @@ func NewStackerfile(stackerfile string, validateHash bool, substitutions []strin
269269

270270
for _, name := range sf.FileOrder {
271271
layer := sf.internal[name]
272-
if layer.WasLegacyImport() {
272+
if layer.WasLegacyImport {
273273
log.Warnf("'import' directive used in layer '%s' inside file '%s' is deprecated. "+
274274
"Support for 'import' will be removed in releases after 2025-01-01. "+
275275
"Migrate by changing 'import' to 'imports' and '/stacker' to '/stacker/imports'. "+

test/caching.bats

Lines changed: 33 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -225,3 +225,36 @@ EOF
225225
echo '{"version": 1, "cache": "lolnope"}' > .stacker/build.cache
226226
stacker build --substitute BUSYBOX_OCI=${BUSYBOX_OCI}
227227
}
228+
229+
@test "cache comparison of legacy import works across prereqs" {
230+
echo "well, hi!"> helloworld
231+
232+
cat >> stacker-req.yaml << "EOF"
233+
base:
234+
from:
235+
type: oci
236+
url: ${{BUSYBOX_OCI}}
237+
build_only: true
238+
import:
239+
- helloworld
240+
run: |
241+
cp /stacker/helloworld /
242+
EOF
243+
244+
cat >> stacker.yaml << "EOF"
245+
config:
246+
prerequisites:
247+
- stacker-req.yaml
248+
249+
buildenv:
250+
from:
251+
type: built
252+
tag: base
253+
import:
254+
- stacker://base/helloworld
255+
run: |
256+
cp /stacker/helloworld /h3
257+
258+
EOF
259+
stacker --debug build --substitute BUSYBOX_OCI=${BUSYBOX_OCI}
260+
}

0 commit comments

Comments
 (0)