mkcomposefs(1)

NAME
mkcomposefs - create a composefs filesystem image

SYNOPSIS
mkcomposefs SOURCE IMAGE

DESCRIPTION
The composefs project uses EROFS image file to store metadata, and one or more separate directories containing content-addressed backing data for regular files.

mkcomposefs constructs the mountable "composefs image" using the source as input. It can also create the backing store directory. Typically the source is a directory, but with --from-file it can also be a file.

OPTIONS
The provided SOURCEDIR argument must be a directory and its entire contents will be read recursively. The provided IMAGE argument will be a mountable composefs image.

mkcomposefs accepts the following options:

--digest-store=PATH
    This path will become a composefs "object store". Regular files larger than 64 bytes in the SOURCEDIR will be copied (reflinked if possible) into this target directory, named after their fsverity digest. Small files will be inlined into the image metadata. If possible, the added files will have fs-verity enabled.

    This directory should be passed to the basedir option when you mount the image.

--print-digest
    Print the fsverity digest of the composefs metadata file.

--print-digest-only
    Print the fsverity digest of the composefs metadata file, but don't write the image. If this is passed, the IMAGE argument should be left out.

--use-epoch
    Use a zero time (unix epoch) as the modification time for all files.

--skip-devices
    Don't add device nodes to the image.

--skip-xattrs
    Don't add xattrs to files in the image.

--user-xattrs
    Only add xattrs with the "user." prefix to files in the image.

--from-file
    The source is a file in the composefs-dump(5) format. If the specified file is "-", the data is read from stdin.

--version
    The base version to use for the image format.

--max-version
    If this specifies a version higher than --version, then the actual image format version used will be adjusted upwards if that is beneficial for the image, up to the max version.

--threads=count
    Number of threads to be used to calculate the file digests and copy. Default thread count is the number of processors when --threads is not specified.

FORMAT VERSIONING
Composefs images are binary reproduceable, meaning that for a given input the result is always the same, giving the same digest of the image. This is important as the digest is used to validate the image, even if the image was re-created rather than transferred as is. However, sometimes the format needs to be changed, such as for example when a new type of file is introduced or a bug is fixed. This is handled by introducing a format version.

Specifying the version is done with two options, the base version (--version) and the max version (--max-version). When building an image, mkcomposefs tries to keep the image format as low as possible, but if some particular requested feature is not available with the base feature, but is accessible in the max version then the version used will be increased. This allows us to introduce new features and fix bugs in a later version and migrate to that using max versions, but still keeping the digests identical for unaffected images.

If you need 100% binary reproducibility over time, specify the same version and a max version each time.

Format version history:

•   0 - Initial version

•   1 - Supports overlay whiteout files in the image (added in 1.0.3)

The default if no version arguments are specified is version 0 and max version 1.

SANDBOXING RECOMMENDATIONS
This tool essentially just processes an input directory or text file and writes a file. It does not require any privileges at all. If you are invoking this as part of an otherwise privileged process (such as a container runtime) we recommend dropping privileges before invoking mkcomposefs.

Especially if you are using --from-file, you can run this as an unprivileged uid that has no writable filesystem access at all except to a passed file descriptor. For example, you can pass a writable file descriptor for the desired target file as fd 3, and run mkcomposefs --from-file - /proc/self/fd/3 to effectively use mkcomposefs as part of a pipeline.

An example simple sandboxing starting from root is setpriv --nnp --reuid nobody -- mkcomposefs .... Another is to use systemd-run -P DynamicUser=yes -P ProtectSystem=strict. Yet another (especially if your code is already part of a container runtime) is to use that runtime's existing functionality (seccomp, unsharing user namespace, mounting a restricted subset of the rootfs, etc.

SEE ALSO
composefs-info(1), mount.composefs(1), composefs-dump(5)

composefs upstream ⟨https://github.com/containers/composefs⟩