diff --git a/cmd/atomfs/mount.go b/cmd/atomfs/mount.go index d0ea6b6..cf80a13 100644 --- a/cmd/atomfs/mount.go +++ b/cmd/atomfs/mount.go @@ -12,7 +12,7 @@ import ( "github.com/urfave/cli" "golang.org/x/sys/unix" "machinerun.io/atomfs" - "machinerun.io/atomfs/squashfs" + "machinerun.io/atomfs/pkg/squashfs" ) var mountCmd = cli.Command{ diff --git a/cmd/atomfs/umount.go b/cmd/atomfs/umount.go index a60a4c1..d650962 100644 --- a/cmd/atomfs/umount.go +++ b/cmd/atomfs/umount.go @@ -7,7 +7,7 @@ import ( "syscall" "github.com/urfave/cli" - "machinerun.io/atomfs/mount" + "machinerun.io/atomfs/pkg/mount" ) var umountCmd = cli.Command{ diff --git a/molecule.go b/molecule.go index 5ba3497..6823faf 100644 --- a/molecule.go +++ b/molecule.go @@ -9,8 +9,8 @@ import ( ispec "github.com/opencontainers/image-spec/specs-go/v1" "github.com/pkg/errors" "golang.org/x/sys/unix" - "machinerun.io/atomfs/mount" - "machinerun.io/atomfs/squashfs" + "machinerun.io/atomfs/pkg/mount" + "machinerun.io/atomfs/pkg/squashfs" ) type Molecule struct { diff --git a/pkg/common/common.go b/pkg/common/common.go new file mode 100644 index 0000000..c83afc6 --- /dev/null +++ b/pkg/common/common.go @@ -0,0 +1,11 @@ +package common + +import "os" + +func FileChanged(a os.FileInfo, path string) bool { + b, err := os.Lstat(path) + if err != nil { + return true + } + return !os.SameFile(a, b) +} diff --git a/erofs/erofs.go b/pkg/erofs/erofs.go similarity index 99% rename from erofs/erofs.go rename to pkg/erofs/erofs.go index e088b71..86d37bc 100644 --- a/erofs/erofs.go +++ b/pkg/erofs/erofs.go @@ -18,8 +18,8 @@ import ( "github.com/Masterminds/semver/v3" "github.com/pkg/errors" "golang.org/x/sys/unix" - "machinerun.io/atomfs/log" - "machinerun.io/atomfs/mount" + "machinerun.io/atomfs/pkg/log" + "machinerun.io/atomfs/pkg/mount" ) var checkZstdSupported sync.Once diff --git a/pkg/erofs/fs.fo b/pkg/erofs/fs.fo new file mode 100644 index 0000000..de39a52 --- /dev/null +++ b/pkg/erofs/fs.fo @@ -0,0 +1,3 @@ +package erofs + +type erofs struct{} diff --git a/erofs/mediatype.go b/pkg/erofs/mediatype.go similarity index 100% rename from erofs/mediatype.go rename to pkg/erofs/mediatype.go diff --git a/erofs/superblock.go b/pkg/erofs/superblock.go similarity index 100% rename from erofs/superblock.go rename to pkg/erofs/superblock.go diff --git a/erofs/verity.go b/pkg/erofs/verity.go similarity index 99% rename from erofs/verity.go rename to pkg/erofs/verity.go index d0ca4d4..d678a90 100644 --- a/erofs/verity.go +++ b/pkg/erofs/verity.go @@ -77,7 +77,7 @@ import ( "github.com/martinjungblut/go-cryptsetup" "github.com/pkg/errors" "golang.org/x/sys/unix" - "machinerun.io/atomfs/mount" + "machinerun.io/atomfs/pkg/mount" ) const VerityRootHashAnnotation = "io.stackeroci.stacker.erofs_verity_root_hash" diff --git a/erofs/verity_static.go b/pkg/erofs/verity_static.go similarity index 100% rename from erofs/verity_static.go rename to pkg/erofs/verity_static.go diff --git a/erofs/verity_test.go b/pkg/erofs/verity_test.go similarity index 100% rename from erofs/verity_test.go rename to pkg/erofs/verity_test.go diff --git a/log/log.go b/pkg/log/log.go similarity index 100% rename from log/log.go rename to pkg/log/log.go diff --git a/mount/mountinfo.go b/pkg/mount/mountinfo.go similarity index 100% rename from mount/mountinfo.go rename to pkg/mount/mountinfo.go diff --git a/squashfs/mediatype.go b/pkg/squashfs/mediatype.go similarity index 71% rename from squashfs/mediatype.go rename to pkg/squashfs/mediatype.go index 051fe9b..5c33c95 100644 --- a/squashfs/mediatype.go +++ b/pkg/squashfs/mediatype.go @@ -3,21 +3,17 @@ package squashfs import ( "fmt" "strings" + + "machinerun.io/atomfs/verity" ) type SquashfsCompression string -type VerityMetadata bool const ( BaseMediaTypeLayerSquashfs = "application/vnd.stacker.image.layer.squashfs" GzipCompression SquashfsCompression = "gzip" ZstdCompression SquashfsCompression = "zstd" - - veritySuffix = "verity" - - VerityMetadataPresent VerityMetadata = true - VerityMetadataMissing VerityMetadata = false ) func IsSquashfsMediaType(mediaType string) bool { @@ -27,11 +23,11 @@ func IsSquashfsMediaType(mediaType string) bool { func GenerateSquashfsMediaType(comp SquashfsCompression, verity VerityMetadata) string { verityString := "" if verity { - verityString = fmt.Sprintf("+%s", veritySuffix) + verityString = fmt.Sprintf("+%s", verity.VeritySuffix) } return fmt.Sprintf("%s+%s%s", BaseMediaTypeLayerSquashfs, comp, verityString) } func HasVerityMetadata(mediaType string) VerityMetadata { - return VerityMetadata(strings.HasSuffix(mediaType, veritySuffix)) + return VerityMetadata(strings.HasSuffix(mediaType, verity.VeritySuffix)) } diff --git a/squashfs/squashfs.go b/pkg/squashfs/squashfs.go similarity index 97% rename from squashfs/squashfs.go rename to pkg/squashfs/squashfs.go index 328b061..f7cdebd 100644 --- a/squashfs/squashfs.go +++ b/pkg/squashfs/squashfs.go @@ -18,8 +18,10 @@ import ( "github.com/Masterminds/semver/v3" "github.com/pkg/errors" "golang.org/x/sys/unix" - "machinerun.io/atomfs/log" - "machinerun.io/atomfs/mount" + "machinerun.io/atomfs/pkg/common" + "machinerun.io/atomfs/pkg/log" + "machinerun.io/atomfs/pkg/mount" + _ "machinerun.io/atomfs/verity" ) var checkZstdSupported sync.Once @@ -168,7 +170,7 @@ func MakeSquashfs(tempdir string, rootfs string, eps *ExcludePaths, verity Verit } if verity { - rootHash, err = appendVerityData(tmpSquashfs.Name()) + rootHash, err = verity.AppendVerityData(tmpSquashfs.Name()) if err != nil { return nil, "", rootHash, err } @@ -366,7 +368,7 @@ func squashFuse(squashFile, extractDir string) (*exec.Cmd, error) { } } } - for count := 0; !fileChanged(fiPre, extractDir); count++ { + for count := 0; !common.FileChanged(fiPre, extractDir); count++ { if cmd.ProcessState != nil { // process exited, the Wait() call in the goroutine above // caused ProcessState to be populated. @@ -742,3 +744,14 @@ func whichSearch(name string, paths []string) string { return "" } + +func verityDataLocation(sblock *superblock) (uint64, error) { + squashLen := sblock.size + + // squashfs is padded out to the nearest 4k + if squashLen%4096 != 0 { + squashLen = squashLen + (4096 - squashLen%4096) + } + + return squashLen, nil +} diff --git a/squashfs/superblock.go b/pkg/squashfs/superblock.go similarity index 100% rename from squashfs/superblock.go rename to pkg/squashfs/superblock.go diff --git a/squashfs/verity_static.go b/pkg/squashfs/verity_static.go similarity index 100% rename from squashfs/verity_static.go rename to pkg/squashfs/verity_static.go diff --git a/squashfs/verity_test.go b/pkg/squashfs/verity_test.go similarity index 100% rename from squashfs/verity_test.go rename to pkg/squashfs/verity_test.go diff --git a/pkg/types/types.go b/pkg/types/types.go new file mode 100644 index 0000000..3892022 --- /dev/null +++ b/pkg/types/types.go @@ -0,0 +1,14 @@ +package types + +type FileSystem interface { + // Mount a filesystem as container root, without host root privileges. + GuestMount(squashFile string, mountpoint string) error + + Mount(squashfs, mountpoint, rootHash string) error + + HostMount(squashfs string, mountpoint string, rootHash string) error + + Umount(mountpoint string) error + + VerityDataLocation() uint64 +} diff --git a/verity/mediatype.go b/verity/mediatype.go new file mode 100644 index 0000000..6333e79 --- /dev/null +++ b/verity/mediatype.go @@ -0,0 +1,10 @@ +package verity + +type VerityMetadata bool + +const ( + VeritySuffix = "verity" + + VerityMetadataPresent VerityMetadata = true + VerityMetadataMissing VerityMetadata = false +) diff --git a/squashfs/verity.go b/verity/verity.go similarity index 95% rename from squashfs/verity.go rename to verity/verity.go index 6642f86..b81275b 100644 --- a/squashfs/verity.go +++ b/verity/verity.go @@ -1,4 +1,4 @@ -package squashfs +package verity // #cgo pkg-config: libcryptsetup devmapper --static // #include @@ -77,7 +77,7 @@ import ( "github.com/martinjungblut/go-cryptsetup" "github.com/pkg/errors" "golang.org/x/sys/unix" - "machinerun.io/atomfs/mount" + "machinerun.io/atomfs/pkg/mount" ) const VerityRootHashAnnotation = "io.stackeroci.stacker.squashfs_verity_root_hash" @@ -130,7 +130,7 @@ func isCryptsetupEINVAL(err error) bool { var cryptsetupTooOld = errors.Errorf("libcryptsetup not new enough, need >= 2.3.0") -func appendVerityData(file string) (string, error) { +func AppendVerityData(file string) (string, error) { fi, err := os.Lstat(file) if err != nil { return "", errors.WithStack(err) @@ -179,27 +179,8 @@ func appendVerityData(file string) (string, error) { return fmt.Sprintf("%x", rootHash), errors.WithStack(err) } -func verityDataLocation(sblock *superblock) (uint64, error) { - squashLen := sblock.size - - // squashfs is padded out to the nearest 4k - if squashLen%4096 != 0 { - squashLen = squashLen + (4096 - squashLen%4096) - } - - return squashLen, nil -} - func verityName(p string) string { - return fmt.Sprintf("%s-%s", p, veritySuffix) -} - -func fileChanged(a os.FileInfo, path string) bool { - b, err := os.Lstat(path) - if err != nil { - return true - } - return !os.SameFile(a, b) + return fmt.Sprintf("%s-%s", p, VeritySuffix) } // Mount a filesystem as container root, without host root @@ -454,7 +435,7 @@ func Umount(mountpoint string) error { // was this a verity mount or a regular loopback mount? (if it's a // regular loopback mount, we detached it above, so need to do anything // special here; verity doesn't play as nicely) - if strings.HasSuffix(theMount.Source, veritySuffix) { + if strings.HasSuffix(theMount.Source, VeritySuffix) { // find the loop device that backs the verity device deviceNo, err := findLoopBackingVerity(theMount.Source) if err != nil {