distro/rhel86: add fido dracut module and enable customizing onboarding

This patch also introduces customizations to fully enable onboarding
options for FDO.

Co-Authored-By: Christian Kellner <christian@kellner.me>
This commit is contained in:
Antonio Murdaca 2022-02-24 12:29:33 +01:00 committed by Christian Kellner
parent 892cfb67cc
commit e2bd3506e2
5 changed files with 92 additions and 12 deletions

View file

@ -20,6 +20,16 @@ type Customizations struct {
Services *ServicesCustomization `json:"services,omitempty" toml:"services,omitempty"`
Filesystem []FilesystemCustomization `json:"filesystem,omitempty" toml:"filesystem,omitempty"`
InstallationDevice string `json:"installation_device,omitempty" toml:"installation_device,omitempty"`
FDO *FDOCustomization `json:"fdo,omitempty" toml:"fdo,omitempty"`
}
type FDOCustomization struct {
ManufacturingServerURL string `json:"manufacturing_server_url,omitempty" toml:"manufacturing_server_url,omitempty"`
DiunPubKeyInsecure string `json:"diun_pub_key_insecure,omitempty" toml:"diun_pub_key_insecure,omitempty"`
// This is the output of:
// echo "sha256:$(openssl x509 -fingerprint -sha256 -noout -in diun_cert.pem | cut -d"=" -f2 | sed 's/://g')"
DiunPubKeyHash string `json:"diun_pub_key_hash,omitempty" toml:"diun_pub_key_hash,omitempty"`
DiunPubKeyRootCerts string `json:"diun_pub_key_root_certs,omitempty" toml:"diun_pub_key_root_certs,omitempty"`
}
type KernelCustomization struct {
@ -337,3 +347,10 @@ func (c *Customizations) GetInstallationDevice() string {
}
return c.InstallationDevice
}
func (c *Customizations) GetFDO() *FDOCustomization {
if c == nil {
return nil
}
return c.FDO
}

View file

@ -449,20 +449,30 @@ func (t *imageType) Manifest(customizations *blueprint.Customizations,
allPackageSpecs = append(allPackageSpecs, specs...)
}
// handle OSTree commit inputs
var commits []ostreeCommit
if options.OSTree.Parent != "" && options.OSTree.URL != "" {
commits = []ostreeCommit{{Checksum: options.OSTree.Parent, URL: options.OSTree.URL}}
}
// handle inline sources
inlineData := []string{}
// FDO root certs, if any, are transmitted via an inline source
if fdo := customizations.GetFDO(); fdo != nil && fdo.DiunPubKeyRootCerts != "" {
inlineData = append(inlineData, fdo.DiunPubKeyRootCerts)
}
return json.Marshal(
osbuild.Manifest{
Version: "2",
Pipelines: pipelines,
Sources: t.sources(allPackageSpecs, commits),
Sources: t.sources(allPackageSpecs, commits, inlineData),
},
)
}
func (t *imageType) sources(packages []rpmmd.PackageSpec, ostreeCommits []ostreeCommit) osbuild.Sources {
func (t *imageType) sources(packages []rpmmd.PackageSpec, ostreeCommits []ostreeCommit, inlineData []string) osbuild.Sources {
sources := osbuild.Sources{}
curl := &osbuild.CurlSource{
Items: make(map[string]osbuild.CurlSourceItem),
@ -492,6 +502,16 @@ func (t *imageType) sources(packages []rpmmd.PackageSpec, ostreeCommits []ostree
if len(ostree.Items) > 0 {
sources["org.osbuild.ostree"] = ostree
}
if len(inlineData) > 0 {
ils := osbuild.NewInlineSource()
for _, data := range inlineData {
ils.AddItem(data)
}
sources["org.osbuild.inline"] = ils
}
return sources
}
@ -522,12 +542,31 @@ func (t *imageType) checkOptions(customizations *blueprint.Customizations, optio
}
if t.name == "edge-simplified-installer" {
if err := customizations.CheckAllowed("InstallationDevice"); err != nil {
if err := customizations.CheckAllowed("InstallationDevice", "FDO"); err != nil {
return fmt.Errorf("boot ISO image type %q contains unsupported blueprint customizations: %v", t.name, err)
}
if customizations.GetInstallationDevice() == "" {
return fmt.Errorf("boot ISO image type %q requires specifying an installation device to install to", t.name)
}
if customizations.GetFDO() == nil {
return fmt.Errorf("boot ISO image type %q requires specifying FDO configuration to install to", t.name)
}
if customizations.GetFDO().ManufacturingServerURL == "" {
return fmt.Errorf("boot ISO image type %q requires specifying FDO.ManufacturingServerURL configuration to install to", t.name)
}
var diunSet int
if customizations.GetFDO().DiunPubKeyHash != "" {
diunSet++
}
if customizations.GetFDO().DiunPubKeyInsecure != "" {
diunSet++
}
if customizations.GetFDO().DiunPubKeyRootCerts != "" {
diunSet++
}
if diunSet != 1 {
return fmt.Errorf("boot ISO image type %q requires specifying one of [FDO.DiunPubKeyHash,FDO.DiunPubKeyInsecure,FDO.DiunPubKeyRootCerts] configuration to install to", t.name)
}
} else if customizations != nil {
return fmt.Errorf("boot ISO image type %q does not support blueprint customizations", t.name)
}
@ -620,7 +659,8 @@ func newDistro(distroName string) distro.Distro {
// Shared Services
edgeServices := []string{
"NetworkManager.service", "firewalld.service", "sshd.service",
// TODO(runcom): move fdo-client-linuxapp.service to presets?
"NetworkManager.service", "firewalld.service", "sshd.service", "fdo-client-linuxapp.service",
}
// Image Definitions

View file

@ -451,6 +451,7 @@ func edgeCommitPackageSet(t *imageType) rpmmd.PackageSet {
"container-selinux", "skopeo", "criu", "slirp4netns",
"fuse-overlayfs", "clevis", "clevis-dracut", "clevis-luks",
"greenboot", "greenboot-default-health-checks",
"fdo-client", "fdo-owner-cli",
},
Exclude: []string{"rng-tools"},
}
@ -744,6 +745,7 @@ func edgeSimplifiedInstallerPackageSet(t *imageType) rpmmd.PackageSet {
"cloud-utils-growpart",
"coreos-installer",
"coreos-installer-dracut",
"fdo-init",
"coreutils",
"device-mapper-multipath",
"dnsmasq",

View file

@ -670,9 +670,9 @@ func edgeSimplifiedInstallerPipelines(t *imageType, customizations *blueprint.Cu
// create boot ISO with raw image
d := t.arch.distro
archName := t.arch.name
installerTreePipeline := simplifiedInstallerTreePipeline(repos, installerPackages, kernelVer, archName, d.product, d.osVersion, "edge")
installerTreePipeline := simplifiedInstallerTreePipeline(repos, installerPackages, kernelVer, archName, d.product, d.osVersion, "edge", customizations.GetFDO())
isolabel := fmt.Sprintf(d.isolabelTmpl, archName)
efibootTreePipeline := simplifiedInstallerEFIBootTreePipeline(installDevice, kernelVer, archName, d.vendor, d.product, d.osVersion, isolabel)
efibootTreePipeline := simplifiedInstallerEFIBootTreePipeline(installDevice, kernelVer, archName, d.vendor, d.product, d.osVersion, isolabel, customizations.GetFDO())
bootISOTreePipeline := simplifiedInstallerBootISOTreePipeline(imgPipelineName, kernelVer)
pipelines = append(pipelines, *installerTreePipeline, *efibootTreePipeline, *bootISOTreePipeline)
@ -774,22 +774,30 @@ func simplifiedInstallerBootISOTreePipeline(archivePipelineName, kver string) *o
return p
}
func simplifiedInstallerEFIBootTreePipeline(installDevice, kernelVer, arch, vendor, product, osVersion, isolabel string) *osbuild.Pipeline {
func simplifiedInstallerEFIBootTreePipeline(installDevice, kernelVer, arch, vendor, product, osVersion, isolabel string, fdo *blueprint.FDOCustomization) *osbuild.Pipeline {
p := new(osbuild.Pipeline)
p.Name = "efiboot-tree"
p.Build = "name:build"
p.AddStage(osbuild.NewGrubISOStage(grubISOStageOptions(installDevice, kernelVer, arch, vendor, product, osVersion, isolabel)))
p.AddStage(osbuild.NewGrubISOStage(grubISOStageOptions(installDevice, kernelVer, arch, vendor, product, osVersion, isolabel, fdo)))
return p
}
func simplifiedInstallerTreePipeline(repos []rpmmd.RepoConfig, packages []rpmmd.PackageSpec, kernelVer, arch, product, osVersion, variant string) *osbuild.Pipeline {
func simplifiedInstallerTreePipeline(repos []rpmmd.RepoConfig, packages []rpmmd.PackageSpec, kernelVer, arch, product, osVersion, variant string, fdo *blueprint.FDOCustomization) *osbuild.Pipeline {
p := new(osbuild.Pipeline)
p.Name = "coi-tree"
p.Build = "name:build"
p.AddStage(osbuild.NewRPMStage(rpmStageOptions(repos), osbuild.NewRpmStageSourceFilesInputs(packages)))
p.AddStage(osbuild.NewBuildstampStage(buildStampStageOptions(arch, product, osVersion, variant)))
p.AddStage(osbuild.NewLocaleStage(&osbuild.LocaleStageOptions{Language: "en_US.UTF-8"}))
p.AddStage(osbuild.NewDracutStage(dracutStageOptions(kernelVer, arch, []string{"coreos-installer"})))
dracutStageOptions := dracutStageOptions(kernelVer, arch, []string{
"coreos-installer",
"fdo",
})
if fdo.DiunPubKeyRootCerts != "" {
p.AddStage(osbuild.NewFDOStageForRootCerts(fdo.DiunPubKeyRootCerts))
dracutStageOptions.Install = []string{"/fdo_diun_pub_key_root_certs.pem"}
}
p.AddStage(osbuild.NewDracutStage(dracutStageOptions))
return p
}

View file

@ -303,7 +303,7 @@ func bootISOMonoStageOptions(kernelVer, arch, vendor, product, osVersion, isolab
}
}
func grubISOStageOptions(installDevice, kernelVer, arch, vendor, product, osVersion, isolabel string) *osbuild.GrubISOStageOptions {
func grubISOStageOptions(installDevice, kernelVer, arch, vendor, product, osVersion, isolabel string, fdo *blueprint.FDOCustomization) *osbuild.GrubISOStageOptions {
var architectures []string
if arch == "x86_64" {
@ -314,7 +314,7 @@ func grubISOStageOptions(installDevice, kernelVer, arch, vendor, product, osVers
panic("unsupported architecture")
}
return &osbuild.GrubISOStageOptions{
grubISOStageOptions := &osbuild.GrubISOStageOptions{
Product: osbuild.Product{
Name: product,
Version: osVersion,
@ -331,6 +331,19 @@ func grubISOStageOptions(installDevice, kernelVer, arch, vendor, product, osVers
Architectures: architectures,
Vendor: vendor,
}
grubISOStageOptions.Kernel.Opts = append(grubISOStageOptions.Kernel.Opts, "fdo.manufacturing_server_url="+fdo.ManufacturingServerURL)
if fdo.DiunPubKeyInsecure != "" {
grubISOStageOptions.Kernel.Opts = append(grubISOStageOptions.Kernel.Opts, "fdo.diun_pub_key_insecure="+fdo.DiunPubKeyInsecure)
}
if fdo.DiunPubKeyHash != "" {
grubISOStageOptions.Kernel.Opts = append(grubISOStageOptions.Kernel.Opts, "fdo.diun_pub_key_hash="+fdo.DiunPubKeyHash)
}
if fdo.DiunPubKeyRootCerts != "" {
grubISOStageOptions.Kernel.Opts = append(grubISOStageOptions.Kernel.Opts, "fdo.diun_pub_key_root_certs=/fdo_diun_root_certs.pem")
}
return grubISOStageOptions
}
func discinfoStageOptions(arch string) *osbuild.DiscinfoStageOptions {