Skip to content

Commit 5835064

Browse files
authored
Add reinitializeVerity API. (#351)
Add API that controls how verity partitions in the base image are handled. Specifically, whether or not the verity data partitions are set to read-only or read-write during OS customization. The primary scenario being targeted is recustomizing an image with a usr verity partition + UKIs without changing/invalidating the /usr partition or the UKIs. A functional test has been added for this scenario.
1 parent 5a42f27 commit 5835064

24 files changed

+308
-83
lines changed

docs/imagecustomizer/api/configuration.md

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -155,6 +155,7 @@ os:
155155
- [options](./configuration/mountpoint.md#options-string)
156156
- [path](./configuration/mountpoint.md#path-string)
157157
- [resetPartitionsUuidsType](./configuration/storage.md#resetpartitionsuuidstype-string)
158+
- [reinitializeVerity](./configuration/storage.md#reinitializeverity-string)
158159
- [iso](./configuration/config.md#iso-iso) ([iso type](./configuration/iso.md))
159160
- [additionalFiles](./configuration/iso.md#additionalfiles-additionalfile)
160161
- [additionalFile type](./configuration/additionalfile.md)

docs/imagecustomizer/api/configuration/storage.md

Lines changed: 18 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -136,3 +136,21 @@ os:
136136
```
137137

138138
Added in v0.7.
139+
140+
## reinitializeVerity [string]
141+
142+
This is a preview feature.
143+
Its API and behavior is subject to change.
144+
You must enable this feature by specifying `reinitialize-verity` in the
145+
[previewFeatures](./config.md#previewfeatures-string) API.
146+
147+
When the base image contains verity partitions, controls whether or not the verity
148+
partitions can be modified.
149+
150+
Supported options:
151+
152+
- `none`: During OS customization, all verity data partitions are mounted as read-only.
153+
The verity hash partitions are left unchanged.
154+
155+
- `all`: During OS customization, all verity data partitions are mounted as read-write.
156+
The verity hash partitions will be regenerated.

toolkit/tools/imagecustomizerapi/config.go

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -118,6 +118,11 @@ func (c *Config) IsValid() (err error) {
118118
}
119119
}
120120

121+
if c.Storage.ReinitializeVerity != ReinitializeVerityTypeDefault &&
122+
!sliceutils.ContainsValue(c.PreviewFeatures, PreviewFeatureReinitializeVerity) {
123+
return fmt.Errorf("the 'reinitialize-verity' preview feature must be enabled to use 'storage.reinitializeVerity'")
124+
}
125+
121126
return nil
122127
}
123128

Lines changed: 27 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,27 @@
1+
// Copyright (c) Microsoft Corporation.
2+
// Licensed under the MIT License.
3+
4+
package imagecustomizerapi
5+
6+
import (
7+
"fmt"
8+
)
9+
10+
type ReinitializeVerityType string
11+
12+
const (
13+
ReinitializeVerityTypeDefault ReinitializeVerityType = ""
14+
ReinitializeVerityTypeNone ReinitializeVerityType = "none"
15+
ReinitializeVerityTypeAll ReinitializeVerityType = "all"
16+
)
17+
18+
func (t ReinitializeVerityType) IsValid() error {
19+
switch t {
20+
case ReinitializeVerityTypeDefault, ReinitializeVerityTypeNone, ReinitializeVerityTypeAll:
21+
// All good.
22+
return nil
23+
24+
default:
25+
return fmt.Errorf("invalid value (%s)", t)
26+
}
27+
}

toolkit/tools/imagecustomizerapi/schema.json

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -592,6 +592,9 @@
592592
"$ref": "#/$defs/Verity"
593593
},
594594
"type": "array"
595+
},
596+
"reinitializeVerity": {
597+
"type": "string"
595598
}
596599
},
597600
"additionalProperties": false,

toolkit/tools/imagecustomizerapi/storage.go

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -26,6 +26,7 @@ type Storage struct {
2626
Disks []Disk `yaml:"disks" json:"disks,omitempty"`
2727
FileSystems []FileSystem `yaml:"filesystems" json:"filesystems,omitempty"`
2828
Verity []Verity `yaml:"verity" json:"verity,omitempty"`
29+
ReinitializeVerity ReinitializeVerityType `yaml:"reinitializeVerity" json:"reinitializeVerity,omitempty"`
2930

3031
// Filled in by Storage.IsValid().
3132
VerityPartitionsType VerityPartitionsType `json:"-"`
@@ -96,6 +97,11 @@ func (s *Storage) IsValid() error {
9697
}
9798
}
9899

100+
err = s.ReinitializeVerity.IsValid()
101+
if err != nil {
102+
return fmt.Errorf("invalid 'reinitializeVerity' value:\n%w", err)
103+
}
104+
99105
hasResetUuids := s.ResetPartitionsUuidsType != ResetPartitionsUuidsTypeDefault
100106
hasBootType := s.BootType != BootTypeNone
101107
hasDisks := len(s.Disks) > 0

toolkit/tools/internal/safechroot/safechroot.go

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -176,6 +176,11 @@ func (m *MountPoint) GetTarget() string {
176176
return m.target
177177
}
178178

179+
// GetFlags gets the flags of the mount.
180+
func (m *MountPoint) GetFlags() uintptr {
181+
return m.flags
182+
}
183+
179184
// NewChroot creates a new Chroot struct
180185
func NewChroot(rootDir string, isExistingDir bool) *Chroot {
181186
// get chroot folder

toolkit/tools/pkg/imagecustomizerlib/artifactsinputoutput.go

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -364,8 +364,8 @@ func prepareImageConversionData(ctx context.Context, rawImageFile string, buildD
364364
) (map[string]diskutils.FstabEntry, []verityDeviceMetadata, string,
365365
[]OsPackage, [randomization.UuidSize]byte, string, *CosiBootloader, error,
366366
) {
367-
imageConnection, partUuidToFstabEntry, baseImageVerityMetadata, err := connectToExistingImage(ctx,
368-
rawImageFile, buildDir, chrootDir, true, true)
367+
imageConnection, partUuidToFstabEntry, baseImageVerityMetadata, _, err := connectToExistingImage(ctx,
368+
rawImageFile, buildDir, chrootDir, true, true, false)
369369
if err != nil {
370370
return nil, nil, "", nil, [randomization.UuidSize]byte{}, "", nil, fmt.Errorf("failed to connect to image:\n%w", err)
371371
}

toolkit/tools/pkg/imagecustomizerlib/customizeos.go

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -78,7 +78,7 @@ func doOsCustomizations(ctx context.Context, buildDir string, baseConfigPath str
7878
}
7979

8080
if config.OS.ImageHistory != imagecustomizerapi.ImageHistoryNone {
81-
err = addImageHistory(ctx, imageChroot.RootDir(), imageUuid, baseConfigPath, ToolVersion, buildTime, config)
81+
err = addImageHistory(ctx, imageChroot, imageUuid, baseConfigPath, ToolVersion, buildTime, config)
8282
if err != nil {
8383
return err
8484
}

toolkit/tools/pkg/imagecustomizerlib/customizepartitionsfilecopy.go

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -17,7 +17,8 @@ import (
1717
func customizePartitionsUsingFileCopy(ctx context.Context, buildDir string, baseConfigPath string, config *imagecustomizerapi.Config,
1818
buildImageFile string, newBuildImageFile string,
1919
) (map[string]string, error) {
20-
existingImageConnection, _, _, err := connectToExistingImage(ctx, buildImageFile, buildDir, "imageroot", false, false)
20+
existingImageConnection, _, _, _, err := connectToExistingImage(ctx, buildImageFile, buildDir, "imageroot", false,
21+
true, false)
2122
if err != nil {
2223
return nil, err
2324
}

0 commit comments

Comments
 (0)