Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Import UEFI Code file if specified in machine yaml #26

Merged
merged 2 commits into from
Sep 6, 2023
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
24 changes: 19 additions & 5 deletions cmd/machine/cmd/init.go
Original file line number Diff line number Diff line change
@@ -1,10 +1,9 @@
/*

Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at

http://www.apache.org/licenses/LICENSE-2.0
http://www.apache.org/licenses/LICENSE-2.0

Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
Expand Down Expand Up @@ -86,7 +85,7 @@ var machineTypes = map[string]string{

func getMachineTypes() []string {
var mTypes []string
for key, _ := range machineTypes {
for key := range machineTypes {
mTypes = append(mTypes, key)
}
sort.Strings(mTypes)
Expand Down Expand Up @@ -175,7 +174,7 @@ func DoCreateMachine(machineName, machineType, fileName string, editFile bool) e
return fmt.Errorf("Error calling editor: %s", err)
}
}
log.Debug("Got config:\n%s", string(machineBytes))
log.Debugf("Got config:\n%s", string(machineBytes))

for {
if err = yaml.Unmarshal(machineBytes, &newMachine); err == nil {
Expand All @@ -196,7 +195,9 @@ func DoCreateMachine(machineName, machineType, fileName string, editFile bool) e
}
}

checkMachineFilePaths(&newMachine)
if err := checkMachineFilePaths(&newMachine); err != nil {
return fmt.Errorf("Error while checking machine fiel paths: %s", err)
}

// persist config if not ephemeral
err = postMachine(newMachine)
Expand Down Expand Up @@ -265,6 +266,14 @@ func checkMachineFilePaths(newMachine *api.Machine) error {
log.Infof("Fully qualified uefi-vars path %s", newPath)
newMachine.Config.UEFIVars = newPath
}
if newMachine.Config.UEFICode != "" {
newPath, err := verifyPath(cwd, newMachine.Config.UEFICode)
if err != nil {
return fmt.Errorf("Failed to verify path to uefi-code: %q: %s", newMachine.Config.UEFICode, err)
}
log.Infof("Fully qualified uefi-code path %s", newPath)
newMachine.Config.UEFICode = newPath
}
return nil
}

Expand Down Expand Up @@ -302,6 +311,10 @@ func doInitArgsValidate(cmd *cobra.Command, args []string) error {
cmd.SilenceUsage = true
return fmt.Errorf("Invalid machine-type '%s', must be one of: %s", mType, strings.Join(mTypes, ", "))
}
debug, _ := cmd.Flags().GetBool("debug")
if debug {
log.SetLevel(log.DebugLevel)
}
return nil
}

Expand All @@ -310,5 +323,6 @@ func init() {
rootCmd.AddCommand(initCmd)
initCmd.PersistentFlags().StringP("file", "f", "", "yaml file to import. If unspecified, use stdin")
initCmd.PersistentFlags().BoolP("edit", "e", false, "edit the yaml file inline")
initCmd.PersistentFlags().BoolP("debug", "D", false, "enable debug logging")
initCmd.PersistentFlags().StringP("machine-type", "m", defaultMachineType, fmt.Sprintf("specify the machine type, one of [%s]", strings.Join(mTypes, ", ")))
}
57 changes: 39 additions & 18 deletions pkg/api/qconfig.go
Original file line number Diff line number Diff line change
Expand Up @@ -2,14 +2,15 @@ package api

import (
"fmt"
"github.com/project-machine/qcli"
"os"
"path"
"path/filepath"
"runtime"
"strconv"
"strings"

"github.com/project-machine/qcli"

log "github.com/sirupsen/logrus"
)

Expand Down Expand Up @@ -66,7 +67,7 @@ func NewDefaultX86Config(name string, numCpus, numMemMB uint32, sockDir string)
SMP: smp,
Memory: mem,
RngDevices: []qcli.RngDevice{
qcli.RngDevice{
{
Driver: qcli.VirtioRng,
ID: "rng0",
Bus: "pcie.0",
Expand All @@ -75,39 +76,39 @@ func NewDefaultX86Config(name string, numCpus, numMemMB uint32, sockDir string)
},
},
CharDevices: []qcli.CharDevice{
qcli.CharDevice{
{
Driver: qcli.LegacySerial,
Backend: qcli.Socket,
ID: "serial0",
Path: filepath.Join(sockDir, "console.sock"),
},
qcli.CharDevice{
{
Driver: qcli.LegacySerial,
Backend: qcli.Socket,
ID: "monitor0",
Path: filepath.Join(sockDir, "monitor.sock"),
},
},
LegacySerialDevices: []qcli.LegacySerialDevice{
qcli.LegacySerialDevice{
{
ChardevID: "serial0",
},
},
MonitorDevices: []qcli.MonitorDevice{
qcli.MonitorDevice{
{
ChardevID: "monitor0",
},
},
QMPSockets: []qcli.QMPSocket{
qcli.QMPSocket{
{
Type: "unix",
Server: true,
NoWait: true,
Name: filepath.Join(sockDir, "qmp.sock"),
},
},
PCIeRootPortDevices: []qcli.PCIeRootPortDevice{
qcli.PCIeRootPortDevice{
{
ID: "root-port.0x4.0",
Bus: "pcie.0",
Chassis: "0x0",
Expand All @@ -116,7 +117,7 @@ func NewDefaultX86Config(name string, numCpus, numMemMB uint32, sockDir string)
Addr: "0x5",
Multifunction: true,
},
qcli.PCIeRootPortDevice{
{
ID: "root-port.0x4.1",
Bus: "pcie.0",
Chassis: "0x1",
Expand Down Expand Up @@ -171,34 +172,34 @@ func NewDefaultAarch64Config(name string, numCpus uint32, numMemMB uint32, sockD
CPUModel: "host",
Memory: mem,
CharDevices: []qcli.CharDevice{
qcli.CharDevice{
{
Driver: qcli.PCISerialDevice,
Backend: qcli.Socket,
ID: "serial0",
Path: "/tmp/console.sock",
},
qcli.CharDevice{
{
Driver: qcli.LegacySerial,
Backend: qcli.Socket,
ID: "monitor0",
Path: filepath.Join(sockDir, "monitor.sock"),
},
},
SerialDevices: []qcli.SerialDevice{
qcli.SerialDevice{
{
Driver: qcli.PCISerialDevice,
ID: "pciser0",
ChardevIDs: []string{"serial0"},
MaxPorts: 1,
},
},
MonitorDevices: []qcli.MonitorDevice{
qcli.MonitorDevice{
{
ChardevID: "monitor0",
},
},
QMPSockets: []qcli.QMPSocket{
qcli.QMPSocket{
{
Type: "unix",
Server: true,
NoWait: true,
Expand Down Expand Up @@ -363,21 +364,41 @@ func (nd NicDef) QNetDevice(qti *qcli.QemuTypeIndex) (qcli.NetDevice, error) {
return ndev, nil
}

func ConfigureUEFIVars(c *qcli.Config, srcVars, runDir string, secureBoot bool) error {
func ConfigureUEFIVars(c *qcli.Config, srcCode, srcVars, runDir string, secureBoot bool) error {
uefiDev, err := qcli.NewSystemUEFIFirmwareDevice(secureBoot)
if err != nil {
return fmt.Errorf("failed to create a UEFI Firmware Device: %s", err)
}
src := uefiDev.Vars
// Import source UEFI Code (if provided)
src := uefiDev.Code
if len(srcCode) > 0 {
src = srcCode
}
// FIXME: create a qcli.UEFICodeFileName
dest := filepath.Join(runDir, "uefi-code.fd")
log.Infof("Importing UEFI Code from '%s' to '%q'", src, dest)
if err := CopyFileBits(src, dest); err != nil {
return fmt.Errorf("Failed to import UEFI Code from '%s' to '%q': %s", src, dest, err)
}
uefiDev.Code = dest

// Import source UEFI Vxrs (if provided)
src = uefiDev.Vars
if len(srcVars) > 0 {
src = srcVars
}
dest := filepath.Join(runDir, qcli.UEFIVarsFileName)
dest = filepath.Join(runDir, qcli.UEFIVarsFileName)
log.Infof("Importing UEFI Vars from '%s' to '%q'", src, dest)
// FIXME: should we skip re-import of srcVars, the imported Vars may have
// had changes that a new import would clobber, warning for now
if PathExists(dest) {
log.Warnf("Already imported UEFI Vars file %q to %q, overwriting...", src, dest)
}
if err := CopyFileBits(src, dest); err != nil {
return fmt.Errorf("Failed to import UEFI Vars from '%s' to '%q': %s", src, dest, err)
}
uefiDev.Vars = dest

c.UEFIFirmwareDevices = []qcli.UEFIFirmwareDevice{*uefiDev}
return nil
}
Expand All @@ -396,7 +417,7 @@ func GenerateQConfig(runDir, sockDir string, v VMDef) (*qcli.Config, error) {
return c, err
}

err = ConfigureUEFIVars(c, v.UEFIVars, runDir, v.SecureBoot)
err = ConfigureUEFIVars(c, v.UEFICode, v.UEFIVars, runDir, v.SecureBoot)
if err != nil {
return c, fmt.Errorf("Error configuring UEFI Vars: %s", err)
}
Expand Down
5 changes: 2 additions & 3 deletions pkg/api/vm.go
Original file line number Diff line number Diff line change
@@ -1,11 +1,9 @@
/*


Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at

http://www.apache.org/licenses/LICENSE-2.0
http://www.apache.org/licenses/LICENSE-2.0

Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
Expand Down Expand Up @@ -67,6 +65,7 @@ type VMDef struct {
Disks []QemuDisk `yaml:"disks"`
Boot string `yaml:"boot"`
Cdrom string `yaml:"cdrom"`
UEFICode string `yaml:"uefi-code"`
UEFIVars string `yaml:"uefi-vars"`
TPM bool `yaml:"tpm"`
TPMVersion string `yaml:"tpm-version"`
Expand Down