Commit graph

81 commits

Author SHA1 Message Date
Achilleas Koutsou
c347373c90 disk: basic partition table creation tests
Add a few test partition tables with well known configurations, like
LVM, LVM on top of LVM and Btrfs in addition to the plain layout that
is currently used in most partition tables. Add very basic checks,
such as that `NewPartitionTable` works and we have approximately the
correct size.

Co-Authored-By: Christian Kellner <christian@kellner.me>
2022-02-22 19:23:41 +00:00
Christian Kellner
d1b1e32b6e disk: Partition.Payload is now an Entity
Partition.Payload now supports every type of disk.Entity which enables
creating PartitionTables with LUKS, LVM, and Btrfs. \o/

Co-Authored-By: Achilleas Koutsou <achilleas@koutsou.net>
2022-02-22 19:23:41 +00:00
Christian Kellner
206e030f2c disk: guard against nil pointer dereferencing
Add guards protecting against dereferencing the pointer receiver of
method calls.

Co-Authored-By: Achilleas Koutsou <achilleas@koutsou.net>
2022-02-22 19:23:41 +00:00
Christian Kellner
beaf411628 disk: remove unused functions
Remove functions that got obsoleted by the more generic, entity based,
ones:
  - `FindPartitionForMountpoint`
  - `BootPartitionIndex`
  - `FindFilesystemForMountpoint`
  - `RootFilesystem`
  - `BootFilesystem`

Co-Authored-By: Achilleas Koutsou <achilleas@koutsou.net>
2022-02-22 19:23:41 +00:00
Christian Kellner
908b62ae08 disk: use entityPath in ContainsMountpoint
Implement `PartitionTable.ContainsMountpoint` via `entityPath` instead
of `FindFileSystemForMountpoint`; `entityPath` is the more generic
variant of `FindFileSystemForMountpoint` and will work with anything
that implements `Mountable`.

Co-Authored-By: Achilleas Koutsou <achilleas@koutsou.net>
2022-02-22 19:23:41 +00:00
Christian Kellner
b0899c5c59 disk: new interface UniqueEntity for Entities with UUID
This is for all entities that have a uniquely identifiable via a UUID.
Currently the interface only contains a single function, GenUUID(),
that should generate a new UUID via a random source (`rand.Rand`).
NB: Partitions are uniquely identifiable if and only if the layout is
GPT.

Co-Authored-By: Achilleas Koutsou <achilleas@koutsou.net>
2022-02-22 19:23:41 +00:00
Achilleas Koutsou
126c23cb13 disk: move constants to main disk.go file
Code cleanup and reorganisation:
Removed customizations.go file, moved all constants to disk.go, and
updated DefaultGrainBytes to it's actual value.
2022-02-22 19:23:41 +00:00
Achilleas Koutsou
d3b4349c63 disk: remove old unused CreatePartitionTable() function
The new `disk.NewPartitionTable` function is now used in all places
and thus `CreatePartitionTable` can be removed; do so.
2022-02-22 19:23:41 +00:00
Achilleas Koutsou
3312323db1 disk: implement VolumeContainer interface for PartitionTable
Co-Authored-By: Christian Kellner <christian@kellner.me>
2022-02-22 19:23:41 +00:00
Achilleas Koutsou
2b957a7de6 disk: new constructor for PartitionTable
Uses the new interfaces and supports all the different kinds of
filesystem configurations that we added.
Clones the base PartitionTable before modifying it.

Co-Authored-By: Christian Kellner <christian@kellner.me>
2022-02-22 19:23:41 +00:00
Achilleas Koutsou
890f380384 distro: replace BootPartition() with FindMountable("/boot")
RootParition() and BootPartition() methods have been removed.
2022-02-22 19:23:41 +00:00
Achilleas Koutsou
3f38602896 disk: new method for finding Mountable entities with a given mountpoint 2022-02-22 19:23:41 +00:00
Achilleas Koutsou
6fc993d03c disk: rename PartitionTable re-layouting method
Small localised change. Nice shorter name.
2022-02-22 19:23:41 +00:00
Achilleas Koutsou
adfed6e0d7 disk: change updatePartitionStartPointOffsets() to use entityPath()
Eventually partition.Payload will be an Entity, so we need to use
more generic functions that work on the interfaces.

Co-Authored-By: Christian Kellner <christian@kellner.me>
2022-02-22 19:23:41 +00:00
Achilleas Koutsou
491020f9b8 disk: add entityPath() function
Starts from an Entity (typically the PartitionTable) and searches for a
target (Mountpoint), returning a slice of all the entities that lead to
the Mountable with the given Mountpoint (in reverse order).

Co-Authored-By: Christian Kellner <christian@kellner.me>
2022-02-22 19:23:41 +00:00
Christian Kellner
26c7be5311 disk: add basic check for ForEachEntity
Assure that we visit all the entities.

Co-Authored-By: Achilleas Koutsou <achilleas@koutsou.net>
2022-02-22 19:23:41 +00:00
Christian Kellner
cea96c43ac disk: new method on partition table to iterate over all entities
Add a new enumerator method to `PartitioTable` that allows the
caller to visit all entities inside a partition table.

Co-Authored-By: Achilleas Koutsou <achilleas@koutsou.net>
2022-02-22 19:23:41 +00:00
Achilleas Koutsou
3110ae4629 disk: move stage option generation functions to osbuild1,2
Co-Authored-By: Christian Kellner <christian@kellner.me>
2022-02-22 19:23:41 +00:00
Achilleas Koutsou
05a2f97549 disk: new PartitionTable method ForEachMountable()
Calls a given function on each Mountable in a PartitionTable.

Co-Authored-By: Christian Kellner <christian@kellner.me>
2022-02-22 19:23:41 +00:00
Achilleas Koutsou
46a0ad77f9 osbuild2: add LUKS2 format stage and device
Co-Authored-By: Christian Kellner <christian@kellner.me>
2022-02-22 19:23:41 +00:00
Achilleas Koutsou
54fd090a60 disk: rename Partition.Filesystem to Payload
A Partition can contain any type of Entity now.  Before we change the
type, rename the field to a more generic term.
2022-02-22 19:23:41 +00:00
Achilleas Koutsou
221cdedebc disk: Entity types must implement Clone()
All disk.Entitity types now implement Clone() which should return a
deep copy of the same object. Add the Clone() method to the entity
interface. The return type is Entity, but callers can assume it's
safe to convert back to the original type.

Co-Authored-By: Christian Kellner <christian@kellner.me>
2022-02-22 19:23:41 +00:00
Achilleas Koutsou
01d922a4d5 disk: make disk_test package internal to disk package
So that we can test internal functions of the disk package.
2022-02-22 19:23:41 +00:00
Achilleas Koutsou
ba9a849b19 disk: new types Btrfs and BtrfsSubvolume
Structs to represent a Btrfs file system with subvolumes.

Btrfs implements the following interfaces:
- Entity
- Container
- VolumeContainer

BtrfsSubvolume implements the following interfaces:
- Entity
- Sizeable
- Mountable

Co-Authored-By: Christian Kellner <christian@kellner.me>
2022-02-22 19:23:41 +00:00
Achilleas Koutsou
f6f54b14ad disk: new types LVMVolumeGroup and LVMLogicalVolume
Types to represent LVM2 setups with logical volumes being contained
in volume groups.

LVMVolumeGroup implements the following disk interfaces:
- Entity
- Container
- VolumeContainer

LVMLogicalVolume implements the following disk interfaces:
- Entity
- Container
- Sizeable

Co-Authored-By: Christian Kellner <christian@kellner.me>
2022-02-22 19:23:41 +00:00
Achilleas Koutsou
ef2fdf16a7 disk: new type LUKSContainer
Representation for the encrypted storage container of the same name.

Implements the following disk interfaces:
- Entity
- Container

Co-Authored-By: Christian Kellner <christian@kellner.me>
2022-02-22 19:23:41 +00:00
Achilleas Koutsou
250116638c disk: implement Mountable interface for Filesystem
A filesystem obviously can be mounted, thus it implements the Mountable
interface.

Co-Authored-By: Christian Kellner <christian@kellner.me>
2022-02-22 19:23:41 +00:00
Christian Kellner
4c34b5e2a8 disk: implement Sizeable interface for PartitionTable and Partition
In our model a partition table has a size to represent the disk size.
Also each individual partition has a size, so they both implement the
Sizeable interface.

Co-Authored-By: Achilleas Koutsou <achilleas@koutsou.net>
2022-02-22 19:23:41 +00:00
Achilleas Koutsou
0e1c769598 disk: implement Container interface for PartitionTable and Partition
A `PartitionTable` is a container for one or more instances of
`Partition`, which itself might contain a `Filesystem`.

Co-Authored-By: Christian Kellner <christian@kellner.me>
2022-02-22 19:23:41 +00:00
Christian Kellner
51a396e3f1 disk: implement Entity interface
Implement the base type of the new entity system, i.e. `Entity`,
for all relevant components:
 - PartitionTable
 - Partition
 - Filesystem

Co-Authored-By: Achilleas Koutsou <achilleas@koutsou.net>
2022-02-22 19:23:41 +00:00
Christian Kellner
37e6fa8b95 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>
2022-02-22 19:23:41 +00:00
Achilleas Koutsou
22b8b671a8 disk: move Partition and methods to separate file
Split up disk.go into smaller more manageable pieces: finish
by moving `Partition` to its own file.

Co-Authored-By: Christian Kellner <christian@kellner.me>
2022-02-22 19:23:41 +00:00
Achilleas Koutsou
53795c3dad disk: move Filesystem and methods to separate file
Split up disk.go into smaller more managable pieces: continue
with moving `Filesystem` to its own file.

Co-Authored-By: Christian Kellner <christian@kellner.me>
2022-02-22 19:23:41 +00:00
Achilleas Koutsou
e7827b4b97 disk: move PartitionTable and methods to separate file
Split up disk.go into smaller more managable pieces: start with
extracting `PartitionTable` and all its methods to a new file.

Co-Authored-By: Christian Kellner <christian@kellner.me>
2022-02-22 19:23:41 +00:00
Christian Kellner
dec5a3850c disk: use bytes instead of sectors in all code
Use bytes internally everywhere and convert to sectors only when writing
the options for the stages.

Changed the AlignUp() method to not do the alignment if the input is
already aligned.  This changes the behaviour when the size is 0, but
that's not a realistic use case.  Updated unit tests to match.

Manifests are unaffected.

Co-Authored-By: Christian Kellner <christian@kellner.me>
2022-02-22 19:23:41 +00:00
Christian Kellner
abaadf95ed disk: dynamically calculate header & footer
Instead of just reserving a fixed amount of sectors for the
partition header and footer, calculate the size of the
header and footer dynamically when the layout is GPT.
2022-02-22 19:23:41 +00:00
Christian Kellner
b65ef74cb2 disk: honour maximum number of partitions
Return an error if the maximum numbers of partitions has been
reached and thus creating further partitions would result in
errors.
Currently we limit MBR partition types to 4 as we dont support
logical partitions and GPT layouts to 128. According to the
UEFI specificatio (2.8) a minimum of 16384 bytes are reserved
for the partition entries array. Each entry is 128 bytes wide
thus resulting in at least 128 entries; we choose this to be
the maximum as well for now.
2022-02-22 19:23:41 +00:00
Christian Kellner
1dbd2bc364 disk: use new alignment helper to align partitions
Align partitions during their re-layout. Specifically, we align the
first partition which removes the need for the hard coded magic
number of 2048, which represents the proper alignment for a grain
size of 1MB given a sector size of 512 (our setup).

NB: Since all our partitions should sizes that are themselves
aligned, i.e. evenly dividable by the default grain (1MB) this
will not actually change any manifest.
2022-02-22 19:23:41 +00:00
Christian Kellner
930633c249 disk: add alignment helper
Add a utility method that can be used to align data to the next "grain"
which is currently defined as 1 MiB -- the default used by sfdisk.

Add corresponding tests.
2022-02-22 19:23:41 +00:00
Christian Kellner
b7abef54e8 disk: calculate padding for secondary GPT header
Instead of hard coding a padding of 100 sectors for all layouts, i.e.
MBR and GTP, adjust the needed space depending on the layout: for MBR 
we don't need to reserve any space at all since it does not have a 
secondary header. For GTP we reserve 33 sectors, as indicated in the
UEFI specific, which allows for the header itself and up to 128 entries.
To not modify the layout of already released distributions, like RHEL
8.4 and 8.5, a new member called `ExtraPadding` is added to `Partition
Table` and then used in the corresponding layouts to preserve the
existing padding of 100.
2022-02-22 19:23:41 +00:00
Christian Kellner
b3c769ae02 disk: grow root partition while re-layouting
Instead of growing the root partition in `CreatePartitionTable` do it
as part of `updatePartitionStartPointOffsets`.
2022-02-22 19:23:41 +00:00
Christian Kellner
16ad1211c3 disk: ensure there is enough space for all parts
The old calculation was wrong since it compared sectors and bytes.
2022-02-22 19:23:41 +00:00
Christian Kellner
6db5a7d6a8 disk: fix order of expected size in test
The method assert.GreaterOrEqual(t, a, b) asserts that a >= b,
but the arguments were (expected, actual), which is the wrong
way around since we want to assure that the actual size is at
least the expected size, i.e. actual >= expected and thus the
argument should be (actual, expected).

The partition table size (pt.Size) is in sectors while our checks and
customizations are in bytes, so we need to convert when comparing.

Co-Authored-By: Achilleas Koutsou <achilleas@koutsou.net>
2022-02-22 19:23:41 +00:00
Christian Kellner
b6cece8b28 disk: ability to grow existing partitions
Apply the minimum size specified in the file system customizations 
also to existing partitions. Specifically, this now allows to set
a minimum size also for the root partition.
2022-02-22 19:23:41 +00:00
Christian Kellner
97754a2c99 disk: add EnsureSize helper
Ensure the partition has at least the given size. Will do nothing
if the partition is already larger. Returns if the size changed.
2022-02-22 19:23:41 +00:00
Christian Kellner
e7dbe60622 disk: add find partition for mountpoint helper 2022-02-22 19:23:41 +00:00
Christian Kellner
9746a87609 disk: move createFilesystem to disk.go
Move the `createFilesystem` method over the `disk.go` and make it
a public method of `PartitionTable`.
2022-02-22 19:23:41 +00:00
Christian Kellner
7e4097fb6f disk: sector size can now be per partition table
Allow the sector size to be specified on the partition table level by
introducing a new `SectorSize` field. Modify the conversion helpers
to use that new field with a fallback to default sector size in case
the field is `0`.
2022-02-22 19:23:41 +00:00
Christian Kellner
aa2825d296 disk: use BytesToSectors in customization.go
Use the newly introduced conversion helper to convert between bytes
and sectors.
2022-02-22 19:23:41 +00:00
Christian Kellner
f5592bd14a disk: add bytes ↔ sectors conversion helper
Add simple helper methods that convert between bytes and sectors. This
is a method of `PartitionTable`, since the sector size can in theory
be per partition table and this prepares for that case.
2022-02-22 19:23:41 +00:00