Skip to content

Commit 7814fb5

Browse files
committed
feat: add support for erofs layers
atomfs has added support for additional filesystem types such as erofs. Signed-off-by: Ramkumar Chinchani <[email protected]>
1 parent ad9a694 commit 7814fb5

File tree

11 files changed

+59
-39
lines changed

11 files changed

+59
-39
lines changed

cmd/stacker/build.go

+5-5
Original file line numberDiff line numberDiff line change
@@ -4,7 +4,7 @@ import (
44
"fmt"
55

66
cli "github.com/urfave/cli/v2"
7-
"machinerun.io/atomfs/squashfs"
7+
"machinerun.io/atomfs/pkg/verity"
88
"stackerbuild.io/stacker/pkg/stacker"
99
"stackerbuild.io/stacker/pkg/types"
1010
)
@@ -52,12 +52,12 @@ func initCommonBuildFlags() []cli.Flag {
5252
},
5353
&cli.StringSliceFlag{
5454
Name: "layer-type",
55-
Usage: "set the output layer type (supported values: tar, squashfs); can be supplied multiple times",
55+
Usage: "set the output layer type (supported values: tar, squashfs, erofs); can be supplied multiple times",
5656
Value: cli.NewStringSlice("tar"),
5757
},
5858
&cli.BoolFlag{
59-
Name: "no-squashfs-verity",
60-
Usage: "do not append dm-verity data to squashfs archives",
59+
Name: "no-verity",
60+
Usage: "do not append dm-verity data to fs archives",
6161
},
6262
&cli.BoolFlag{
6363
Name: "require-hash",
@@ -103,7 +103,7 @@ func newBuildArgs(ctx *cli.Context) (stacker.BuildArgs, error) {
103103
AnnotationsNamespace: ctx.String("annotations-namespace"),
104104
}
105105
var err error
106-
verity := squashfs.VerityMetadata(!ctx.Bool("no-squashfs-verity"))
106+
verity := verity.VerityMetadata(!ctx.Bool("no-verity"))
107107
args.LayerTypes, err = types.NewLayerTypes(ctx.StringSlice("layer-type"), verity)
108108
return args, err
109109
}

cmd/stacker/inspect.go

+1-1
Original file line numberDiff line numberDiff line change
@@ -11,7 +11,7 @@ import (
1111
"github.com/opencontainers/umoci/oci/casext"
1212
"github.com/pkg/errors"
1313
cli "github.com/urfave/cli/v2"
14-
stackeroci "machinerun.io/atomfs/oci"
14+
stackeroci "machinerun.io/atomfs/pkg/oci"
1515
)
1616

1717
var inspectCmd = cli.Command{

cmd/stacker/internal_go.go

+7-5
Original file line numberDiff line numberDiff line change
@@ -10,7 +10,7 @@ import (
1010
"github.com/pkg/errors"
1111
cli "github.com/urfave/cli/v2"
1212
"golang.org/x/sys/unix"
13-
"machinerun.io/atomfs"
13+
"machinerun.io/atomfs/pkg/molecule"
1414
"stackerbuild.io/stacker/pkg/lib"
1515
"stackerbuild.io/stacker/pkg/log"
1616
"stackerbuild.io/stacker/pkg/overlay"
@@ -182,15 +182,17 @@ func doAtomfsMount(ctx *cli.Context) error {
182182
return errors.WithStack(err)
183183
}
184184

185-
opts := atomfs.MountOCIOpts{
185+
opts := molecule.MountOCIOpts{
186186
OCIDir: config.OCIDir,
187-
MetadataPath: path.Join(wd, "atomfs-metadata"),
188187
Tag: tag,
189188
Target: mountpoint,
189+
AddWriteableOverlay: false,
190+
WriteableOverlayPath: "",
190191
AllowMissingVerityData: true,
192+
MetadataDir: path.Join(wd, "atomfs-metadata"),
191193
}
192194

193-
mol, err := atomfs.BuildMoleculeFromOCI(opts)
195+
mol, err := molecule.BuildMoleculeFromOCI(opts)
194196
if err != nil {
195197
return err
196198
}
@@ -206,5 +208,5 @@ func doAtomfsUmount(ctx *cli.Context) error {
206208
}
207209

208210
mountpoint := ctx.Args().Get(0)
209-
return atomfs.Umount(mountpoint)
211+
return molecule.Umount(mountpoint)
210212
}

cmd/stacker/publish.go

+3-3
Original file line numberDiff line numberDiff line change
@@ -3,7 +3,7 @@ package main
33
import (
44
"github.com/pkg/errors"
55
cli "github.com/urfave/cli/v2"
6-
"machinerun.io/atomfs/squashfs"
6+
"machinerun.io/atomfs/pkg/verity"
77
"stackerbuild.io/stacker/pkg/lib"
88
"stackerbuild.io/stacker/pkg/stacker"
99
"stackerbuild.io/stacker/pkg/types"
@@ -69,7 +69,7 @@ var publishCmd = cli.Command{
6969
},
7070
&cli.StringSliceFlag{
7171
Name: "layer-type",
72-
Usage: "set the output layer type (supported values: tar, squashfs); can be supplied multiple times",
72+
Usage: "set the output layer type (supported values: tar, squashfs, erofs); can be supplied multiple times",
7373
Value: cli.NewStringSlice("tar"),
7474
},
7575
&cli.StringSliceFlag{
@@ -108,7 +108,7 @@ func beforePublish(ctx *cli.Context) error {
108108
}
109109

110110
func doPublish(ctx *cli.Context) error {
111-
verity := squashfs.VerityMetadata(!ctx.Bool("no-squashfs-verity"))
111+
verity := verity.VerityMetadata(!ctx.Bool("no-verity"))
112112
layerTypes, err := types.NewLayerTypes(ctx.StringSlice("layer-type"), verity)
113113
if err != nil {
114114
return err

cmd/stacker/validate.go

+2
Original file line numberDiff line numberDiff line change
@@ -50,6 +50,8 @@ func validateLayerTypeFlags(ctx *cli.Context) error {
5050
break
5151
case "squashfs":
5252
break
53+
case "erofs":
54+
break
5355
default:
5456
return errors.Errorf("unknown layer type: %s", layerType)
5557
}

go.mod

+1
Original file line numberDiff line numberDiff line change
@@ -289,5 +289,6 @@ require (
289289

290290
replace (
291291
github.com/opencontainers/umoci => github.com/project-stacker/umoci v0.0.0-20240906174318-e9397ba4ced0
292+
machinerun.io/atomfs => github.com/rchincha/atomfs v0.0.0-20241110073635-4f4ab76866e4
292293
stackerbuild.io/stacker-bom => github.com/project-stacker/stacker-bom v0.0.0-20240509203427-4d685e046780
293294
)

go.sum

+2-2
Original file line numberDiff line numberDiff line change
@@ -818,6 +818,8 @@ github.com/prometheus/procfs v0.0.8/go.mod h1:7Qr8sr6344vo1JqZ6HhLceV9o3AJ1Ff+Gx
818818
github.com/prometheus/procfs v0.6.0/go.mod h1:cz+aTbrPOrUb4q7XlbU9ygM+/jj0fzG6c1xBZuNvfVA=
819819
github.com/prometheus/procfs v0.12.0 h1:jluTpSng7V9hY0O2R9DzzJHYb2xULk9VTR1V1R/k6Bo=
820820
github.com/prometheus/procfs v0.12.0/go.mod h1:pcuDEFsWDnvcgNzo4EEweacyhjeA9Zk3cnaOZAZEfOo=
821+
github.com/rchincha/atomfs v0.0.0-20241110073635-4f4ab76866e4 h1:yF7enH6V5n922jlnZDXP8DA1H1wcAdRYs4vmAW8GNz0=
822+
github.com/rchincha/atomfs v0.0.0-20241110073635-4f4ab76866e4/go.mod h1:cidyEmsNeeo+9f7OiHl/nA+8KS7Vj5XOslR87VkIebM=
821823
github.com/remyoudompheng/bigfft v0.0.0-20230129092748-24d4a6f8daec h1:W09IVJc94icq4NjY3clb7Lk8O1qJ8BdBEF8z0ibU0rE=
822824
github.com/remyoudompheng/bigfft v0.0.0-20230129092748-24d4a6f8daec/go.mod h1:qqbHyh8v60DhA7CoWK5oRCqLrMHRGoxYCSS9EjAz6Eo=
823825
github.com/rivo/uniseg v0.2.0/go.mod h1:J6wj4VEh+S6ZtnVlnTBMWIodfgj8LQOQFoIToxlJtxc=
@@ -1592,8 +1594,6 @@ honnef.co/go/tools v0.0.0-20190523083050-ea95bdfd59fc/go.mod h1:rf3lG4BRIbNafJWh
15921594
honnef.co/go/tools v0.0.1-2019.2.3/go.mod h1:a3bituU0lyd329TUQxRnasdCoJDkEUEAqEt0JzvZhAg=
15931595
honnef.co/go/tools v0.0.1-2020.1.3/go.mod h1:X/FiERA/W4tHapMX5mGpAtMSVEeEUOyHaw9vFzvIQ3k=
15941596
honnef.co/go/tools v0.0.1-2020.1.4/go.mod h1:X/FiERA/W4tHapMX5mGpAtMSVEeEUOyHaw9vFzvIQ3k=
1595-
machinerun.io/atomfs v1.1.1 h1:EprTiYMzAlKL+3S7woe9DsCJGwO2dkHTlvmjlVNO8pY=
1596-
machinerun.io/atomfs v1.1.1/go.mod h1:cidyEmsNeeo+9f7OiHl/nA+8KS7Vj5XOslR87VkIebM=
15971597
modernc.org/libc v1.37.6 h1:orZH3c5wmhIQFTXF+Nt+eeauyd+ZIt2BX6ARe+kD+aw=
15981598
modernc.org/libc v1.37.6/go.mod h1:YAXkAZ8ktnkCKaN9sw/UDeUVkGYJ/YquGO4FTi5nmHE=
15991599
modernc.org/mathutil v1.6.0 h1:fRe9+AmYlaej+64JsEEhoWuAYBkOtQiMEU7n/XgfYi4=

pkg/lib/image_test.go

+3-2
Original file line numberDiff line numberDiff line change
@@ -13,7 +13,8 @@ import (
1313
"github.com/opencontainers/umoci/mutate"
1414
"github.com/opencontainers/umoci/oci/casext"
1515
"github.com/stretchr/testify/assert"
16-
"machinerun.io/atomfs/squashfs"
16+
"machinerun.io/atomfs/pkg/squashfs"
17+
"machinerun.io/atomfs/pkg/verity"
1718
)
1819

1920
func createImage(dir string, tag string) error {
@@ -48,7 +49,7 @@ func createImage(dir string, tag string) error {
4849

4950
// need *something* in the layer, why not just recursively include the
5051
// OCI image for maximum confusion :)
51-
layer, mediaType, _, err := squashfs.MakeSquashfs(dir, path.Join(dir, "oci"), nil, squashfs.VerityMetadataMissing)
52+
layer, mediaType, _, err := squashfs.MakeSquashfs(dir, path.Join(dir, "oci"), nil, verity.VerityMetadataMissing)
5253
if err != nil {
5354
return err
5455
}

pkg/overlay/metadata.go

+1-1
Original file line numberDiff line numberDiff line change
@@ -10,7 +10,7 @@ import (
1010
ispec "github.com/opencontainers/image-spec/specs-go/v1"
1111
"github.com/opencontainers/umoci/oci/casext"
1212
"github.com/pkg/errors"
13-
stackeroci "machinerun.io/atomfs/oci"
13+
stackeroci "machinerun.io/atomfs/pkg/oci"
1414
"stackerbuild.io/stacker/pkg/log"
1515
"stackerbuild.io/stacker/pkg/types"
1616
)

pkg/overlay/pack.go

+10-7
Original file line numberDiff line numberDiff line change
@@ -22,8 +22,9 @@ import (
2222
"github.com/opencontainers/umoci/oci/layer"
2323
"github.com/pkg/errors"
2424
"github.com/pkg/xattr"
25-
stackeroci "machinerun.io/atomfs/oci"
26-
"machinerun.io/atomfs/squashfs"
25+
stackerfs "machinerun.io/atomfs/pkg/fs"
26+
stackeroci "machinerun.io/atomfs/pkg/oci"
27+
"machinerun.io/atomfs/pkg/verity"
2728
"stackerbuild.io/stacker/pkg/lib"
2829
"stackerbuild.io/stacker/pkg/log"
2930
"stackerbuild.io/stacker/pkg/storage"
@@ -280,7 +281,8 @@ func generateBlob(layerType types.LayerType, contents string, ociDir string, low
280281
blob = layer.GenerateInsertLayer(contents, "/", false, &packOptions)
281282
mediaType = ispec.MediaTypeImageLayer
282283
} else {
283-
blob, mediaType, rootHash, err = squashfs.MakeSquashfs(ociDir, contents, nil, layerType.Verity)
284+
fsi := stackerfs.New(stackerfs.FilesystemType(layerType.Type))
285+
blob, mediaType, rootHash, err = fsi.Make(ociDir, contents, nil, layerType.Verity)
284286
if err != nil {
285287
return nil, "", "", err
286288
}
@@ -303,7 +305,7 @@ func ociPutBlob(blob io.ReadCloser, config types.StackerConfig, layerMediaType s
303305

304306
annotations := map[string]string{}
305307
if rootHash != "" {
306-
annotations[squashfs.VerityRootHashAnnotation] = rootHash
308+
annotations[verity.VerityRootHashAnnotation] = rootHash
307309
}
308310

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

696-
if squashfs.IsSquashfsMediaType(l.MediaType) {
697-
return squashfs.ExtractSingleSquash(
698+
if fsi := stackerfs.NewFromMediaType(l.MediaType); fsi != nil {
699+
return fsi.ExtractSingle(
698700
path.Join(ociDir, "blobs", "sha256", l.Digest.Encoded()), extractDir)
699701
}
702+
700703
switch l.MediaType {
701704
case ispec.MediaTypeImageLayer, ispec.MediaTypeImageLayerGzip:
702705
tarEx.Lock()

pkg/types/layer_type.go

+24-13
Original file line numberDiff line numberDiff line change
@@ -7,14 +7,16 @@ import (
77

88
ispec "github.com/opencontainers/image-spec/specs-go/v1"
99
"github.com/pkg/errors"
10-
"machinerun.io/atomfs/squashfs"
10+
"machinerun.io/atomfs/pkg/erofs"
11+
"machinerun.io/atomfs/pkg/squashfs"
12+
"machinerun.io/atomfs/pkg/verity"
1113
)
1214

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

1517
type LayerType struct {
1618
Type string
17-
Verity squashfs.VerityMetadata
19+
Verity verity.VerityMetadata
1820
}
1921

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

47-
lt.Verity = squashfs.VerityMetadata(result)
49+
lt.Verity = verity.VerityMetadata(result)
4850

4951
return nil
5052
}
5153

52-
func NewLayerType(lt string, verity squashfs.VerityMetadata) (LayerType, error) {
54+
func NewLayerType(lt string, verity verity.VerityMetadata) (LayerType, error) {
5355
switch lt {
5456
case "squashfs":
5557
return LayerType{Type: lt, Verity: verity}, nil
58+
case "erofs":
59+
return LayerType{Type: lt, Verity: verity}, nil
5660
case "tar":
5761
return LayerType{Type: lt}, nil
5862
default:
@@ -62,31 +66,38 @@ func NewLayerType(lt string, verity squashfs.VerityMetadata) (LayerType, error)
6266

6367
func NewLayerTypeManifest(manifest ispec.Manifest) (LayerType, error) {
6468
if len(manifest.Layers) == 0 {
65-
return NewLayerType("tar", squashfs.VerityMetadataMissing)
69+
return NewLayerType("tar", verity.VerityMetadataMissing)
6670
}
6771

6872
switch manifest.Layers[0].MediaType {
6973
case squashfs.BaseMediaTypeLayerSquashfs:
7074
// older stackers generated media types without compression information
7175
fallthrough
72-
case squashfs.GenerateSquashfsMediaType(squashfs.GzipCompression, squashfs.VerityMetadataMissing):
76+
case squashfs.GenerateSquashfsMediaType(squashfs.GzipCompression, verity.VerityMetadataMissing):
77+
fallthrough
78+
case squashfs.GenerateSquashfsMediaType(squashfs.ZstdCompression, verity.VerityMetadataMissing):
79+
return NewLayerType("squashfs", verity.VerityMetadataMissing)
80+
case squashfs.GenerateSquashfsMediaType(squashfs.GzipCompression, verity.VerityMetadataPresent):
7381
fallthrough
74-
case squashfs.GenerateSquashfsMediaType(squashfs.ZstdCompression, squashfs.VerityMetadataMissing):
75-
return NewLayerType("squashfs", squashfs.VerityMetadataMissing)
76-
case squashfs.GenerateSquashfsMediaType(squashfs.GzipCompression, squashfs.VerityMetadataPresent):
82+
case squashfs.GenerateSquashfsMediaType(squashfs.ZstdCompression, verity.VerityMetadataPresent):
83+
return NewLayerType("squashfs", verity.VerityMetadataPresent)
84+
case erofs.BaseMediaTypeLayerErofs:
85+
// older stackers generated media types without compression information
7786
fallthrough
78-
case squashfs.GenerateSquashfsMediaType(squashfs.ZstdCompression, squashfs.VerityMetadataPresent):
79-
return NewLayerType("squashfs", squashfs.VerityMetadataPresent)
87+
case erofs.GenerateErofsMediaType(erofs.GzipCompression, verity.VerityMetadataMissing):
88+
return NewLayerType("erofs", verity.VerityMetadataMissing)
89+
case erofs.GenerateErofsMediaType(erofs.GzipCompression, verity.VerityMetadataPresent):
90+
return NewLayerType("erofs", verity.VerityMetadataPresent)
8091
case ispec.MediaTypeImageLayerGzip:
8192
fallthrough
8293
case ispec.MediaTypeImageLayer:
83-
return NewLayerType("tar", squashfs.VerityMetadataMissing)
94+
return NewLayerType("tar", verity.VerityMetadataMissing)
8495
default:
8596
return LayerType{}, errors.Errorf("invalid layer type %s", manifest.Layers[0].MediaType)
8697
}
8798
}
8899

89-
func NewLayerTypes(lts []string, verity squashfs.VerityMetadata) ([]LayerType, error) {
100+
func NewLayerTypes(lts []string, verity verity.VerityMetadata) ([]LayerType, error) {
90101
ret := []LayerType{}
91102
for _, lt := range lts {
92103
hoisted, err := NewLayerType(lt, verity)

0 commit comments

Comments
 (0)