Skip to content

Commit

Permalink
feat: add support for erofs layers
Browse files Browse the repository at this point in the history
atomfs has added support for additional filesystem types such as erofs.

Signed-off-by: Ramkumar Chinchani <[email protected]>
  • Loading branch information
rchincha committed Nov 10, 2024
1 parent ad9a694 commit 284c7f5
Show file tree
Hide file tree
Showing 11 changed files with 57 additions and 38 deletions.
10 changes: 5 additions & 5 deletions cmd/stacker/build.go
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@ import (
"fmt"

cli "github.com/urfave/cli/v2"
"machinerun.io/atomfs/squashfs"
"machinerun.io/atomfs/pkg/verity"
"stackerbuild.io/stacker/pkg/stacker"
"stackerbuild.io/stacker/pkg/types"
)
Expand Down Expand Up @@ -52,12 +52,12 @@ func initCommonBuildFlags() []cli.Flag {
},
&cli.StringSliceFlag{
Name: "layer-type",
Usage: "set the output layer type (supported values: tar, squashfs); can be supplied multiple times",
Usage: "set the output layer type (supported values: tar, squashfs, erofs); can be supplied multiple times",
Value: cli.NewStringSlice("tar"),
},
&cli.BoolFlag{
Name: "no-squashfs-verity",
Usage: "do not append dm-verity data to squashfs archives",
Name: "no-verity",
Usage: "do not append dm-verity data to fs archives",
},
&cli.BoolFlag{
Name: "require-hash",
Expand Down Expand Up @@ -103,7 +103,7 @@ func newBuildArgs(ctx *cli.Context) (stacker.BuildArgs, error) {
AnnotationsNamespace: ctx.String("annotations-namespace"),
}
var err error
verity := squashfs.VerityMetadata(!ctx.Bool("no-squashfs-verity"))
verity := verity.VerityMetadata(!ctx.Bool("no-verity"))
args.LayerTypes, err = types.NewLayerTypes(ctx.StringSlice("layer-type"), verity)
return args, err
}
Expand Down
2 changes: 1 addition & 1 deletion cmd/stacker/inspect.go
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,7 @@ import (
"github.com/opencontainers/umoci/oci/casext"
"github.com/pkg/errors"
cli "github.com/urfave/cli/v2"
stackeroci "machinerun.io/atomfs/oci"
stackeroci "machinerun.io/atomfs/pkg/oci"
)

var inspectCmd = cli.Command{
Expand Down
12 changes: 7 additions & 5 deletions cmd/stacker/internal_go.go
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,7 @@ import (
"github.com/pkg/errors"
cli "github.com/urfave/cli/v2"
"golang.org/x/sys/unix"
"machinerun.io/atomfs"
"machinerun.io/atomfs/pkg/molecule"
"stackerbuild.io/stacker/pkg/lib"
"stackerbuild.io/stacker/pkg/log"
"stackerbuild.io/stacker/pkg/overlay"
Expand Down Expand Up @@ -182,15 +182,17 @@ func doAtomfsMount(ctx *cli.Context) error {
return errors.WithStack(err)
}

opts := atomfs.MountOCIOpts{
opts := molecule.MountOCIOpts{
OCIDir: config.OCIDir,
MetadataPath: path.Join(wd, "atomfs-metadata"),
Tag: tag,
Target: mountpoint,
AddWriteableOverlay: false,
WriteableOverlayPath: "",
AllowMissingVerityData: true,
MetadataDir: path.Join(wd, "atomfs-metadata"),
}

mol, err := atomfs.BuildMoleculeFromOCI(opts)
mol, err := molecule.BuildMoleculeFromOCI(opts)
if err != nil {
return err
}
Expand All @@ -206,5 +208,5 @@ func doAtomfsUmount(ctx *cli.Context) error {
}

mountpoint := ctx.Args().Get(0)
return atomfs.Umount(mountpoint)
return molecule.Umount(mountpoint)
}
6 changes: 3 additions & 3 deletions cmd/stacker/publish.go
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@ package main
import (
"github.com/pkg/errors"
cli "github.com/urfave/cli/v2"
"machinerun.io/atomfs/squashfs"
"machinerun.io/atomfs/pkg/verity"
"stackerbuild.io/stacker/pkg/lib"
"stackerbuild.io/stacker/pkg/stacker"
"stackerbuild.io/stacker/pkg/types"
Expand Down Expand Up @@ -69,7 +69,7 @@ var publishCmd = cli.Command{
},
&cli.StringSliceFlag{
Name: "layer-type",
Usage: "set the output layer type (supported values: tar, squashfs); can be supplied multiple times",
Usage: "set the output layer type (supported values: tar, squashfs, erofs); can be supplied multiple times",
Value: cli.NewStringSlice("tar"),
},
&cli.StringSliceFlag{
Expand Down Expand Up @@ -108,7 +108,7 @@ func beforePublish(ctx *cli.Context) error {
}

func doPublish(ctx *cli.Context) error {
verity := squashfs.VerityMetadata(!ctx.Bool("no-squashfs-verity"))
verity := verity.VerityMetadata(!ctx.Bool("no-verity"))
layerTypes, err := types.NewLayerTypes(ctx.StringSlice("layer-type"), verity)
if err != nil {
return err
Expand Down
2 changes: 2 additions & 0 deletions cmd/stacker/validate.go
Original file line number Diff line number Diff line change
Expand Up @@ -50,6 +50,8 @@ func validateLayerTypeFlags(ctx *cli.Context) error {
break
case "squashfs":
break
case "erofs":
break
default:
return errors.Errorf("unknown layer type: %s", layerType)
}
Expand Down
1 change: 1 addition & 0 deletions go.mod
Original file line number Diff line number Diff line change
Expand Up @@ -289,5 +289,6 @@ require (

replace (
github.com/opencontainers/umoci => github.com/project-stacker/umoci v0.0.0-20240906174318-e9397ba4ced0
machinerun.io/atomfs => github.com/rchincha/atomfs v0.0.0-20241110073635-4f4ab76866e4
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 @@ -818,6 +818,8 @@ github.com/prometheus/procfs v0.0.8/go.mod h1:7Qr8sr6344vo1JqZ6HhLceV9o3AJ1Ff+Gx
github.com/prometheus/procfs v0.6.0/go.mod h1:cz+aTbrPOrUb4q7XlbU9ygM+/jj0fzG6c1xBZuNvfVA=
github.com/prometheus/procfs v0.12.0 h1:jluTpSng7V9hY0O2R9DzzJHYb2xULk9VTR1V1R/k6Bo=
github.com/prometheus/procfs v0.12.0/go.mod h1:pcuDEFsWDnvcgNzo4EEweacyhjeA9Zk3cnaOZAZEfOo=
github.com/rchincha/atomfs v0.0.0-20241110073635-4f4ab76866e4 h1:yF7enH6V5n922jlnZDXP8DA1H1wcAdRYs4vmAW8GNz0=
github.com/rchincha/atomfs v0.0.0-20241110073635-4f4ab76866e4/go.mod h1:cidyEmsNeeo+9f7OiHl/nA+8KS7Vj5XOslR87VkIebM=
github.com/remyoudompheng/bigfft v0.0.0-20230129092748-24d4a6f8daec h1:W09IVJc94icq4NjY3clb7Lk8O1qJ8BdBEF8z0ibU0rE=
github.com/remyoudompheng/bigfft v0.0.0-20230129092748-24d4a6f8daec/go.mod h1:qqbHyh8v60DhA7CoWK5oRCqLrMHRGoxYCSS9EjAz6Eo=
github.com/rivo/uniseg v0.2.0/go.mod h1:J6wj4VEh+S6ZtnVlnTBMWIodfgj8LQOQFoIToxlJtxc=
Expand Down Expand Up @@ -1592,8 +1594,6 @@ honnef.co/go/tools v0.0.0-20190523083050-ea95bdfd59fc/go.mod h1:rf3lG4BRIbNafJWh
honnef.co/go/tools v0.0.1-2019.2.3/go.mod h1:a3bituU0lyd329TUQxRnasdCoJDkEUEAqEt0JzvZhAg=
honnef.co/go/tools v0.0.1-2020.1.3/go.mod h1:X/FiERA/W4tHapMX5mGpAtMSVEeEUOyHaw9vFzvIQ3k=
honnef.co/go/tools v0.0.1-2020.1.4/go.mod h1:X/FiERA/W4tHapMX5mGpAtMSVEeEUOyHaw9vFzvIQ3k=
machinerun.io/atomfs v1.1.1 h1:EprTiYMzAlKL+3S7woe9DsCJGwO2dkHTlvmjlVNO8pY=
machinerun.io/atomfs v1.1.1/go.mod h1:cidyEmsNeeo+9f7OiHl/nA+8KS7Vj5XOslR87VkIebM=
modernc.org/libc v1.37.6 h1:orZH3c5wmhIQFTXF+Nt+eeauyd+ZIt2BX6ARe+kD+aw=
modernc.org/libc v1.37.6/go.mod h1:YAXkAZ8ktnkCKaN9sw/UDeUVkGYJ/YquGO4FTi5nmHE=
modernc.org/mathutil v1.6.0 h1:fRe9+AmYlaej+64JsEEhoWuAYBkOtQiMEU7n/XgfYi4=
Expand Down
2 changes: 1 addition & 1 deletion pkg/lib/image_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,7 @@ import (
"github.com/opencontainers/umoci/mutate"
"github.com/opencontainers/umoci/oci/casext"
"github.com/stretchr/testify/assert"
"machinerun.io/atomfs/squashfs"
"machinerun.io/atomfs/pkg/squashfs"
)

func createImage(dir string, tag string) error {
Expand Down
2 changes: 1 addition & 1 deletion pkg/overlay/metadata.go
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,7 @@ import (
ispec "github.com/opencontainers/image-spec/specs-go/v1"
"github.com/opencontainers/umoci/oci/casext"
"github.com/pkg/errors"
stackeroci "machinerun.io/atomfs/oci"
stackeroci "machinerun.io/atomfs/pkg/oci"
"stackerbuild.io/stacker/pkg/log"
"stackerbuild.io/stacker/pkg/types"
)
Expand Down
17 changes: 10 additions & 7 deletions pkg/overlay/pack.go
Original file line number Diff line number Diff line change
Expand Up @@ -22,8 +22,9 @@ import (
"github.com/opencontainers/umoci/oci/layer"
"github.com/pkg/errors"
"github.com/pkg/xattr"
stackeroci "machinerun.io/atomfs/oci"
"machinerun.io/atomfs/squashfs"
stackerfs "machinerun.io/atomfs/pkg/fs"
stackeroci "machinerun.io/atomfs/pkg/oci"
"machinerun.io/atomfs/pkg/verity"
"stackerbuild.io/stacker/pkg/lib"
"stackerbuild.io/stacker/pkg/log"
"stackerbuild.io/stacker/pkg/storage"
Expand Down Expand Up @@ -280,7 +281,8 @@ func generateBlob(layerType types.LayerType, contents string, ociDir string, low
blob = layer.GenerateInsertLayer(contents, "/", false, &packOptions)
mediaType = ispec.MediaTypeImageLayer
} else {
blob, mediaType, rootHash, err = squashfs.MakeSquashfs(ociDir, contents, nil, layerType.Verity)
fsi := stackerfs.New(stackerfs.FilesystemType(layerType.Type))
blob, mediaType, rootHash, err = fsi.Make(ociDir, contents, nil, layerType.Verity)
if err != nil {
return nil, "", "", err
}
Expand All @@ -303,7 +305,7 @@ func ociPutBlob(blob io.ReadCloser, config types.StackerConfig, layerMediaType s

annotations := map[string]string{}
if rootHash != "" {
annotations[squashfs.VerityRootHashAnnotation] = rootHash
annotations[verity.VerityRootHashAnnotation] = rootHash
}

desc := ispec.Descriptor{
Expand Down Expand Up @@ -443,7 +445,7 @@ func generateLayer(config types.StackerConfig, _ casext.Engine, mutators []*muta
} else {
annotations := map[string]string{}
if rootHash != "" {
annotations[squashfs.VerityRootHashAnnotation] = rootHash
annotations[verity.VerityRootHashAnnotation] = rootHash
}
desc, err = mutator.Add(context.Background(), mediaType, blob, history, mutate.NoopCompressor, annotations)
if err != nil {
Expand Down Expand Up @@ -693,10 +695,11 @@ func unpackOne(l ispec.Descriptor, ociDir string, extractDir string) error {
return nil
}

if squashfs.IsSquashfsMediaType(l.MediaType) {
return squashfs.ExtractSingleSquash(
if fsi := stackerfs.NewFromMediaType(l.MediaType); fsi != nil {
return fsi.ExtractSingle(
path.Join(ociDir, "blobs", "sha256", l.Digest.Encoded()), extractDir)
}

switch l.MediaType {
case ispec.MediaTypeImageLayer, ispec.MediaTypeImageLayerGzip:
tarEx.Lock()
Expand Down
37 changes: 24 additions & 13 deletions pkg/types/layer_type.go
Original file line number Diff line number Diff line change
Expand Up @@ -7,14 +7,16 @@ import (

ispec "github.com/opencontainers/image-spec/specs-go/v1"
"github.com/pkg/errors"
"machinerun.io/atomfs/squashfs"
"machinerun.io/atomfs/pkg/erofs"
"machinerun.io/atomfs/pkg/squashfs"
"machinerun.io/atomfs/pkg/verity"
)

var ErrEmptyLayers = errors.New("empty layers")

type LayerType struct {
Type string
Verity squashfs.VerityMetadata
Verity verity.VerityMetadata
}

func (lt LayerType) String() string {
Expand Down Expand Up @@ -44,15 +46,17 @@ func (lt *LayerType) UnmarshalText(text []byte) error {
return errors.Wrapf(err, "bad verity bool: %s", fields[1])
}

lt.Verity = squashfs.VerityMetadata(result)
lt.Verity = verity.VerityMetadata(result)

return nil
}

func NewLayerType(lt string, verity squashfs.VerityMetadata) (LayerType, error) {
func NewLayerType(lt string, verity verity.VerityMetadata) (LayerType, error) {
switch lt {
case "squashfs":
return LayerType{Type: lt, Verity: verity}, nil
case "erofs":
return LayerType{Type: lt, Verity: verity}, nil
case "tar":
return LayerType{Type: lt}, nil
default:
Expand All @@ -62,31 +66,38 @@ func NewLayerType(lt string, verity squashfs.VerityMetadata) (LayerType, error)

func NewLayerTypeManifest(manifest ispec.Manifest) (LayerType, error) {
if len(manifest.Layers) == 0 {
return NewLayerType("tar", squashfs.VerityMetadataMissing)
return NewLayerType("tar", verity.VerityMetadataMissing)
}

switch manifest.Layers[0].MediaType {
case squashfs.BaseMediaTypeLayerSquashfs:
// older stackers generated media types without compression information
fallthrough
case squashfs.GenerateSquashfsMediaType(squashfs.GzipCompression, squashfs.VerityMetadataMissing):
case squashfs.GenerateSquashfsMediaType(squashfs.GzipCompression, verity.VerityMetadataMissing):
fallthrough
case squashfs.GenerateSquashfsMediaType(squashfs.ZstdCompression, verity.VerityMetadataMissing):
return NewLayerType("squashfs", verity.VerityMetadataMissing)
case squashfs.GenerateSquashfsMediaType(squashfs.GzipCompression, verity.VerityMetadataPresent):
fallthrough
case squashfs.GenerateSquashfsMediaType(squashfs.ZstdCompression, squashfs.VerityMetadataMissing):
return NewLayerType("squashfs", squashfs.VerityMetadataMissing)
case squashfs.GenerateSquashfsMediaType(squashfs.GzipCompression, squashfs.VerityMetadataPresent):
case squashfs.GenerateSquashfsMediaType(squashfs.ZstdCompression, verity.VerityMetadataPresent):
return NewLayerType("squashfs", verity.VerityMetadataPresent)
case erofs.BaseMediaTypeLayerErofs:
// older stackers generated media types without compression information
fallthrough
case squashfs.GenerateSquashfsMediaType(squashfs.ZstdCompression, squashfs.VerityMetadataPresent):
return NewLayerType("squashfs", squashfs.VerityMetadataPresent)
case erofs.GenerateErofsMediaType(erofs.GzipCompression, verity.VerityMetadataMissing):
return NewLayerType("erofs", verity.VerityMetadataMissing)
case erofs.GenerateErofsMediaType(erofs.GzipCompression, verity.VerityMetadataPresent):
return NewLayerType("erofs", verity.VerityMetadataPresent)
case ispec.MediaTypeImageLayerGzip:
fallthrough
case ispec.MediaTypeImageLayer:
return NewLayerType("tar", squashfs.VerityMetadataMissing)
return NewLayerType("tar", verity.VerityMetadataMissing)
default:
return LayerType{}, errors.Errorf("invalid layer type %s", manifest.Layers[0].MediaType)
}
}

func NewLayerTypes(lts []string, verity squashfs.VerityMetadata) ([]LayerType, error) {
func NewLayerTypes(lts []string, verity verity.VerityMetadata) ([]LayerType, error) {
ret := []LayerType{}
for _, lt := range lts {
hoisted, err := NewLayerType(lt, verity)
Expand Down

0 comments on commit 284c7f5

Please sign in to comment.