diff --git a/go.mod b/go.mod index d81b62a..ee9983a 100644 --- a/go.mod +++ b/go.mod @@ -4,13 +4,13 @@ go 1.23.0 require ( github.com/BurntSushi/toml v1.3.2 + github.com/adrg/xdg v0.5.3 github.com/creack/pty/v2 v2.0.1 github.com/docker/docker v27.5.0+incompatible github.com/go-quicktest/qt v1.101.0 github.com/google/go-containerregistry v0.20.3 github.com/kballard/go-shellquote v0.0.0-20180428030007-95032a82bc51 github.com/schollz/progressbar/v3 v3.18.0 - github.com/u-root/u-root v0.11.0 golang.org/x/sync v0.10.0 golang.org/x/sys v0.29.0 rsc.io/script v0.0.2-0.20231205190631-334f6c18cff3 @@ -18,15 +18,12 @@ require ( require ( github.com/AdaLogics/go-fuzz-headers v0.0.0-20240806141605-e8a1dd7889d6 // indirect - github.com/adrg/xdg v0.5.3 // indirect github.com/containerd/log v0.1.0 // indirect github.com/containerd/stargz-snapshotter/estargz v0.16.3 // indirect github.com/docker/cli v27.5.0+incompatible // indirect github.com/docker/distribution v2.8.3+incompatible // indirect github.com/docker/docker-credential-helpers v0.8.2 // indirect github.com/google/go-cmp v0.6.0 // indirect - github.com/google/goexpect v0.0.0-20191001010744-5b6988669ffa // indirect - github.com/google/goterm v0.0.0-20200907032337-555d40f16ae2 // indirect github.com/klauspost/compress v1.17.11 // indirect github.com/kr/pretty v0.3.1 // indirect github.com/kr/text v0.2.0 // indirect @@ -44,10 +41,7 @@ require ( github.com/sirupsen/logrus v1.9.3 // indirect github.com/stretchr/testify v1.10.0 // indirect github.com/vbatts/tar-split v0.11.6 // indirect - golang.org/x/crypto v0.0.0-20210921155107-089bfa567519 // indirect golang.org/x/term v0.28.0 // indirect golang.org/x/tools v0.29.0 // indirect - google.golang.org/genproto/googleapis/rpc v0.0.0-20250102185135-69823020774d // indirect - google.golang.org/grpc v1.69.4 // indirect gotest.tools/v3 v3.5.1 // indirect ) diff --git a/go.sum b/go.sum index a95ff02..011e19e 100644 --- a/go.sum +++ b/go.sum @@ -26,16 +26,10 @@ github.com/docker/docker-credential-helpers v0.8.2 h1:bX3YxiGzFP5sOXWc3bTPEXdEaZ github.com/docker/docker-credential-helpers v0.8.2/go.mod h1:P3ci7E3lwkZg6XiHdRKft1KckHiO9a2rNtyFbZ/ry9M= github.com/go-quicktest/qt v1.101.0 h1:O1K29Txy5P2OK0dGo59b7b0LR6wKfIhttaAhHUyn7eI= github.com/go-quicktest/qt v1.101.0/go.mod h1:14Bz/f7NwaXPtdYEgzsx46kqSxVwTbzVZsDC26tQJow= -github.com/golang/glog v1.2.2 h1:1+mZ9upx1Dh6FmUTFR1naJ77miKiXgALjWOZ3NVFPmY= -github.com/golang/glog v1.2.2/go.mod h1:6AhwSGph0fcJtXVM/PEHPqZlFeoLxhs7/t5UDAwmO+w= github.com/google/go-cmp v0.6.0 h1:ofyhxvXcZhMsU5ulbFiLKl/XBFqE1GSq7atu8tAmTRI= github.com/google/go-cmp v0.6.0/go.mod h1:17dUlkBOakJ0+DkrSSNjCkIjxS6bF9zb3elmeNGIjoY= github.com/google/go-containerregistry v0.20.3 h1:oNx7IdTI936V8CQRveCjaxOiegWwvM7kqkbXTpyiovI= github.com/google/go-containerregistry v0.20.3/go.mod h1:w00pIgBRDVUDFM6bq+Qx8lwNWK+cxgCuX1vd3PIBDNI= -github.com/google/goexpect v0.0.0-20191001010744-5b6988669ffa h1:PMkmJA8ju9DjqAJjIzrBdrmhuuPsoNnNLYgKQBopWL0= -github.com/google/goexpect v0.0.0-20191001010744-5b6988669ffa/go.mod h1:qtE5aAEkt0vOSA84DBh8aJsz6riL8ONfqfULY7lBjqc= -github.com/google/goterm v0.0.0-20200907032337-555d40f16ae2 h1:CVuJwN34x4xM2aT4sIKhmeib40NeBPhRihNjQmpJsA4= -github.com/google/goterm v0.0.0-20200907032337-555d40f16ae2/go.mod h1:nOFQdrUlIlx6M6ODdSpBj1NVA+VgLC6kmw60mkw34H4= github.com/kballard/go-shellquote v0.0.0-20180428030007-95032a82bc51 h1:Z9n2FFNUXsshfwJMBgNA0RU6/i7WVaAegv3PtuIHPMs= github.com/kballard/go-shellquote v0.0.0-20180428030007-95032a82bc51/go.mod h1:CzGEWj7cYgsdH8dAjBGEr58BoE7ScuLd+fwFZ44+/x8= github.com/klauspost/compress v1.17.11 h1:In6xLpyWOi1+C7tXUUWv2ot1QvBjxevKAaI6IXrJmUc= @@ -80,12 +74,8 @@ github.com/stretchr/objx v0.1.0/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+ github.com/stretchr/testify v1.7.0/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/h/Wwjteg= github.com/stretchr/testify v1.10.0 h1:Xv5erBjTwe/5IxqUQTdXv5kgmIvbHo3QQyRwhJsOfJA= github.com/stretchr/testify v1.10.0/go.mod h1:r2ic/lqez/lEtzL7wO/rwa5dbSLXVDPFyf8C91i36aY= -github.com/u-root/u-root v0.11.0 h1:6gCZLOeRyevw7gbTwMj3fKxnr9+yHFlgF3N7udUVNO8= -github.com/u-root/u-root v0.11.0/go.mod h1:DBkDtiZyONk9hzVEdB/PWI9B4TxDkElWlVTHseglrZY= github.com/vbatts/tar-split v0.11.6 h1:4SjTW5+PU11n6fZenf2IPoV8/tz3AaYHMWjf23envGs= github.com/vbatts/tar-split v0.11.6/go.mod h1:dqKNtesIOr2j2Qv3W/cHjnvk9I8+G7oAkFDFN6TCBEI= -golang.org/x/crypto v0.0.0-20210921155107-089bfa567519 h1:7I4JAnoQBe7ZtJcBaYHi5UtiO8tQHbUSXxL+pnGRANg= -golang.org/x/crypto v0.0.0-20210921155107-089bfa567519/go.mod h1:GvvjBRRGRdwPK5ydBHafDWAxML/pGHZbMvKqRZ5+Abc= golang.org/x/sync v0.10.0 h1:3NQrjDixjgGwUOCaF8w2+VYHv0Ve/vGYSbdkTa98gmQ= golang.org/x/sync v0.10.0/go.mod h1:Czt+wKu1gCyEFDUtn0jG5QVvpJ6rzVqr5aXyt9drQfk= golang.org/x/sys v0.0.0-20220715151400-c0bba94af5f8/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= @@ -95,12 +85,6 @@ golang.org/x/term v0.28.0 h1:/Ts8HFuMR2E6IP/jlo7QVLZHggjKQbhu/7H0LJFr3Gg= golang.org/x/term v0.28.0/go.mod h1:Sw/lC2IAUZ92udQNf3WodGtn4k/XoLyZoh8v/8uiwek= golang.org/x/tools v0.29.0 h1:Xx0h3TtM9rzQpQuR4dKLrdglAmCEN5Oi+P74JdhdzXE= golang.org/x/tools v0.29.0/go.mod h1:KMQVMRsVxU6nHCFXrBPhDB8XncLNLM0lIy/F14RP588= -google.golang.org/genproto/googleapis/rpc v0.0.0-20250102185135-69823020774d h1:xJJRGY7TJcvIlpSrN3K6LAWgNFUILlO+OMAqtg9aqnw= -google.golang.org/genproto/googleapis/rpc v0.0.0-20250102185135-69823020774d/go.mod h1:3ENsm/5D1mzDyhpzeRi1NR784I0BcofWBoSc5QqqMK4= -google.golang.org/grpc v1.69.4 h1:MF5TftSMkd8GLw/m0KM6V8CMOCY6NZ1NQDPGFgbTt4A= -google.golang.org/grpc v1.69.4/go.mod h1:vyjdE6jLBI76dgpDojsFGNaHlxdjXN9ghpnd2o7JGZ4= -google.golang.org/protobuf v1.36.3 h1:82DV7MYdb8anAVi3qge1wSnMDrnKK7ebr+I0hHRN1BU= -google.golang.org/protobuf v1.36.3/go.mod h1:9fA7Ob0pmnwhb644+1+CVWFRbNajQ6iRojtC/QF5bRE= gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0= gopkg.in/yaml.v3 v3.0.0-20200313102051-9f266ea9e77c/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM= gopkg.in/yaml.v3 v3.0.1 h1:fxVm/GzAzEWqLHuvctI91KS9hhNmmWOoWu0XTYJS7CA= diff --git a/qemu.go b/qemu.go index 2876eac..32f4325 100644 --- a/qemu.go +++ b/qemu.go @@ -18,7 +18,6 @@ import ( "strings" "time" - "github.com/u-root/u-root/pkg/qemu" "golang.org/x/sync/errgroup" "golang.org/x/sys/unix" ) @@ -128,16 +127,17 @@ func (cmd *command) Start(ctx context.Context) (err error) { // subprocesses with this port as stdin, stdout and stderr. virtioPorts.Chardevs[chardev("stdio")] = stdioPortName - devices := []qemu.Device{ - qemu.ArbitraryArgs{ + devices := []device{ + arbitraryArgs{ "-nodefaults", + "-nographic", "-display", "none", "-cpu", "max", "-chardev", "stdio,id=stdio", "-m", cmd.Memory, "-smp", cmd.SMP, }, - qemu.VirtioRandom{}, + virtioRandom{}, readOnlyRootfs{}, exitOnPanic{}, disablePS2Probing{}, @@ -161,7 +161,7 @@ func (cmd *command) Start(ctx context.Context) (err error) { } if !disableKVM { - devices = append(devices, qemu.ArbitraryArgs{"-enable-kvm"}) + devices = append(devices, arbitraryArgs{"-enable-kvm"}) } else if cmd.Stderr != nil { fmt.Fprintln(cmd.Stderr, "Warning: KVM disabled, performance will be limited.") } @@ -175,7 +175,7 @@ func (cmd *command) Start(ctx context.Context) (err error) { case "arm64": binary = "qemu-system-aarch64" devices = append(devices, - qemu.ArbitraryArgs{"-machine", "virt,gic-version=max"}, + arbitraryArgs{"-machine", "virt,gic-version=max"}, earlycon{}, ) @@ -275,22 +275,6 @@ func (cmd *command) Start(ctx context.Context) (err error) { []string{stdioPortName, controlPortName}, }) - qemuPath, err := exec.LookPath(binary) - if err != nil { - return err - } - - qemuOpts := qemu.Options{ - QEMUPath: qemuPath, - Kernel: cmd.Kernel, - Devices: devices, - } - - qemuArgs, err := qemuOpts.Cmdline() - if err != nil { - return err - } - stdinIsDevZero := false if f, ok := cmd.Stdin.(*os.File); ok { stdinIsDevZero, err = fileIsDevZero(f) @@ -314,7 +298,7 @@ func (cmd *command) Start(ctx context.Context) (err error) { cmd.fakeStdin = fakeStdinHost } - proc := commandWithGracefulTermination(ctx, qemuArgs[0], qemuArgs[1:]...) + proc := commandWithGracefulTermination(ctx, binary, qemuCmdline(cmd.Kernel, devices)...) proc.Stdin = stdin proc.Stdout = cmd.Stdout proc.Stderr = cmd.Stderr @@ -421,6 +405,32 @@ func (gge *genericGuestError) Error() string { return fmt.Sprintf("guest: %s", gge.Message) } +type device interface { + Cmdline() []string + KArgs() []string +} + +func qemuCmdline(kernel string, devices []device) []string { + var args []string + + args = append(args, + "-nographic", + "-kernel", kernel, + ) + + var kargs []string + for _, dev := range devices { + args = append(args, dev.Cmdline()...) + kargs = append(kargs, dev.KArgs()...) + } + + if len(kargs) > 0 { + args = append(args, "-append", strings.Join(kargs, " ")) + } + + return args +} + type initWithArgs struct { path string args []string @@ -709,3 +719,26 @@ func (p9sd *p9SharedDirectory) Cmdline() []string { func (*p9SharedDirectory) KArgs() []string { return nil } + +// virtioRandom and arbitraryArgs were copied from u-root, available under BSD-3-Clause. +// Copyright (c) 2012-2019, u-root Authors + +// virtioRandom is a Device that exposes a PCI random number generator to the +// QEMU VM. +type virtioRandom struct{} + +func (virtioRandom) Cmdline() []string { + return []string{"-device", "virtio-rng-pci"} +} + +func (virtioRandom) KArgs() []string { return nil } + +// arbitraryArgs is a Device that allows users to add arbitrary arguments to +// the QEMU command line. +type arbitraryArgs []string + +func (aa arbitraryArgs) Cmdline() []string { + return aa +} + +func (arbitraryArgs) KArgs() []string { return nil }