diff --git a/cmd/convertor/builder/builder.go b/cmd/convertor/builder/builder.go index 932296f8..c0ab2b10 100644 --- a/cmd/convertor/builder/builder.go +++ b/cmd/convertor/builder/builder.go @@ -54,6 +54,7 @@ type BuilderOptions struct { PlainHTTP bool WorkDir string OCI bool + FsType string Mkfs bool Vsize int DB database.ConversionDatabase @@ -234,6 +235,7 @@ func (b *graphBuilder) buildOne(ctx context.Context, src v1.Descriptor, tag bool } engineBase.workDir = workdir engineBase.oci = b.OCI + engineBase.fstype = b.FsType engineBase.mkfs = b.Mkfs engineBase.vsize = b.Vsize engineBase.db = b.DB diff --git a/cmd/convertor/builder/builder_engine.go b/cmd/convertor/builder/builder_engine.go index b664a3f3..a8351c25 100644 --- a/cmd/convertor/builder/builder_engine.go +++ b/cmd/convertor/builder/builder_engine.go @@ -85,6 +85,7 @@ type builderEngineBase struct { config specs.Image workDir string oci bool + fstype string mkfs bool vsize int db database.ConversionDatabase diff --git a/cmd/convertor/builder/turboOCI_builder.go b/cmd/convertor/builder/turboOCI_builder.go index 83ffeeb9..e4789bf1 100644 --- a/cmd/convertor/builder/turboOCI_builder.go +++ b/cmd/convertor/builder/turboOCI_builder.go @@ -41,7 +41,7 @@ const ( gzipMetaFile = "gzip.meta" // index of block device - fsMetaFile = "ext4.fs.meta" + fsMetaFileSuffix = ".fs.meta" // foci index layer (gzip) tociLayerTar = "turboOCIv1.tar.gz" @@ -103,12 +103,21 @@ func (e *turboOCIBuilderEngine) BuildLayer(ctx context.Context, idx int) error { if err := e.apply(ctx, layerDir); err != nil { return err } - if err := e.commit(ctx, layerDir); err != nil { + + var fsMetaFile string + if e.fstype == "" { + fsMetaFile = "ext4" + fsMetaFileSuffix + } else { + fsMetaFile = e.fstype + fsMetaFileSuffix + } + + if err := e.commit(ctx, layerDir, fsMetaFile); err != nil { return err } if err := e.createIdentifier(idx); err != nil { return errors.Wrapf(err, "failed to create identifier %q", tociIdentifier) } + files := []string{ path.Join(layerDir, fsMetaFile), path.Join(layerDir, tociIdentifier), @@ -249,7 +258,7 @@ func (e *turboOCIBuilderEngine) create(ctx context.Context, dir string, mkfs boo vsizeGB = e.vsize } opts := []string{"-s", fmt.Sprintf("%d", vsizeGB), "--turboOCI"} - if mkfs { + if mkfs && e.fstype != "erofs" { opts = append(opts, "--mkfs") logrus.Infof("mkfs for baselayer, vsize: %d GB", vsizeGB) } @@ -257,10 +266,14 @@ func (e *turboOCIBuilderEngine) create(ctx context.Context, dir string, mkfs boo } func (e *turboOCIBuilderEngine) apply(ctx context.Context, dir string) error { + if e.fstype != "" { + opts := []string{"--fstype", e.fstype} + return utils.ApplyTurboOCI(ctx, dir, gzipMetaFile, opts...) + } return utils.ApplyTurboOCI(ctx, dir, gzipMetaFile) } -func (e *turboOCIBuilderEngine) commit(ctx context.Context, dir string) error { +func (e *turboOCIBuilderEngine) commit(ctx context.Context, dir string, fsMetaFile string) error { if err := utils.Commit(ctx, dir, dir, false, "-z", "--fastoci"); err != nil { return err } diff --git a/cmd/convertor/main.go b/cmd/convertor/main.go index 9b9bdafc..76e5dc80 100644 --- a/cmd/convertor/main.go +++ b/cmd/convertor/main.go @@ -39,6 +39,7 @@ var ( tagOutput string dir string oci bool + fsType string mkfs bool verbose bool vsize int @@ -93,6 +94,7 @@ Version: ` + commitID, PlainHTTP: plain, WorkDir: dir, OCI: oci, + FsType: fsType, Mkfs: mkfs, Vsize: vsize, CertOption: builder.CertOption{ @@ -159,6 +161,7 @@ func init() { rootCmd.Flags().StringVarP(&tagOutput, "output-tag", "o", "", "tag for image converting to") rootCmd.Flags().StringVarP(&dir, "dir", "d", "tmp_conv", "directory used for temporary data") rootCmd.Flags().BoolVarP(&oci, "oci", "", false, "export image with oci spec") + rootCmd.Flags().StringVar(&fsType, "fstype", "ext4", "filesystem type of converted image. Default ext4") rootCmd.Flags().BoolVarP(&mkfs, "mkfs", "", true, "make ext4 fs in bottom layer") rootCmd.Flags().IntVarP(&vsize, "vsize", "", 64, "virtual block device size (GB)") rootCmd.Flags().StringVar(&fastoci, "fastoci", "", "build 'Overlaybd-Turbo OCIv1' format (old name of turboOCIv1. deprecated)") diff --git a/pkg/snapshot/overlay.go b/pkg/snapshot/overlay.go index 597c5df6..b61e0b10 100644 --- a/pkg/snapshot/overlay.go +++ b/pkg/snapshot/overlay.go @@ -574,8 +574,12 @@ func (o *snapshotter) createMountPoint(ctx context.Context, kind snapshots.Kind, } fsType, ok := obdInfo.Labels[label.OverlayBDBlobFsType] if !ok { - log.G(ctx).Warnf("cannot get fs type from label, %v, using %s", obdInfo.Labels, o.defaultFsType) - fsType = o.defaultFsType + if isTurboOCI, _, _ := o.checkTurboOCI(obdInfo.Labels); isTurboOCI { + _, fsType = o.turboOCIFsMeta(obdID) + } else { + fsType = o.defaultFsType + } + log.G(ctx).Warnf("cannot get fs type from label, %v, using %s", obdInfo.Labels, fsType) } log.G(ctx).Debugf("attachAndMountBlockDevice (obdID: %s, writeType: %s, fsType %s, targetPath: %s)", obdID, writeType, fsType, o.overlaybdTargetPath(obdID)) @@ -733,7 +737,11 @@ func (o *snapshotter) Mounts(ctx context.Context, key string) (_ []mount.Mount, if parentStype == storageTypeRemoteBlock || parentStype == storageTypeLocalBlock { fsType, ok := parentInfo.Labels[label.OverlayBDBlobFsType] if !ok { - fsType = o.defaultFsType + if isTurboOCI, _, _ := o.checkTurboOCI(parentInfo.Labels); isTurboOCI { + _, fsType = o.turboOCIFsMeta(parentID) + } else { + fsType = o.defaultFsType + } } if err := o.attachAndMountBlockDevice(ctx, parentID, RoDir, fsType, false); err != nil { return nil, errors.Wrapf(err, "failed to attach and mount for snapshot %v", key) @@ -1355,8 +1363,13 @@ func (o *snapshotter) blockPath(id string) string { return filepath.Join(o.root, "snapshots", id, "block") } -func (o *snapshotter) turboOCIFsMeta(id string) string { - return filepath.Join(o.root, "snapshots", id, "fs", "ext4.fs.meta") +func (o *snapshotter) turboOCIFsMeta(id string) (string, string) { + // TODO: make the priority order (multi-meta exists) configurable later if needed + erofsmeta := filepath.Join(o.root, "snapshots", id, "fs", "erofs.fs.meta") + if _, err := os.Stat(erofsmeta); err == nil { + return erofsmeta, "erofs" + } + return filepath.Join(o.root, "snapshots", id, "fs", "ext4.fs.meta"), "ext4" } func (o *snapshotter) magicFilePath(id string) string { diff --git a/pkg/snapshot/storage.go b/pkg/snapshot/storage.go index e99c2f04..704be220 100644 --- a/pkg/snapshot/storage.go +++ b/pkg/snapshot/storage.go @@ -502,10 +502,11 @@ func (o *snapshotter) constructOverlayBDSpec(ctx context.Context, key string, wr configJSON.RepoBlobURL = blobPrefixURL if isTurboOCI, dataDgst, compType := o.checkTurboOCI(info.Labels); isTurboOCI { + fsmeta, _ := o.turboOCIFsMeta(id) lower := sn.OverlayBDBSConfigLower{ Dir: o.upperPath(id), // keep this to support ondemand turboOCI loading. - File: o.turboOCIFsMeta(id), + File: fsmeta, TargetDigest: dataDgst, } if isGzipLayerType(compType) { diff --git a/pkg/utils/cmd.go b/pkg/utils/cmd.go index cc4d6b76..19db7d1d 100644 --- a/pkg/utils/cmd.go +++ b/pkg/utils/cmd.go @@ -160,7 +160,7 @@ func ApplyTurboOCI(ctx context.Context, dir, gzipMetaFile string, opts ...string path.Join(dir, "config.json"), "--gz_index_path", path.Join(dir, gzipMetaFile)}, opts...) log.G(ctx).Debugf("%s %s", obdBinApply, strings.Join(args, " ")) - out, err := exec.CommandContext(ctx, obdBinApply, args...).CombinedOutput() + out, err := exec.CommandContext(ctx, obdBinTurboOCIApply, args...).CombinedOutput() if err != nil { return errors.Wrapf(err, "failed to overlaybd-apply[turboOCI]: %s", out) }