Skip to content

Commit

Permalink
Image Customizer: Make verity API a list. (microsoft#10789)
Browse files Browse the repository at this point in the history
Change the verity config from a single item to a list of items. This is being done so that it is easier to add support for other verity partitions (e.g. /usr) in the future. However, this change restricts the verity API to only the root partition (`/`).

In addition, move the verity config from `.os` to `.storage`. This is being done for alignment with the Trident API. But is also probably a more morally correct place for verity to be placed.

As a side effect, this change removes support for enabling verity on a base image that somehow had all the correct partitions to support verity but didn't actually have verity enabled. None of our base images are like this. So, it is expected that no user ever made use of this functionality. This functionality could be re-added in the future. It was omitted from this change to avoid adding additional complexity.
  • Loading branch information
cwize1 authored and durgajagadeesh committed Dec 31, 2024
1 parent 6f5994c commit 294f2ab
Show file tree
Hide file tree
Showing 21 changed files with 1,184 additions and 470 deletions.
37 changes: 0 additions & 37 deletions toolkit/tools/imagecustomizerapi/config.go
Original file line number Diff line number Diff line change
Expand Up @@ -49,43 +49,6 @@ func (c *Config) IsValid() (err error) {
return fmt.Errorf("'os.resetBootLoaderType' must be specified if 'storage.resetPartitionsUuidsType' is specified")
}

if c.OS != nil && c.OS.Verity != nil {
err := ensureVerityPartitionIdExists(c.OS.Verity.DataPartition, &c.Storage)
if err != nil {
return fmt.Errorf("invalid verity 'dataPartition':\n%w", err)
}

err = ensureVerityPartitionIdExists(c.OS.Verity.HashPartition, &c.Storage)
if err != nil {
return fmt.Errorf("invalid verity 'hashPartition':\n%w", err)
}
}

return nil
}

func ensureVerityPartitionIdExists(verityPartition IdentifiedPartition, storage *Storage) error {
switch verityPartition.IdType {
case IdTypeId:
if !storage.CustomizePartitions() {
return fmt.Errorf("'idType' cannot be 'id' if 'storage.disks' is not specified")
}

foundPartition := false
for _, disk := range storage.Disks {
for _, partition := range disk.Partitions {
if partition.Id == verityPartition.Id {
foundPartition = true
break
}
}
}

if !foundPartition {
return fmt.Errorf("partition with 'id' (%s) not found", verityPartition.Id)
}
}

return nil
}

Expand Down
62 changes: 28 additions & 34 deletions toolkit/tools/imagecustomizerapi/config_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -413,26 +413,24 @@ func TestConfigIsValidVerityValid(t *testing.T) {
},
},
{
DeviceId: "root",
DeviceId: "rootverity",
Type: "ext4",
MountPoint: &MountPoint{
Path: "/",
},
},
},
Verity: []Verity{
{
Id: "rootverity",
Name: "root",
DataDeviceId: "root",
HashDeviceId: "verityhash",
},
},
},
OS: &OS{
ResetBootLoaderType: "hard-reset",
Verity: &Verity{
DataPartition: IdentifiedPartition{
IdType: IdTypeId,
Id: "root",
},
HashPartition: IdentifiedPartition{
IdType: IdTypeId,
Id: "verityhash",
},
},
},
}
err := config.IsValid()
Expand Down Expand Up @@ -486,42 +484,38 @@ func TestConfigIsValidVerityPartitionNotFound(t *testing.T) {
},
},
},
Verity: []Verity{
{
Id: "rootverity",
Name: "root",
DataDeviceId: "wrongname",
HashDeviceId: "verityhash",
},
},
},
OS: &OS{
ResetBootLoaderType: "hard-reset",
Verity: &Verity{
DataPartition: IdentifiedPartition{
IdType: IdTypeId,
Id: "wrongname",
},
HashPartition: IdentifiedPartition{
IdType: IdTypeId,
Id: "verityhash",
},
},
},
}
err := config.IsValid()
assert.ErrorContains(t, err, "invalid verity 'dataPartition'")
assert.ErrorContains(t, err, "partition with 'id' (wrongname) not found")
assert.ErrorContains(t, err, "invalid verity item at index 0:")
assert.ErrorContains(t, err, "invalid 'dataDeviceId'")
assert.ErrorContains(t, err, "device (wrongname) not found")
}

func TestConfigIsValidVerityNoStorage(t *testing.T) {
config := &Config{
OS: &OS{
Verity: &Verity{
DataPartition: IdentifiedPartition{
IdType: IdTypePartLabel,
Id: "root",
},
HashPartition: IdentifiedPartition{
IdType: IdTypeId,
Id: "verityhash",
Storage: Storage{
Verity: []Verity{
{
Id: "rootverity",
Name: "root",
DataDeviceId: "root",
HashDeviceId: "verityhash",
},
},
},
}
err := config.IsValid()
assert.ErrorContains(t, err, "invalid verity 'hashPartition'")
assert.ErrorContains(t, err, "'idType' cannot be 'id' if 'storage.disks' is not specified")
assert.ErrorContains(t, err, "cannot specify 'verity' without specifying 'disks'")
}
9 changes: 9 additions & 0 deletions toolkit/tools/imagecustomizerapi/filesystem.go
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,11 @@ type FileSystem struct {
Type FileSystemType `yaml:"type"`
// MountPoint contains the mount settings.
MountPoint *MountPoint `yaml:"mountPoint"`

// If 'DeviceId' points at a verity device, this value is the 'Id' of the data partition.
// Otherwise, it is the same as 'DeviceId'.
// Value is filled in by Storage.IsValid().
PartitionId string
}

// IsValid returns an error if the MountPoint is not valid
Expand All @@ -33,6 +38,10 @@ func (f *FileSystem) IsValid() error {
if err != nil {
return fmt.Errorf("invalid mountPoint value:\n%w", err)
}

if f.Type == FileSystemTypeNone {
return fmt.Errorf("filesystem with 'mountPoint' must have a 'type'")
}
}

return nil
Expand Down
44 changes: 0 additions & 44 deletions toolkit/tools/imagecustomizerapi/identifiedpartition.go

This file was deleted.

87 changes: 0 additions & 87 deletions toolkit/tools/imagecustomizerapi/identifiedpartition_test.go

This file was deleted.

8 changes: 0 additions & 8 deletions toolkit/tools/imagecustomizerapi/os.go
Original file line number Diff line number Diff line change
Expand Up @@ -22,7 +22,6 @@ type OS struct {
Users []User `yaml:"users"`
Services Services `yaml:"services"`
Modules []Module `yaml:"modules"`
Verity *Verity `yaml:"verity"`
Overlays *[]Overlay `yaml:"overlays"`
}

Expand Down Expand Up @@ -83,13 +82,6 @@ func (s *OS) IsValid() error {
}
}

if s.Verity != nil {
err = s.Verity.IsValid()
if err != nil {
return fmt.Errorf("invalid verity:\n%w", err)
}
}

if s.Overlays != nil {
mountPoints := make(map[string]bool)
upperDirs := make(map[string]bool)
Expand Down
19 changes: 0 additions & 19 deletions toolkit/tools/imagecustomizerapi/os_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -53,25 +53,6 @@ func TestOSIsValidInvalidAdditionalFilesContent(t *testing.T) {
assert.NoError(t, err)
}

func TestOSIsValidVerityInValidPartUuid(t *testing.T) {
invalidVerity := OS{
Verity: &Verity{
DataPartition: IdentifiedPartition{
IdType: "part-uuid",
Id: "incorrect-uuid-format",
},
HashPartition: IdentifiedPartition{
IdType: "part-label",
Id: "hash_partition",
},
},
}

err := invalidVerity.IsValid()
assert.Error(t, err)
assert.ErrorContains(t, err, "invalid id format")
}

func TestOSIsValidInvalidResetBootLoaderType(t *testing.T) {
os := OS{
ResetBootLoaderType: "bad",
Expand Down
Loading

0 comments on commit 294f2ab

Please sign in to comment.