Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

fix: remove superfluous userxattr whiteouts #629

Merged
merged 1 commit into from
Jul 31, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion Makefile
Original file line number Diff line number Diff line change
Expand Up @@ -46,7 +46,7 @@ BATS = $(TOOLS_D)/bin/bats
BATS_VERSION := v1.10.0
# OCI registry
ZOT := $(TOOLS_D)/bin/zot
ZOT_VERSION := v2.0.2
ZOT_VERSION := v2.1.0

export PATH := $(TOOLS_D)/bin:$(PATH)

Expand Down
2 changes: 1 addition & 1 deletion go.mod
Original file line number Diff line number Diff line change
Expand Up @@ -284,6 +284,6 @@ require (
)

replace (
github.com/opencontainers/umoci => github.com/project-stacker/umoci v0.0.0-20240417195808-16c510104378
github.com/opencontainers/umoci => github.com/project-stacker/umoci v0.0.0-20240731171528-3a75e000071d
stackerbuild.io/stacker-bom => github.com/project-stacker/stacker-bom v0.0.0-20240509203427-4d685e046780
)
4 changes: 2 additions & 2 deletions go.sum
Original file line number Diff line number Diff line change
Expand Up @@ -795,8 +795,8 @@ github.com/proglottis/gpgme v0.1.3 h1:Crxx0oz4LKB3QXc5Ea0J19K/3ICfy3ftr5exgUK1AU
github.com/proglottis/gpgme v0.1.3/go.mod h1:fPbW/EZ0LvwQtH8Hy7eixhp1eF3G39dtx7GUN+0Gmy0=
github.com/project-stacker/stacker-bom v0.0.0-20240509203427-4d685e046780 h1:VJQ/G6xlNQqEvdzTdtXJ/XNvxv9LQTDJORik1wuxXJU=
github.com/project-stacker/stacker-bom v0.0.0-20240509203427-4d685e046780/go.mod h1:S7hlUdKwPKIMNx2ceiqmLKyXq+FOVaVnAuk77AzdhtI=
github.com/project-stacker/umoci v0.0.0-20240417195808-16c510104378 h1:NHGVwIe0Icrbn8b7WW55FQjETHm5B0i6Gt6UZmzaF9A=
github.com/project-stacker/umoci v0.0.0-20240417195808-16c510104378/go.mod h1:XUXUpCpA/Y8aJWezK1i8o4WDR0Y/vhMcWg+FUNQkKMQ=
github.com/project-stacker/umoci v0.0.0-20240731171528-3a75e000071d h1:MKBVRErs7R34UBQP6ITh97XPPT5GgTDxsme/KxufP5c=
github.com/project-stacker/umoci v0.0.0-20240731171528-3a75e000071d/go.mod h1:XUXUpCpA/Y8aJWezK1i8o4WDR0Y/vhMcWg+FUNQkKMQ=
github.com/prometheus/client_golang v0.9.1/go.mod h1:7SWBe2y4D6OKWSNQJUaRYU/AaXPKyh/dDVn+NZz0KFw=
github.com/prometheus/client_golang v1.0.0/go.mod h1:db9x61etRT2tGnBNRi70OPL5FsnadC4Ky3P0J6CfImo=
github.com/prometheus/client_golang v1.4.0/go.mod h1:e9GMxYsXl05ICDXkRhurwBS4Q3OK1iX/F2sw+iXX5zU=
Expand Down
4 changes: 3 additions & 1 deletion install-build-deps.sh
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,7 @@ installdeps_fedora() {
sudo dnf install golang
go version
fi
sudo dnf install bsdtar
}

installdeps_ubuntu() {
Expand All @@ -40,7 +41,8 @@ installdeps_ubuntu() {
parallel \
pkg-config \
squashfs-tools \
squashfuse
squashfuse \
libarchive-tools
# skopeo deps
sudo apt -yy install \
libgpgme-dev \
Expand Down
2 changes: 1 addition & 1 deletion pkg/overlay/overlay-dirs.go
Original file line number Diff line number Diff line change
Expand Up @@ -48,7 +48,7 @@ func generateOverlayDirLayer(name string, layerType types.LayerType, overlayDir
defer oci.Close()

contents := path.Join(config.RootFSDir, name, "overlay_dirs", path.Base(overlayDir.Source))
blob, mediaType, rootHash, err := generateBlob(layerType, contents, config.OCIDir)
blob, mediaType, rootHash, err := generateBlob(layerType, contents, config.OCIDir, nil)
if err != nil {
return ispec.Descriptor{}, err
}
Expand Down
37 changes: 27 additions & 10 deletions pkg/overlay/pack.go
Original file line number Diff line number Diff line change
Expand Up @@ -135,7 +135,7 @@ func ConvertAndOutput(config types.StackerConfig, tag, name string, layerType ty
bundlePath := overlayPath(config.RootFSDir, theLayer.Digest)
overlayDir := path.Join(bundlePath, "overlay")
// generate blob
blob, mediaType, rootHash, err := generateBlob(layerType, overlayDir, config.OCIDir)
blob, mediaType, rootHash, err := generateBlob(layerType, overlayDir, config.OCIDir, nil)
if err != nil {
return err
}
Expand Down Expand Up @@ -283,23 +283,23 @@ func (o *overlay) initializeBasesInOutput(name string, layerTypes []types.LayerT
return nil
}

func (o *overlay) Repack(name string, layerTypes []types.LayerType, sfm types.StackerFiles) error {
func (o *overlay) Repack(name string, layer types.Layer, layerTypes []types.LayerType, sfm types.StackerFiles) error {
err := o.initializeBasesInOutput(name, layerTypes, sfm)
if err != nil {
return err
}

return repackOverlay(o.config, name, layerTypes)
return repackOverlay(o.config, name, layer, layerTypes)
}

// generateBlob generates either a tar blob or a squashfs blob based on layerType
func generateBlob(layerType types.LayerType, contents string, ociDir string) (io.ReadCloser, string, string, error) {
func generateBlob(layerType types.LayerType, contents string, ociDir string, lowerDirs []string) (io.ReadCloser, string, string, error) {
var blob io.ReadCloser
var err error
var mediaType string
var rootHash string
if layerType.Type == "tar" {
packOptions := layer.RepackOptions{TranslateOverlayWhiteouts: true}
packOptions := layer.RepackOptions{TranslateOverlayWhiteouts: true, OverlayLowerDirs: lowerDirs}
blob = layer.GenerateInsertLayer(contents, "/", false, &packOptions)
mediaType = ispec.MediaTypeImageLayer
} else {
Expand Down Expand Up @@ -382,7 +382,9 @@ func stripOverlayAttrsUnder(dirPath string) error {
})
}

func generateLayer(config types.StackerConfig, oci casext.Engine, mutators []*mutate.Mutator, name string, layerTypes []types.LayerType) (bool, error) {
func generateLayer(config types.StackerConfig, oci casext.Engine, mutators []*mutate.Mutator,
name string, layer types.Layer, layerTypes []types.LayerType,
) (bool, error) {
dir := path.Join(config.RootFSDir, name, "overlay")
ents, err := os.ReadDir(dir)
if err != nil {
Expand Down Expand Up @@ -430,12 +432,27 @@ func generateLayer(config types.StackerConfig, oci casext.Engine, mutators []*mu
return false, err
}

var ovl overlayMetadata
if layer.From.Type != types.BuiltLayer {
ovl, err = readOverlayMetadata(config.RootFSDir, name)
} else {
ovl, err = readOverlayMetadata(config.RootFSDir, layer.From.Tag)
}
if err != nil {
return false, err
}

descs := []ispec.Descriptor{}
for i, layerType := range layerTypes {
mutator := mutators[i]
var desc ispec.Descriptor

blob, mediaType, rootHash, err := generateBlob(layerType, dir, config.OCIDir)
lowerDirs := []string{}
for i := len(ovl.Manifests[layerType].Layers) - 1; i >= 0; i-- {
lowerDirs = append(lowerDirs, overlayPath(config.RootFSDir, ovl.Manifests[layerType].Layers[i].Digest))
}

blob, mediaType, rootHash, err := generateBlob(layerType, dir, config.OCIDir, lowerDirs)
if err != nil {
return false, err
}
Expand Down Expand Up @@ -547,7 +564,7 @@ func generateLayer(config types.StackerConfig, oci casext.Engine, mutators []*mu
return true, nil
}

func repackOverlay(config types.StackerConfig, name string, layerTypes []types.LayerType) error {
func repackOverlay(config types.StackerConfig, name string, layer types.Layer, layerTypes []types.LayerType) error {
oci, err := umoci.OpenLayout(config.OCIDir)
if err != nil {
return err
Expand Down Expand Up @@ -602,7 +619,7 @@ func repackOverlay(config types.StackerConfig, name string, layerTypes []types.L
// generate blobs for each build layer
for _, buildLayer := range ovl.BuiltLayers {

didMutate, err := generateLayer(config, oci, mutators, buildLayer, layerTypes)
didMutate, err := generateLayer(config, oci, mutators, buildLayer, layer, layerTypes)
if err != nil {
return err
}
Expand Down Expand Up @@ -637,7 +654,7 @@ func repackOverlay(config types.StackerConfig, name string, layerTypes []types.L
return err
}

didMutate, err := generateLayer(config, oci, mutators, name, layerTypes)
didMutate, err := generateLayer(config, oci, mutators, name, layer, layerTypes)
if err != nil {
return err
}
Expand Down
2 changes: 1 addition & 1 deletion pkg/stacker/build.go
Original file line number Diff line number Diff line change
Expand Up @@ -551,7 +551,7 @@ func (b *Builder) build(s types.Storage, file string) error {
continue
}

err = s.Repack(name, opts.LayerTypes, b.builtStackerfiles)
err = s.Repack(name, l, opts.LayerTypes, b.builtStackerfiles)
if err != nil {
return err
}
Expand Down
2 changes: 1 addition & 1 deletion pkg/types/storage.go
Original file line number Diff line number Diff line change
Expand Up @@ -47,7 +47,7 @@ type Storage interface {
Unpack(tag, name string) error

// Repack repacks the specified working dir into the specified OCI dir.
Repack(name string, layerTypes []LayerType, sfm StackerFiles) error
Repack(name string, layer Layer, layerTypes []LayerType, sfm StackerFiles) error

// GetLXCRootfsConfig returns the string that should be set as
// lxc.rootfs.path in the LXC container's config.
Expand Down
10 changes: 9 additions & 1 deletion test/publish.bats
Original file line number Diff line number Diff line change
Expand Up @@ -260,8 +260,12 @@ parent:
run: |
rm -rf /etc/apk/repositories
EOF
stacker check
stacker build
stacker publish --skip-tls --url docker://${REGISTRY_URL} --tag latest --substitute BUSYBOX_OCI=${BUSYBOX_OCI}
manifest0=$(cat oci/index.json | jq -r .manifests[0].digest | cut -f2 -d:)
layers0=$(cat oci/blobs/sha256/$manifest0 | jq -r .layers[1].digest | cut -f2 -d:)
bsdtar -tvf oci/blobs/sha256/$layers0
stacker publish --skip-tls --url docker://${REGISTRY_URL} --tag latest
stacker clean

cat > stacker.yaml <<"EOF"
Expand All @@ -271,6 +275,10 @@ child:
url: docker://${{REGISTRY_URL}}/parent:latest
insecure: true
run: |
ps
ls -l /
ls -l /etc
ls -l /etc/apk
[ ! -f /etc/apk/repositories ]
EOF
stacker build --substitute REGISTRY_URL=${REGISTRY_URL}
Expand Down
75 changes: 75 additions & 0 deletions test/whiteout.bats
Original file line number Diff line number Diff line change
@@ -0,0 +1,75 @@
load helpers

function setup() {
stacker_setup
}

function teardown() {
cleanup
}

@test "test not adding extraneous whiteouts" {
cat > stacker.yaml <<EOF
image:
from:
type: docker
url: docker://public.ecr.aws/ubuntu/ubuntu:latest
run: |
apt-get update
apt-get -y install libsensors-config
EOF

stacker build
echo "checking"
for f in $(ls oci/blobs/sha256/); do
file oci/blobs/sha256/$f | grep "gzip" || {
echo "skipping $f"
continue
}
bsdtar -tvf oci/blobs/sha256/$f
run "bsdtar -tvf oci/blobs/sha256/$f | grep '.wh.sensors.d'"
if [ "$status" -eq 0 ]; then
echo "should not have a sensors.d whiteout!";
exit 1;
fi
done
}

@test "dont emit whiteout for new dir creates" {
cat > stacker.yaml <<EOF
# a1.tar has /a1/file
bb:
from:
type: docker
url: docker://busybox
run: |
mkdir /a1
touch /a1/file

nodir:
from:
type: built
tag: bb
run: |
rm -rf /a1

emptydir:
from:
type: built
tag: bb
run: |
rm -rf /a1
mkdir /a1

fulldir:
from:
type: built
tag: bb
run: |
rm -rf /a1
mkdir /a1
touch /a1/newfile
EOF

stacker build
}
Loading