tag v0.142.0 Tagger: imagebuilder-bot <imagebuilder-bots+imagebuilder-bot@redhat.com> Changes with 0.142.0 ---------------- * distro: move `kernelOptions` into `ImageConfig` (osbuild/images#1470) * Author: Michael Vogt, Reviewers: Achilleas Koutsou, Tomáš Hozza * manifest: register insights to template on boot (HMS-5994) (osbuild/images#1443) * Author: rverdile, Reviewers: Achilleas Koutsou, Tomáš Hozza * many: add custom unmarshalers for osbuild, platform (osbuild/images#1477) * Author: Michael Vogt, Reviewers: Achilleas Koutsou, Tomáš Hozza — Somewhere on the Internet, 2025-05-05 --- tag v0.143.0 Tagger: imagebuilder-bot <imagebuilder-bots+imagebuilder-bot@redhat.com> Changes with 0.143.0 ---------------- * distro/rhel9/azure: drop net.ifnames=0 kernel arg (RHEL-89440) (osbuild/images#1487) * Author: Achilleas Koutsou, Reviewers: Michael Vogt, Sanne Raymaekers * github: don't run manifest checksum validation on the merge queue (osbuild/images#1478) * Author: Achilleas Koutsou, Reviewers: Brian C. Lane, Florian Schüller * repositories: Set 6h expire on main repo, use default for updates (osbuild/images#1482) * Author: Brian C. Lane, Reviewers: Achilleas Koutsou, Neal Gompa (ニール・ゴンパ), Simon de Vlieger — Somewhere on the Internet, 2025-05-05 ---
156 lines
4.3 KiB
Go
156 lines
4.3 KiB
Go
package disk
|
|
|
|
import (
|
|
"encoding/json"
|
|
"fmt"
|
|
"math/rand"
|
|
"reflect"
|
|
|
|
"github.com/google/uuid"
|
|
|
|
"github.com/osbuild/images/internal/common"
|
|
"github.com/osbuild/images/pkg/datasizes"
|
|
)
|
|
|
|
// Argon2id defines parameters for the key derivation function for LUKS.
|
|
type Argon2id struct {
|
|
// Number of iterations to perform.
|
|
Iterations uint `json:"iterations,omitempty" yaml:"iterations,omitempty"`
|
|
|
|
// Amount of memory to use (in KiB).
|
|
Memory uint `json:"memory,omitempty" yaml:"memory,omitempty"`
|
|
|
|
// Degree of parallelism (i.e. number of threads).
|
|
Parallelism uint `json:"parallelism,omitempty" yaml:"parallelism,omitempty"`
|
|
}
|
|
|
|
// ClevisBind defines parameters for binding a LUKS device with a given policy.
|
|
type ClevisBind struct {
|
|
Pin string `json:"pin,omitempty" yaml:"pin,omitempty"`
|
|
Policy string `json:"policy,omitempty" yaml:"policy,omitempty"`
|
|
|
|
// If enabled, the passphrase will be removed from the LUKS device at the
|
|
// end of the build (using the org.osbuild.luks2.remove-key stage).
|
|
RemovePassphrase bool `json:"remove_passphrase,omitempty" yaml:"remove_passphrase,omitempty"`
|
|
}
|
|
|
|
// LUKSContainer represents a LUKS encrypted volume.
|
|
type LUKSContainer struct {
|
|
Passphrase string `json:"passphrase,omitempty" yaml:"passphrase,omitempty"`
|
|
UUID string `json:"uuid,omitempty" yaml:"uuid,omitempty"`
|
|
Cipher string `json:"cipher,omitempty" yaml:"cipher,omitempty"`
|
|
Label string `json:"label,omitempty" yaml:"label,omitempty"`
|
|
Subsystem string `json:"subsystem,omitempty" yaml:"subsystem,omitempty"`
|
|
SectorSize uint64 `json:"sector_size,omitempty" yaml:"sector_size,omitempty"`
|
|
|
|
// The password-based key derivation function's parameters.
|
|
PBKDF Argon2id `json:"pbkdf,omitempty" yaml:"pbkdf,omitempty"`
|
|
|
|
// Parameters for binding the LUKS device.
|
|
Clevis *ClevisBind `json:"clevis,omitempty" yaml:"clevis,omitempty"`
|
|
|
|
Payload Entity `json:"payload,omitempty" yaml:"payload,omitempty"`
|
|
}
|
|
|
|
func init() {
|
|
payloadEntityMap["luks"] = reflect.TypeOf(LUKSContainer{})
|
|
}
|
|
|
|
func (lc *LUKSContainer) EntityName() string {
|
|
return "luks"
|
|
}
|
|
|
|
func (lc *LUKSContainer) GetItemCount() uint {
|
|
if lc.Payload == nil {
|
|
return 0
|
|
}
|
|
return 1
|
|
}
|
|
|
|
func (lc *LUKSContainer) GetChild(n uint) Entity {
|
|
if n != 0 {
|
|
panic(fmt.Sprintf("invalid child index for LUKSContainer: %d != 0", n))
|
|
}
|
|
return lc.Payload
|
|
}
|
|
|
|
func (lc *LUKSContainer) Clone() Entity {
|
|
if lc == nil {
|
|
return nil
|
|
}
|
|
clc := &LUKSContainer{
|
|
Passphrase: lc.Passphrase,
|
|
UUID: lc.UUID,
|
|
Cipher: lc.Cipher,
|
|
Label: lc.Label,
|
|
Subsystem: lc.Subsystem,
|
|
SectorSize: lc.SectorSize,
|
|
PBKDF: Argon2id{
|
|
Iterations: lc.PBKDF.Iterations,
|
|
Memory: lc.PBKDF.Memory,
|
|
Parallelism: lc.PBKDF.Parallelism,
|
|
},
|
|
Payload: lc.Payload.Clone(),
|
|
}
|
|
if lc.Clevis != nil {
|
|
clc.Clevis = &ClevisBind{
|
|
Pin: lc.Clevis.Pin,
|
|
Policy: lc.Clevis.Policy,
|
|
RemovePassphrase: lc.Clevis.RemovePassphrase,
|
|
}
|
|
}
|
|
return clc
|
|
}
|
|
|
|
func (lc *LUKSContainer) GenUUID(rng *rand.Rand) {
|
|
if lc == nil {
|
|
return
|
|
}
|
|
|
|
if lc.UUID == "" {
|
|
lc.UUID = uuid.Must(newRandomUUIDFromReader(rng)).String()
|
|
}
|
|
}
|
|
|
|
func (lc *LUKSContainer) MetadataSize() uint64 {
|
|
if lc == nil {
|
|
return 0
|
|
}
|
|
|
|
// 16 MiB is the default size for the LUKS2 header
|
|
return 16 * datasizes.MiB
|
|
}
|
|
|
|
func (lc *LUKSContainer) minSize(size uint64) uint64 {
|
|
// since a LUKS container can contain pretty much any payload, but we only
|
|
// care about the ones that have a size, or contain children with sizes
|
|
minSize := lc.MetadataSize()
|
|
switch payload := lc.Payload.(type) {
|
|
case VolumeContainer:
|
|
minSize += payload.minSize(size)
|
|
case Sizeable:
|
|
minSize += payload.GetSize()
|
|
}
|
|
return minSize
|
|
}
|
|
|
|
func (lc *LUKSContainer) UnmarshalJSON(data []byte) (err error) {
|
|
// keep in sync with lvm.go,partition.go,luks.go
|
|
type alias LUKSContainer
|
|
var withoutPayload struct {
|
|
alias
|
|
Payload json.RawMessage `json:"payload" yaml:"payload"`
|
|
PayloadType string `json:"payload_type" yaml:"payload_type"`
|
|
}
|
|
if err := jsonUnmarshalStrict(data, &withoutPayload); err != nil {
|
|
return fmt.Errorf("cannot unmarshal %q: %w", data, err)
|
|
}
|
|
*lc = LUKSContainer(withoutPayload.alias)
|
|
|
|
lc.Payload, err = unmarshalJSONPayload(data)
|
|
return err
|
|
}
|
|
|
|
func (lc *LUKSContainer) UnmarshalYAML(unmarshal func(any) error) error {
|
|
return common.UnmarshalYAMLviaJSON(lc, unmarshal)
|
|
}
|