Delete internal/blueprint/ and import from osbuild/blueprint

Import osbuild/blueprint v1.6.0
This commit is contained in:
Achilleas Koutsou 2025-03-25 17:15:30 +01:00
parent 362712a71d
commit cf956ff5a6
93 changed files with 2300 additions and 4163 deletions

View file

@ -11,10 +11,10 @@ import (
const DefaultBtrfsCompression = "zstd:1"
type Btrfs struct {
UUID string
Label string
Mountpoint string
Subvolumes []BtrfsSubvolume
UUID string `json:"uuid,omitempty" yaml:"uuid,omitempty"`
Label string `json:"label,omitempty" yaml:"label,omitempty"`
Mountpoint string `json:"mountpoint,omitempty" yaml:"mountpoint,omitempty"`
Subvolumes []BtrfsSubvolume `json:"subvolumes,omitempty" yaml:"subvolumes,omitempty"`
}
func init() {
@ -107,15 +107,15 @@ func (b *Btrfs) minSize(size uint64) uint64 {
}
type BtrfsSubvolume struct {
Name string
Size uint64
Mountpoint string
GroupID uint64
Compress string
ReadOnly bool
Name string `json:"name" yaml:"name"`
Size uint64 `json:"size" yaml:"size"`
Mountpoint string `json:"mountpoint,omitempty" yaml:"mountpoint,omitempty"`
GroupID uint64 `json:"group_id,omitempty" yaml:"group_id,omitempty"`
Compress string `json:"compress,omitempty" yaml:"compress,omitempty"`
ReadOnly bool `json:"read_only,omitempty" yaml:"read_only,omitempty"`
// UUID of the parent volume
UUID string
UUID string `json:"uuid,omitempty" yaml:"uuid,omitempty"`
}
func (bs *BtrfsSubvolume) Clone() Entity {

View file

@ -24,11 +24,11 @@ import (
"io"
"math/rand"
"reflect"
"slices"
"strings"
"slices"
"github.com/google/uuid"
"github.com/osbuild/images/pkg/arch"
)
@ -248,6 +248,10 @@ func (t PartitionTableType) MarshalJSON() ([]byte, error) {
return json.Marshal(t.String())
}
func (t PartitionTableType) MarshalYAML() (interface{}, error) {
return t.String(), nil
}
func (t *PartitionTableType) UnmarshalJSON(data []byte) error {
var s string
if err := json.Unmarshal(data, &s); err != nil {

View file

@ -9,19 +9,19 @@ import (
// Filesystem related functions
type Filesystem struct {
Type string `json:"type"`
Type string `json:"type" yaml:"type"`
// ID of the filesystem, vfat doesn't use traditional UUIDs, therefore this
// is just a string.
UUID string `json:"uuid,omitempty"`
Label string `json:"label,omitempty"`
Mountpoint string `json:"mountpoint,omitempty"`
UUID string `json:"uuid,omitempty" yaml:"uuid,omitempty"`
Label string `json:"label,omitempty" yaml:"label,omitempty"`
Mountpoint string `json:"mountpoint,omitempty" yaml:"mountpoint,omitempty"`
// The fourth field of fstab(5); fs_mntops
FSTabOptions string `json:"fstab_options,omitempty"`
FSTabOptions string `json:"fstab_options,omitempty" yaml:"fstab_options,omitempty"`
// The fifth field of fstab(5); fs_freq
FSTabFreq uint64 `json:"fstab_freq,omitempty"`
FSTabFreq uint64 `json:"fstab_freq,omitempty" yaml:"fstab_freq,omitempty"`
// The sixth field of fstab(5); fs_passno
FSTabPassNo uint64 `json:"fstab_passno,omitempty"`
FSTabPassNo uint64 `json:"fstab_passno,omitempty" yaml:"fstab_passno,omitempty"`
}
func init() {

View file

@ -1,6 +1,7 @@
package disk
import (
"encoding/json"
"fmt"
"math/rand"
"reflect"
@ -13,41 +14,41 @@ import (
// Argon2id defines parameters for the key derivation function for LUKS.
type Argon2id struct {
// Number of iterations to perform.
Iterations uint
Iterations uint `json:"iterations,omitempty" yaml:"iterations,omitempty"`
// Amount of memory to use (in KiB).
Memory uint
Memory uint `json:"memory,omitempty" yaml:"memory,omitempty"`
// Degree of parallelism (i.e. number of threads).
Parallelism uint
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
Policy string
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
RemovePassphrase bool `json:"remove_passphrase,omitempty" yaml:"remove_passphrase,omitempty"`
}
// LUKSContainer represents a LUKS encrypted volume.
type LUKSContainer struct {
Passphrase string
UUID string
Cipher string
Label string
Subsystem string
SectorSize uint64
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
PBKDF Argon2id `json:"pbkdf,omitempty" yaml:"pbkdf,omitempty"`
// Parameters for binding the LUKS device.
Clevis *ClevisBind
Clevis *ClevisBind `json:"clevis,omitempty" yaml:"clevis,omitempty"`
Payload Entity
Payload Entity `json:"payload,omitempty" yaml:"payload,omitempty"`
}
func init() {
@ -131,3 +132,24 @@ func (lc *LUKSContainer) minSize(size uint64) uint64 {
}
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 unmarshalYAMLviaJSON(lc, unmarshal)
}

View file

@ -1,6 +1,7 @@
package disk
import (
"encoding/json"
"fmt"
"reflect"
"strings"
@ -13,10 +14,10 @@ import (
const LVMDefaultExtentSize = 4 * datasizes.MebiByte
type LVMVolumeGroup struct {
Name string
Description string
Name string `json:"name,omitempty" yaml:"name,omitempty"`
Description string `json:"description,omitempty" yaml:"description,omitempty"`
LogicalVolumes []LVMLogicalVolume
LogicalVolumes []LVMLogicalVolume `json:"logical_volumes,omitempty" yaml:"logical_volumes,omitempty"`
}
func init() {
@ -174,10 +175,20 @@ func (vg *LVMVolumeGroup) minSize(size uint64) uint64 {
return vg.AlignUp(size)
}
func (vg *LVMVolumeGroup) UnmarshalJSON(data []byte) error {
type alias LVMVolumeGroup
var tmp alias
if err := json.Unmarshal(data, &tmp); err != nil {
return err
}
*vg = LVMVolumeGroup(tmp)
return nil
}
type LVMLogicalVolume struct {
Name string
Size uint64
Payload Entity
Name string `json:"name,omitempty" yaml:"name,omitempty"`
Size uint64 `json:"size,omitempty" yaml:"size,omitempty"`
Payload Entity `json:"payload,omitempty" yaml:"payload,omitempty"`
}
func (lv *LVMLogicalVolume) Clone() Entity {
@ -232,3 +243,24 @@ func lvname(path string) string {
path = strings.TrimLeft(path, "/")
return strings.ReplaceAll(path, "/", "_") + "lv"
}
func (lv *LVMLogicalVolume) UnmarshalJSON(data []byte) (err error) {
// keep in sync with lvm.go,partition.go,luks.go
type alias LVMLogicalVolume
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)
}
*lv = LVMLogicalVolume(withoutPayload.alias)
lv.Payload, err = unmarshalJSONPayload(data)
return err
}
func (lv *LVMLogicalVolume) UnmarshalYAML(unmarshal func(any) error) error {
return unmarshalYAMLviaJSON(lv, unmarshal)
}

View file

@ -1,28 +1,26 @@
package disk
import (
"bytes"
"encoding/json"
"fmt"
"reflect"
)
type Partition struct {
// Start of the partition in bytes
Start uint64 `json:"start"`
Start uint64 `json:"start,omitempty" yaml:"start,omitempty"`
// Size of the partition in bytes
Size uint64 `json:"size"`
Size uint64 `json:"size" yaml:"size"`
// Partition type, e.g. 0x83 for MBR or a UUID for gpt
Type string `json:"type,omitempty"`
Type string `json:"type,omitempty" yaml:"type,omitempty"`
// `Legacy BIOS bootable` (GPT) or `active` (DOS) flag
Bootable bool `json:"bootable,omitempty"`
Bootable bool `json:"bootable,omitempty" yaml:"bootable,omitempty"`
// ID of the partition, dos doesn't use traditional UUIDs, therefore this
// is just a string.
UUID string `json:"uuid,omitempty"`
UUID string `json:"uuid,omitempty" yaml:"uuid,omitempty"`
// If nil, the partition is raw; It doesn't contain a payload.
Payload PayloadEntity `json:"payload,omitempty"`
Payload PayloadEntity `json:"payload,omitempty" yaml:"payload,omitempty"`
}
func (p *Partition) Clone() Entity {
@ -105,14 +103,14 @@ func (p *Partition) IsPReP() bool {
func (p *Partition) MarshalJSON() ([]byte, error) {
type partAlias Partition
entityName := "no-payload"
var entityName string
if p.Payload != nil {
entityName = p.Payload.EntityName()
}
partWithPayloadType := struct {
partAlias
PayloadType string `json:"payload_type,omitempty"`
PayloadType string `json:"payload_type,omitempty" yaml:"payload_type,omitempty"`
}{
partAlias(*p),
entityName,
@ -121,36 +119,23 @@ func (p *Partition) MarshalJSON() ([]byte, error) {
return json.Marshal(partWithPayloadType)
}
func (p *Partition) UnmarshalJSON(data []byte) error {
type partAlias Partition
var partWithoutPayload struct {
partAlias
Payload json.RawMessage `json:"payload"`
PayloadType string `json:"payload_type,omitempty"`
func (p *Partition) UnmarshalJSON(data []byte) (err error) {
// keep in sync with lvm.go,partition.go,luks.go
type alias Partition
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)
}
*p = Partition(withoutPayload.alias)
dec := json.NewDecoder(bytes.NewBuffer(data))
if err := dec.Decode(&partWithoutPayload); err != nil {
return fmt.Errorf("cannot build partition from %q: %w", data, err)
}
*p = Partition(partWithoutPayload.partAlias)
// no payload, e.g. bios partiton
if partWithoutPayload.PayloadType == "no-payload" {
return nil
}
entType := payloadEntityMap[partWithoutPayload.PayloadType]
if entType == nil {
return fmt.Errorf("cannot build partition from %q: unknown payload %q", data, partWithoutPayload.PayloadType)
}
entValP := reflect.New(entType).Elem().Addr()
ent := entValP.Interface()
if err := json.Unmarshal(partWithoutPayload.Payload, &ent); err != nil {
return err
}
p.Payload = ent.(PayloadEntity)
return nil
p.Payload, err = unmarshalJSONPayload(data)
return err
}
func (t *Partition) UnmarshalYAML(unmarshal func(any) error) error {
return unmarshalYAMLviaJSON(t, unmarshal)
}

View file

@ -15,19 +15,19 @@ import (
type PartitionTable struct {
// Size of the disk (in bytes).
Size uint64 `json:"size"`
Size uint64 `json:"size,omitempty" yaml:"size,omitempty"`
// Unique identifier of the partition table (GPT only).
UUID string `json:"uuid,omitempty"`
UUID string `json:"uuid,omitempty" yaml:"uuid,omitempty"`
// Partition table type, e.g. dos, gpt.
Type PartitionTableType `json:"type"`
Partitions []Partition `json:"partitions"`
Type PartitionTableType `json:"type" yaml:"type"`
Partitions []Partition `json:"partitions" yaml:"partitions"`
// Sector size in bytes
SectorSize uint64 `json:"sector_size,omitempty"`
SectorSize uint64 `json:"sector_size,omitempty" yaml:"sector_size,omitempty"`
// Extra space at the end of the partition table (sectors)
ExtraPadding uint64 `json:"extra_padding,omitempty"`
ExtraPadding uint64 `json:"extra_padding,omitempty" yaml:"extra_padding,omitempty"`
// Starting offset of the first partition in the table (Mb)
StartOffset uint64 `json:"start_offset,omitempty"`
StartOffset uint64 `json:"start_offset,omitempty" yaml:"start_offset,omitempty"`
}
type PartitioningMode string

View file

@ -1,8 +1,10 @@
package disk
import (
"bytes"
"encoding/json"
"fmt"
"reflect"
)
// unmarshalYAMLviaJSON unmarshals via the JSON interface, this avoids code
@ -22,3 +24,35 @@ func unmarshalYAMLviaJSON(u json.Unmarshaler, unmarshal func(any) error) error {
}
return nil
}
func unmarshalJSONPayload(data []byte) (PayloadEntity, error) {
var payload struct {
Payload json.RawMessage `json:"payload"`
PayloadType string `json:"payload_type,omitempty"`
}
if err := json.Unmarshal(data, &payload); err != nil {
return nil, fmt.Errorf("cannot peek payload: %w", err)
}
if payload.PayloadType == "" {
if len(payload.Payload) > 0 {
return nil, fmt.Errorf("cannot build payload: empty payload type but payload is: %q", payload.Payload)
}
return nil, nil
}
entType := payloadEntityMap[payload.PayloadType]
if entType == nil {
return nil, fmt.Errorf("cannot build payload from %q: unknown payload type %q", data, payload.PayloadType)
}
entValP := reflect.New(entType).Elem().Addr()
ent := entValP.Interface()
if err := jsonUnmarshalStrict(payload.Payload, &ent); err != nil {
return nil, fmt.Errorf("cannot decode payload for %q: %w", data, err)
}
return ent.(PayloadEntity), nil
}
func jsonUnmarshalStrict(data []byte, v any) error {
dec := json.NewDecoder(bytes.NewBuffer(data))
dec.DisallowUnknownFields()
return dec.Decode(&v)
}