File systems verification utility and library, in likeness of mtree(8) https://github.com/vbatts/go-mtree
Go to file
Vincent Batts 1adae81a54
Merge pull request #165 from vbatts/change-ci
Change ci
2021-09-14 10:06:35 -04:00
.github/workflows github: add action for build and validation 2021-06-25 22:17:01 -04:00
.vscode vscode: adding IDE tasks 2017-09-29 11:38:12 -04:00
cmd/gomtree vendor: Replace Sirupsen/logrus with sirupsen/logrus 2017-11-03 12:19:19 -07:00
pkg/govis govis: comment for lint 2017-06-30 15:06:50 -04:00
test cli.test: colorize the success/failure 2018-08-20 07:57:14 -04:00
testdata casync: adding a casync style mtree 2017-12-13 14:20:29 -05:00
vendor vendor: update the vendored sources 2021-06-25 22:19:26 -04:00
xattr test: Allow using an environment variable to override the test dir 2017-04-13 11:35:01 -07:00
.drone.yml trying out drone 2021-09-14 09:56:11 -04:00
.gitignore git: add an ignores 2017-02-16 10:45:15 -05:00
LICENSE LICENSE: adding a license 2016-03-24 16:34:58 -04:00
Makefile Makefile: '[[' misinterpreted as a command 2021-01-25 13:46:31 -05:00
README.md README: change out badge of CI 2021-09-14 10:00:24 -04:00
check.go check: remove unused TarCheck(), for Compare() 2018-12-10 11:26:12 -05:00
check_test.go *: xattr can Update() 2017-06-24 15:05:24 -04:00
cksum.go cksum: comment 2016-03-24 16:35:09 -04:00
cksum_test.go cksum: test is fine. commenting. 2016-04-05 16:47:36 -04:00
compare.go compare: return the right delta 2020-04-02 12:03:07 -06:00
compare_test.go walk: implement FsEval hooks 2016-12-14 16:26:31 +11:00
creator.go walk: implement FsEval hooks 2016-12-14 16:26:31 +11:00
entry.go entry: rework e.Path() handling for casync-mtree 2018-09-15 00:18:31 +10:00
fseval.go walk: implement FsEval hooks 2016-12-14 16:26:31 +11:00
fseval_test.go fseval: not nanosecond for mock test 2017-06-15 22:54:59 -05:00
go.mod go.mod: tidy up 2021-06-25 22:19:25 -04:00
go.sum go.mod: tidy up 2021-06-25 22:19:25 -04:00
hierarchy.go compare: correctly use .Prefix() during comparisons 2017-09-29 21:05:45 +10:00
hierarchy_test.go compare: correctly use .Prefix() during comparisons 2017-09-29 21:05:45 +10:00
keywordfunc.go keyword: include sha-2 512/256 2017-10-28 22:16:03 -04:00
keywordfuncs_bsd.go *: xattr can Update() 2017-06-24 15:05:24 -04:00
keywordfuncs_linux.go *: xattr can Update() 2017-06-24 15:05:24 -04:00
keywordfuncs_unsupported.go *: xattr can Update() 2017-06-24 15:05:24 -04:00
keywords.go keyword: include sha-2 512/256 2017-10-28 22:16:03 -04:00
keywords_linux_test.go *: xattr can Update() 2017-06-24 15:05:24 -04:00
keywords_test.go *: xattr can Update() 2017-06-24 15:05:24 -04:00
lchtimes_unix.go *: use UtimesNanoAt from x/sys/unix 2017-10-20 12:31:55 +02:00
lchtimes_unsupported.go *: use UtimesNanoAt from x/sys/unix 2017-10-20 12:31:55 +02:00
lookup_new.go lookupGroupId: add implementation for go1.6 2017-06-15 12:36:11 -05:00
lookup_old.go lookupGroupId: add implementation for go1.6 2017-06-15 12:36:11 -05:00
mtree_test.go *.go: clean up variable names 2018-08-19 18:25:48 -04:00
parse.go *: make Keyword and KeyVal pervasive 2016-11-17 21:38:01 -05:00
releases.md release: add some steps to remember 2017-01-23 14:40:40 -05:00
stat_unix.go *: update `-u` behavior 2017-06-30 15:34:44 -04:00
stat_windows.go *: update `-u` behavior 2017-06-30 15:34:44 -04:00
tar.go vendor: Replace Sirupsen/logrus with sirupsen/logrus 2017-11-03 12:19:19 -07:00
tar_test.go check: remove unused TarCheck(), for Compare() 2018-12-10 11:26:12 -05:00
update.go vendor: Replace Sirupsen/logrus with sirupsen/logrus 2017-11-03 12:19:19 -07:00
update_linux_test.go *: xattr can Update() 2017-06-24 15:05:24 -04:00
update_test.go vendor: Replace Sirupsen/logrus with sirupsen/logrus 2017-11-03 12:19:19 -07:00
updatefuncs.go vendor: Replace Sirupsen/logrus with sirupsen/logrus 2017-11-03 12:19:19 -07:00
updatefuncs_linux.go *: use UtimesNanoAt from x/sys/unix 2017-10-20 12:31:55 +02:00
updatefuncs_unsupported.go *: use UtimesNanoAt from x/sys/unix 2017-10-20 12:31:55 +02:00
version.go version: bump master back to -dev 2020-04-30 18:38:31 -04:00
walk.go *: xattr can Update() 2017-06-24 15:05:24 -04:00
walk_test.go casync: adding a casync style mtree 2017-12-13 14:20:29 -05:00

README.md

go-mtree

Go Report Card

mtree is a filesystem hierarchy validation tooling and format. This is a library and simple cli tool for mtree(8) support.

While the traditional mtree cli utility is primarily on BSDs (FreeBSD, openBSD, etc), even broader support for the mtree specification format is provided with libarchive (libarchive-formats(5)).

There is also an mtree port for Linux though it is not widely packaged for Linux distributions.

Format

The format of hierarchy specification is consistent with the # mtree v2.0 format. Both the BSD mtree and libarchive ought to be interoperable with it with only one definite caveat. On Linux, extended attributes (xattr) on files are often a critical aspect of the file, holding ACLs, capabilities, etc. While FreeBSD filesystem do support extattr, this feature has not made its way into their mtree.

This implementation of mtree supports a few non-upstream "keyword"s, such as: xattr and tar_time. If you include these keywords, the FreeBSD mtree will fail, as they are unknown keywords to that implementation.

To have go-mtree produce specifications that will be strictly compatible with the BSD mtree, use the -bsd-keywords flag when creating a manifest. This will make sure that only the keywords supported by BSD mtree are used in the program.

Typical form

With the standard keywords, plus say sha256digest, the hierarchy specification looks like:

# .
/set type=file nlink=1 mode=0664 uid=1000 gid=100
. size=4096 type=dir mode=0755 nlink=6 time=1459370393.273231538
    LICENSE size=1502 mode=0644 time=1458851690.0 sha256digest=ef4e53d83096be56dc38dbf9bc8ba9e3068bec1ec37c179033d1e8f99a1c2a95
    README.md size=2820 mode=0644 time=1459370256.316148361 sha256digest=d9b955134d99f84b17c0a711ce507515cc93cd7080a9dcd50400e3d993d876ac

[...]

See the directory presently in, and the files present. Along with each path, is provided the keywords and the unique values for each path. Any common keyword and values are established in the /set command.

Extended attributes form

# .
/set type=file nlink=1 mode=0664 uid=1000 gid=1000
. size=4096 type=dir mode=0775 nlink=6 time=1459370191.11179595 xattr.security.selinux=dW5jb25maW5lZF91Om9iamVjdF9yOnVzZXJfaG9tZV90OnMwAA==
    LICENSE size=1502 time=1458851690.583562292 xattr.security.selinux=dW5jb25maW5lZF91Om9iamVjdF9yOnVzZXJfaG9tZV90OnMwAA==
    README.md size=2366 mode=0644 time=1459369604.0 xattr.security.selinux=dW5jb25maW5lZF91Om9iamVjdF9yOnVzZXJfaG9tZV90OnMwAA==

[...]

See the keyword prefixed with xattr. followed by the extended attribute's namespace and keyword. This setup is consistent for use with Linux extended attributes as well as FreeBSD extended attributes.

Since extended attributes are an unordered hashmap, this approach allows for checking each <namespace>.<key> individually.

The value is the base64 encoded of the value of the particular extended attribute. Since the values themselves could be raw bytes, this approach avoids issues with encoding.

Tar form

# .
/set type=file mode=0664 uid=1000 gid=1000
. type=dir mode=0775 tar_time=1468430408.000000000

# samedir
samedir type=dir mode=0775 tar_time=1468000972.000000000
    file2 size=0 tar_time=1467999782.000000000
    file1 size=0 tar_time=1467999781.000000000
    
[...]

While go-mtree serves mainly as a library for upstream mtree support, go-mtree is also compatible with tar archives (which is not an upstream feature). This means that we can now create and validate a manifest by specifying a tar file. More interestingly, this also means that we can create a manifest from an archive, and then validate this manifest against a filesystem hierarchy that's on disk, and vice versa.

Notice that for the output of creating a validation manifest from a tar file, the default behavior for evaluating a notion of time is to use the tar_time keyword. In the "filesystem hierarchy" format of mtree, time is being evaluated with nanosecond precision. However, GNU tar truncates a file's modification time to 1-second precision. That is, if a file's full modification time is 123456789.123456789, the "tar time" equivalent would be 123456789.000000000. This way, if you validate a manifest created using a tar file against an actual root directory, there will be no complaints from go-mtree so long as the 1-second precision time of a file in the root directory is the same.

Usage

To use the Go programming language library, see the docs.

To use the command line tool, first build it, then the following.

Create a manifest

This will also include the sha512 digest of the files.

gomtree -c -K sha512digest -p . > /tmp/root.mtree

With a tar file:

gomtree -c -K sha512digest -T sometarfile.tar > /tmp/tar.mtree

Validate a manifest

gomtree -p . -f /tmp/root.mtree

With a tar file:

gomtree -T sometarfile.tar -f /tmp/root.mtree

See the supported keywords

gomtree -list-keywords
Available keywords:
 uname
 sha1
 sha1digest
 sha256digest
 xattrs (not upstream)
 link (default)
 nlink (default)
 md5digest
 rmd160digest
 mode (default)
 cksum
 md5
 rmd160
 type (default)
 time (default)
 uid (default)
 gid (default)
 sha256
 sha384
 sha512
 xattr (not upstream)
 tar_time (not upstream)
 size (default)
 ripemd160digest
 sha384digest
 sha512digest

Building

Either:

go get github.com/vbatts/go-mtree/cmd/gomtree

or

git clone git://github.com/vbatts/go-mtree.git $GOPATH/src/github.com/vbatts/go-mtree
cd $GOPATH/src/github.com/vbatts/go-mtree
go build ./cmd/gomtree

Testing

On Linux:

cd $GOPATH/src/github.com/vbatts/go-mtree
make

On FreeBSD:

cd $GOPATH/src/github.com/vbatts/go-mtree
gmake