disk: add entity-based interfaces and types

Add a generic entity data model that can be used to navigate and operate
on any specific disk image layout. Since the latter allows for arbitrary
nesting of different container types, such as LUKS2, LVM2, and with file
systems that can have sub-volumes, the entity model is very generic.

Co-Authored-By: Achilleas Koutsou <achilleas@koutsou.net>
This commit is contained in:
Christian Kellner 2022-02-19 11:38:09 +01:00 committed by Tom Gundersen
parent 22b8b671a8
commit 37e6fa8b95

View file

@ -1,7 +1,19 @@
// Disk package contains abstract data-types to define disk-related entities.
//
// PartitionTable, Partition and Filesystem types are currently defined.
// All of them can be 1:1 converted to osbuild.QEMUAssemblerOptions.
// The disk package is a collection of interfaces and structs that can be used
// to represent an disk image with its layout. Various concrete types, such as
// PartitionTable, Partition and Filesystem types are defined to model a given
// disk layout. These implement a collection of interfaces that can be used to
// navigate and operate on the various possible combinations of entities in a
// generic way. The entity data model is very generic so that it can represent
// all possible layouts, which can be arbitrarily complex, since technologies
// like logical volume management, LUKS2 container and file systems, that can
// have sub-volumes, allow for complex layouts.
// Entity and Container are the two main interfaces that are used to model the
// tree structure of a disk image layout. The other entity interfaces, such as
// Sizeable and Mountable, then describe various properties and capabilities
// of a given entity.
package disk
import (
@ -18,6 +30,60 @@ const (
DefaultGrainBytes = uint64(1024 * 1024) // 1 MiB
)
// Entity is the base interface for all disk-related entities.
type Entity interface {
// IsContainer indicates if the implementing type can
// contain any other entities.
IsContainer() bool
}
// Container is the interface for entities that can contain other entities.
// Together with the base Entity interface this allows to model a generic
// entity tree of theoretically arbitrary depth and width.
type Container interface {
Entity
// GetItemCount returns the number of actual child entities.
GetItemCount() uint
// GetChild returns the child entity at the given index.
GetChild(n uint) Entity
}
// Sizeable is implemented by entities that carry size information.
type Sizeable interface {
// EnsureSize will resize the entity to the given size in case
// it is currently smaller. Returns if the size was changed.
EnsureSize(size uint64) bool
// GetSize returns the size of the entity in bytes.
GetSize() uint64
}
// A Mountable entity is an entity that can be mounted.
type Mountable interface {
// GetMountPoint returns the path of the mount point.
GetMountpoint() string
// GetFSType returns the file system type, e.g. 'xfs'.
GetFSType() string
// GetFSSpec returns the file system spec information.
GetFSSpec() FSSpec
// GetFSTabOptions returns options for mounting the entity.
GetFSTabOptions() FSTabOptions
}
// A VolumeContainer is a container that is able to create new volumes.
//
// CreateVolume creates a new volume with the given mount point and
// size and returns it.
type VolumeContainer interface {
CreateVolume(mountpoint string, size uint64) (Entity, error)
}
// FSSpec for a filesystem (UUID and Label); the first field of fstab(5)
type FSSpec struct {
UUID string