diff --git a/mantle/cmd/kola/options.go b/mantle/cmd/kola/options.go index 96a756ad65..aea04742cd 100644 --- a/mantle/cmd/kola/options.go +++ b/mantle/cmd/kola/options.go @@ -252,7 +252,7 @@ func syncCosaOptions() error { } } - if kola.Options.IgnitionVersion == "" { + if kola.Options.IgnitionVersion == "" && kola.QEMUOptions.DiskImage == "" { if kola.CosaBuild != nil { kola.Options.IgnitionVersion = sdk.TargetIgnitionVersion(kola.CosaBuild) } diff --git a/mantle/cmd/kola/qemuexec.go b/mantle/cmd/kola/qemuexec.go index b89a520f01..c969effc47 100644 --- a/mantle/cmd/kola/qemuexec.go +++ b/mantle/cmd/kola/qemuexec.go @@ -17,13 +17,11 @@ package main import ( - "encoding/json" "fmt" "io/ioutil" - "os" - ignconverter "github.com/coreos/ign-converter" v3 "github.com/coreos/ignition/v2/config/v3_0" + v3types "github.com/coreos/ignition/v2/config/v3_0/types" "github.com/pkg/errors" "github.com/spf13/cobra" @@ -67,12 +65,7 @@ func init() { cmdQemuExec.Flags().BoolVarP(&forceConfigInjection, "inject-ignition", "", false, "Force injecting Ignition config using guestfs") } -func renderFragments() (string, error) { - buf, err := ioutil.ReadFile(ignition) - if err != nil { - return "", err - } - config, _, err := v3.Parse(buf) +func renderFragments(config v3types.Config) (*v3types.Config, error) { for _, fragtype := range ignitionFragments { switch fragtype { case "autologin": @@ -80,73 +73,34 @@ func renderFragments() (string, error) { config = newconf break default: - return "", fmt.Errorf("Unknown fragment: %s", fragtype) + return nil, fmt.Errorf("Unknown fragment: %s", fragtype) } } + return &config, nil +} - newbuf, err := json.Marshal(config) +func runQemuExec(cmd *cobra.Command, args []string) error { + var err error + buf, err := ioutil.ReadFile(ignition) if err != nil { - return "", err + return err } - tmpf, err := ioutil.TempFile("", "qemuexec-ign") + config, _, err := v3.Parse(buf) if err != nil { - return "", err + return errors.Wrapf(err, "parsing %s", ignition) } - if _, err := tmpf.Write(newbuf); err != nil { - return "", err - } - - return tmpf.Name(), nil -} - -func runQemuExec(cmd *cobra.Command, args []string) error { - var err error - cleanupIgnition := false if len(ignitionFragments) > 0 { - newconfig, err := renderFragments() + newconfig, err := renderFragments(config) if err != nil { return errors.Wrapf(err, "rendering fragments") } - ignition = newconfig - cleanupIgnition = true + config = *newconfig } - if kola.Options.IgnitionVersion == "v2" { - buf, err := ioutil.ReadFile(ignition) - if err != nil { - return err - } - config, _, err := v3.Parse(buf) - if err != nil { - return errors.Wrapf(err, "parsing %s", ignition) - } - ignc2, err := ignconverter.Translate3to2(config) - if err != nil { - return err - } - ignc2buf, err := json.Marshal(ignc2) - if err != nil { - return err - } - tmpf, err := ioutil.TempFile("", "qemuexec-ign-conv") - if err != nil { - return err - } - if _, err := tmpf.Write(ignc2buf); err != nil { - return err - } - if cleanupIgnition { - os.Remove(ignition) - } - cleanupIgnition = true - ignition = tmpf.Name() + builder, err := platform.NewBuilderFromParsed(config, kola.Options.IgnitionVersion == "v2") + if err != nil { + return errors.Wrapf(err, "creating qemu builder") } - defer func() { - if cleanupIgnition { - os.Remove(ignition) - } - }() - - builder := platform.NewBuilder(ignition, forceConfigInjection) + builder.ForceConfigInjection = forceConfigInjection if len(knetargs) > 0 { builder.IgnitionNetworkKargs = knetargs } diff --git a/mantle/platform/qemu.go b/mantle/platform/qemu.go index 07fea01f36..a846772cb1 100644 --- a/mantle/platform/qemu.go +++ b/mantle/platform/qemu.go @@ -15,6 +15,7 @@ package platform import ( + "encoding/json" "fmt" "io" "io/ioutil" @@ -25,6 +26,8 @@ import ( "strings" "syscall" + ignconverter "github.com/coreos/ign-converter" + v3types "github.com/coreos/ignition/v2/config/v3_0/types" "github.com/coreos/mantle/system" "github.com/coreos/mantle/system/exec" "github.com/coreos/mantle/util" @@ -45,6 +48,7 @@ type Disk struct { type QemuInstance struct { qemu exec.Cmd + tmpConfig string swtpmTmpd string swtpm exec.Cmd } @@ -116,6 +120,9 @@ func (inst *QemuInstance) Wait() error { } func (inst *QemuInstance) Destroy() { + if inst.tmpConfig != "" { + os.Remove(inst.tmpConfig) + } if inst.qemu != nil { if err := inst.qemu.Kill(); err != nil { plog.Errorf("Error killing qemu instance %v: %v", inst.Pid(), err) @@ -161,6 +168,9 @@ type QemuBuilder struct { primaryDiskAdded bool + // cleanupConfig is true if we own the Ignition config + cleanupConfig bool + finalized bool diskId uint fds []*os.File @@ -178,6 +188,37 @@ func NewBuilder(config string, forceIgnInjection bool) *QemuBuilder { return &ret } +func NewBuilderFromParsed(config v3types.Config, convSpec2 bool) (*QemuBuilder, error) { + var configBuf []byte + var err error + if convSpec2 { + ignc2, err := ignconverter.Translate3to2(config) + if err != nil { + return nil, err + } + configBuf, err = json.Marshal(ignc2) + if err != nil { + return nil, err + } + } else { + configBuf, err = json.Marshal(config) + if err != nil { + return nil, err + } + } + tmpf, err := ioutil.TempFile("", "mantle-qemu-ign") + if err != nil { + return nil, err + } + if _, err := tmpf.Write(configBuf); err != nil { + return nil, err + } + + builder := NewBuilder(tmpf.Name(), false) + builder.cleanupConfig = true + return builder, nil +} + // AddFd appends a file descriptor that will be passed to qemu, // returning a "/dev/fdset/" argument that one can use with e.g. // -drive file=/dev/fdset/. @@ -718,6 +759,10 @@ func (builder *QemuBuilder) Exec() (*QemuInstance, error) { cmd.Stderr = os.Stderr } + if builder.cleanupConfig { + inst.tmpConfig = builder.Config + } + if err = inst.qemu.Start(); err != nil { return nil, err } diff --git a/src/cmd-run b/src/cmd-run index 1e2c9092b7..51627ecc16 100755 --- a/src/cmd-run +++ b/src/cmd-run @@ -125,11 +125,6 @@ fi vmdiskdir=$(dirname "${VM_DISK}") VM_DISK=$(realpath "${vmdiskdir}")/$(basename "${VM_DISK}") -# For future me: if you are in here wondering where this value is ultimately -# derived from, it exists in mantle/sdk/ignversion.go via `TargetIgnitionVersionFromName()` -ignition_version=$(disk_ignition_version "${VM_DISK}") -ign_validate="ignition-validate" - # Set name to coreos to be shorter, and default CPUs to host set -- -name coreos -smp "${VM_NCPUS}" "$@" @@ -230,12 +225,6 @@ cat > "${f}" < "${spec2f}" - mv "${spec2f}" "${f}" -fi # We're using fd 9 to avoid clashing with kola's internal qemu fd mappings; # this is a bug. @@ -243,11 +232,6 @@ exec 9<>"${f}" rm -f "${f}" IGNITION_CONFIG_FILE=/proc/self/fd/9 -if ! ${ign_validate} "${IGNITION_CONFIG_FILE}"; then - jq . < "${IGNITION_CONFIG_FILE}" - exit 1 -fi - case "${DISK_CHANNEL}" in virtio) ;; nvme) kola_args+=('--qemu-nvme');;