Repository

Struct Repository 

Source
pub struct Repository<ObjectID: FsVerityHashValue> {
    repository: OwnedFd,
    objects: OnceCell<OwnedFd>,
    insecure: bool,
    _data: PhantomData<ObjectID>,
}
Expand description

A content-addressable repository for composefs objects.

Stores content-addressed objects, splitstreams, and images with fsverity verification. Objects are stored by their fsverity digest, streams by SHA256 content hash, and both support named references for persistence across garbage collection.

Fields§

§repository: OwnedFd§objects: OnceCell<OwnedFd>§insecure: bool§_data: PhantomData<ObjectID>

Implementations§

Source§

impl<ObjectID: FsVerityHashValue> Repository<ObjectID>

Source

pub fn objects_dir(&self) -> ErrnoResult<&OwnedFd>

Return the objects directory.

Source

pub fn open_path(dirfd: impl AsFd, path: impl AsRef<Path>) -> Result<Self>

Open a repository at the target directory and path.

Source

pub fn open_user() -> Result<Self>

Open the default user-owned composefs repository.

Source

pub fn open_system() -> Result<Self>

Open the default system-global composefs repository.

Source

fn ensure_dir(&self, dir: impl AsRef<Path>) -> ErrnoResult<()>

Source

pub async fn ensure_object_async( self: &Arc<Self>, data: Vec<u8>, ) -> Result<ObjectID>

Asynchronously ensures an object exists in the repository.

Same as ensure_object but runs the operation on a blocking thread pool to avoid blocking async tasks. Returns the fsverity digest of the object.

Source

pub fn ensure_object(&self, data: &[u8]) -> Result<ObjectID>

Given a blob of data, store it in the repository.

Source

fn open_with_verity( &self, filename: &str, expected_verity: &ObjectID, ) -> Result<OwnedFd>

Source

pub fn set_insecure(&mut self, insecure: bool) -> &mut Self

By default fsverity is required to be enabled on the target filesystem. Setting this disables verification of digests and an instance of Self can be used on a filesystem without fsverity support.

Source

pub fn create_stream( self: &Arc<Self>, sha256: Option<Sha256Digest>, maps: Option<DigestMap<ObjectID>>, ) -> SplitStreamWriter<ObjectID>

Creates a SplitStreamWriter for writing a split stream. You should write the data to the returned object and then pass it to .store_stream() to store the result.

Source

fn format_object_path(id: &ObjectID) -> String

Source

pub fn has_stream(&self, sha256: &Sha256Digest) -> Result<Option<ObjectID>>

Check if the provided splitstream is present in the repository; if so, return its fsverity digest.

Source

pub fn check_stream(&self, sha256: &Sha256Digest) -> Result<Option<ObjectID>>

Similar to Self::has_stream but performs more expensive verification.

Source

pub fn write_stream( &self, writer: SplitStreamWriter<ObjectID>, reference: Option<&str>, ) -> Result<ObjectID>

Write the given splitstream to the repository with the provided name.

Source

pub fn name_stream(&self, sha256: Sha256Digest, name: &str) -> Result<()>

Assign the given name to a stream. The stream must already exist. After this operation it will be possible to refer to the stream by its new name ‘refs/{name}’.

Source

pub fn ensure_stream( self: &Arc<Self>, sha256: &Sha256Digest, callback: impl FnOnce(&mut SplitStreamWriter<ObjectID>) -> Result<()>, reference: Option<&str>, ) -> Result<ObjectID>

Ensures that the stream with a given SHA256 digest exists in the repository.

This tries to find the stream by the sha256 digest of its contents. If the stream is already in the repository, the object ID (fs-verity digest) is read from the symlink. If the stream is not already in the repository, a SplitStreamWriter is created and passed to callback. On return, the object ID of the stream will be calculated and it will be written to disk (if it wasn’t already created by someone else in the meantime).

In both cases, if reference is provided, it is used to provide a fixed name for the object. Any object that doesn’t have a fixed reference to it is subject to garbage collection. It is an error if this reference already exists.

On success, the object ID of the new object is returned. It is expected that this object ID will be used when referring to the stream from other linked streams.

Source

pub fn open_stream( &self, name: &str, verity: Option<&ObjectID>, ) -> Result<SplitStreamReader<File, ObjectID>>

Open a splitstream with the given name.

Source

pub fn open_object(&self, id: &ObjectID) -> Result<OwnedFd>

Given an object identifier (a digest), return a read-only file descriptor for its contents. The fsverity digest is verified (if the repository is not in insecure mode).

Source

pub fn merge_splitstream( &self, name: &str, verity: Option<&ObjectID>, stream: &mut impl Write, ) -> Result<()>

Merges a splitstream into a single continuous stream.

Opens the named splitstream, resolves all object references, and writes the complete merged content to the provided writer. Optionally verifies the splitstream’s fsverity digest matches the expected value.

Source

pub fn write_image(&self, name: Option<&str>, data: &[u8]) -> Result<ObjectID>

Write data into the repository as an image with the given name`.

The fsverity digest is returned.

§Integrity

This function is not safe for untrusted users.

Source

pub fn import_image<R: Read>( &self, name: &str, image: &mut R, ) -> Result<ObjectID>

Import the data from the provided read into the repository as an image.

The fsverity digest is returned.

§Integrity

This function is not safe for untrusted users.

Source

fn open_image(&self, name: &str) -> Result<(OwnedFd, bool)>

Returns the fd of the image and whether or not verity should be enabled when mounting it.

Source

pub fn mount(&self, name: &str) -> Result<OwnedFd>

Create a detached mount of an image. This file descriptor can then be attached via e.g. move_mount.

Source

pub fn mount_at(&self, name: &str, mountpoint: impl AsRef<Path>) -> Result<()>

Mount the image with the provided digest at the target path.

Creates a relative symlink within the repository.

Computes the correct relative path from the symlink location to the target, creating any necessary intermediate directories. Atomically replaces any existing symlink at the specified name.

Source

fn walk_symlinkdir(fd: OwnedFd, objects: &mut HashSet<ObjectID>) -> Result<()>

Source

fn openat(&self, name: &str, flags: OFlags) -> ErrnoResult<OwnedFd>

Open the provided path in the repository.

Source

fn gc_category(&self, category: &str) -> Result<HashSet<ObjectID>>

Source

pub fn objects_for_image(&self, name: &str) -> Result<HashSet<ObjectID>>

Given an image, return the set of all objects referenced by it.

Source

pub fn gc(&self) -> Result<()>

Perform a garbage collection operation.

§Locking

An exclusive lock is held for the duration of this operation.

Trait Implementations§

Source§

impl<ObjectID: Debug + FsVerityHashValue> Debug for Repository<ObjectID>

Source§

fn fmt(&self, f: &mut Formatter<'_>) -> Result

Formats the value using the given formatter. Read more
Source§

impl<ObjectID: FsVerityHashValue> Drop for Repository<ObjectID>

Source§

fn drop(&mut self)

Executes the destructor for this type. Read more

Auto Trait Implementations§

§

impl<ObjectID> !Freeze for Repository<ObjectID>

§

impl<ObjectID> RefUnwindSafe for Repository<ObjectID>
where ObjectID: RefUnwindSafe,

§

impl<ObjectID> Send for Repository<ObjectID>

§

impl<ObjectID> Sync for Repository<ObjectID>

§

impl<ObjectID> Unpin for Repository<ObjectID>

§

impl<ObjectID> UnwindSafe for Repository<ObjectID>
where ObjectID: UnwindSafe,

Blanket Implementations§

Source§

impl<T> Any for T
where T: 'static + ?Sized,

Source§

fn type_id(&self) -> TypeId

Gets the TypeId of self. Read more
Source§

impl<T> Borrow<T> for T
where T: ?Sized,

Source§

fn borrow(&self) -> &T

Immutably borrows from an owned value. Read more
Source§

impl<T> BorrowMut<T> for T
where T: ?Sized,

Source§

fn borrow_mut(&mut self) -> &mut T

Mutably borrows from an owned value. Read more
Source§

impl<T> From<T> for T

Source§

fn from(t: T) -> T

Returns the argument unchanged.

Source§

impl<T, U> Into<U> for T
where U: From<T>,

Source§

fn into(self) -> U

Calls U::from(self).

That is, this conversion is whatever the implementation of From<T> for U chooses to do.

Source§

impl<T> Same for T

Source§

type Output = T

Should always be Self
Source§

impl<T, U> TryFrom<U> for T
where U: Into<T>,

Source§

type Error = Infallible

The type returned in the event of a conversion error.
Source§

fn try_from(value: U) -> Result<T, <T as TryFrom<U>>::Error>

Performs the conversion.
Source§

impl<T, U> TryInto<U> for T
where U: TryFrom<T>,

Source§

type Error = <U as TryFrom<T>>::Error

The type returned in the event of a conversion error.
Source§

fn try_into(self) -> Result<U, <U as TryFrom<T>>::Error>

Performs the conversion.
§

impl<V, T> VZip<V> for T
where V: MultiLane<T>,

§

fn vzip(self) -> V