diff --git a/mantle/cmd/kola/qemuexec.go b/mantle/cmd/kola/qemuexec.go index bf48552a46..3f151107b9 100644 --- a/mantle/cmd/kola/qemuexec.go +++ b/mantle/cmd/kola/qemuexec.go @@ -61,6 +61,8 @@ var ( devshell bool devshellConsole bool + + consoleFile string ) func init() { @@ -81,6 +83,7 @@ func init() { cmdQemuExec.Flags().StringArrayVar(&bindrw, "bind-rw", nil, "Same as above, but writable") cmdQemuExec.Flags().BoolVarP(&forceConfigInjection, "inject-ignition", "", false, "Force injecting Ignition config using guestfs") cmdQemuExec.Flags().BoolVar(&propagateInitramfsFailure, "propagate-initramfs-failure", false, "Error out if the system fails in the initramfs") + cmdQemuExec.Flags().StringVarP(&consoleFile, "console-to-file", "", "", "Filepath in which to save serial console logs") } @@ -114,6 +117,10 @@ func runQemuExec(cmd *cobra.Command, args []string) error { if devshellConsole { devshell = true + + if consoleFile != "" { + return fmt.Errorf("Cannot use console devshell and --console-to-file") + } } if devshell { if directIgnition { @@ -244,6 +251,7 @@ func runQemuExec(cmd *cobra.Command, args []string) error { builder.EnableUsermodeNetworking(h) } builder.InheritConsole = true + builder.ConsoleFile = consoleFile builder.Append(args...) if devshell && !devshellConsole { diff --git a/mantle/cmd/kola/testiso.go b/mantle/cmd/kola/testiso.go index dd62d57c30..d5eda68aa3 100644 --- a/mantle/cmd/kola/testiso.go +++ b/mantle/cmd/kola/testiso.go @@ -185,7 +185,7 @@ func newQemuBuilder(outdir string) (*platform.QemuBuilder, *conf.Conf, error) { } if !builder.InheritConsole { - builder.ConsoleToFile(filepath.Join(outdir, "console.txt")) + builder.ConsoleFile = filepath.Join(outdir, "console.txt") } config, err := conf.EmptyIgnition().Render(kola.IsIgnitionV2()) if err != nil { diff --git a/mantle/platform/machine/qemuiso/cluster.go b/mantle/platform/machine/qemuiso/cluster.go index 94ec8860b5..9389473873 100644 --- a/mantle/platform/machine/qemuiso/cluster.go +++ b/mantle/platform/machine/qemuiso/cluster.go @@ -102,7 +102,7 @@ func (qc *Cluster) NewMachineWithQemuOptions(userdata *conf.UserData, options pl builder.Firmware = qc.flight.opts.Firmware } builder.Hostname = fmt.Sprintf("qemu%d", qc.BaseCluster.AllocateMachineSerial()) - builder.ConsoleToFile(qm.consolePath) + builder.ConsoleFile = qm.consolePath if qc.flight.opts.Memory != "" { memory, err := strconv.ParseInt(qc.flight.opts.Memory, 10, 32) diff --git a/mantle/platform/machine/unprivqemu/cluster.go b/mantle/platform/machine/unprivqemu/cluster.go index 723a36ae0a..40beeaa3b7 100644 --- a/mantle/platform/machine/unprivqemu/cluster.go +++ b/mantle/platform/machine/unprivqemu/cluster.go @@ -104,7 +104,7 @@ func (qc *Cluster) NewMachineWithQemuOptions(userdata *conf.UserData, options pl builder.Firmware = qc.flight.opts.Firmware builder.Swtpm = qc.flight.opts.Swtpm builder.Hostname = fmt.Sprintf("qemu%d", qc.BaseCluster.AllocateMachineSerial()) - builder.ConsoleToFile(qm.consolePath) + builder.ConsoleFile = qm.consolePath if qc.flight.opts.Memory != "" { memory, err := strconv.ParseInt(qc.flight.opts.Memory, 10, 32) diff --git a/mantle/platform/qemu.go b/mantle/platform/qemu.go index 31ed7354f6..354a7b8110 100644 --- a/mantle/platform/qemu.go +++ b/mantle/platform/qemu.go @@ -303,6 +303,9 @@ type QemuBuilder struct { ForceConfigInjection bool configInjected bool + // File to which to redirect the serial console + ConsoleFile string + // Memory defaults to 1024 on most architectures, others it may be 2048 Memory int // Processors < 0 means to use host count, unset means 1, values > 1 are directly used @@ -436,11 +439,6 @@ func virtio(device, args string) string { return fmt.Sprintf("virtio-%s-%s,%s", device, suffix, args) } -// ConsoleToFile configures the instance to have a serial console, logging to `path`. -func (builder *QemuBuilder) ConsoleToFile(path string) { - builder.Append("-display", "none", "-chardev", "file,id=log,path="+path, "-serial", "chardev:log") -} - // EnableUsermodeNetworking configure forwarding for all requested ports, // via usermode network helpers. func (builder *QemuBuilder) EnableUsermodeNetworking(h []HostForwardPort) { @@ -1307,6 +1305,12 @@ func (builder *QemuBuilder) Exec() (*QemuInstance, error) { fdnum++ } + if builder.ConsoleFile != "" { + builder.Append("-display", "none", "-chardev", "file,id=log,path="+builder.ConsoleFile, "-serial", "chardev:log") + } else { + builder.Append("-serial", "mon:stdio") + } + // And the custom arguments argv = append(argv, builder.Argv...) diff --git a/src/cmdlib.sh b/src/cmdlib.sh index c264f9c3d6..c73eefcb38 100755 --- a/src/cmdlib.sh +++ b/src/cmdlib.sh @@ -500,7 +500,8 @@ EOF echo "$@" > "${tmp_builddir}"/cmd.sh touch "${runvm_console}" - kola_args=(kola qemuexec -m 2048 --auto-cpus -U --workdir none) + kola_args=(kola qemuexec -m 2048 --auto-cpus -U --workdir none \ + --console-to-file "${runvm_console}") base_qemu_args=(-drive 'if=none,id=root,format=raw,snapshot=on,file='"${vmbuilddir}"'/root,index=1' \ -device 'virtio-blk,drive=root' -kernel "${vmbuilddir}/kernel" -initrd "${vmbuilddir}/initrd" \ @@ -518,7 +519,6 @@ EOF if [ -z "${RUNVM_SHELL:-}" ]; then if ! "${kola_args[@]}" -- "${base_qemu_args[@]}" \ - -serial file:"${runvm_console}" \ -device virtserialport,chardev=virtioserial0,name=cosa-cmdout \ -chardev stdio,id=virtioserial0 \ "${qemu_args[@]}" <&-; then # the <&- here closes stdin otherwise qemu waits forever