mirror of
https://github.com/containers/podman.git
synced 2025-06-20 17:13:43 +08:00
machine: USB passthrough
Sets up USB passthrough for machine. Additionally moves `SetOptions` out from `pkg/machine/config.go` to its own file in `pkg/machine/define/setopts.go`. [NO NEW TESTS NEEDED] Signed-off-by: Jake Correnti <jakecorrenti+github@proton.me>
This commit is contained in:
@ -9,6 +9,7 @@ import (
|
||||
"github.com/containers/common/pkg/strongunits"
|
||||
"github.com/containers/podman/v5/cmd/podman/registry"
|
||||
"github.com/containers/podman/v5/pkg/machine"
|
||||
"github.com/containers/podman/v5/pkg/machine/define"
|
||||
"github.com/containers/podman/v5/pkg/machine/vmconfigs"
|
||||
"github.com/spf13/cobra"
|
||||
)
|
||||
@ -28,7 +29,7 @@ var (
|
||||
|
||||
var (
|
||||
setFlags = SetFlags{}
|
||||
setOpts = machine.SetOptions{}
|
||||
setOpts = define.SetOptions{}
|
||||
)
|
||||
|
||||
type SetFlags struct {
|
||||
@ -90,9 +91,6 @@ func init() {
|
||||
func setMachine(cmd *cobra.Command, args []string) error {
|
||||
var (
|
||||
err error
|
||||
newCPUs, newMemory *uint64
|
||||
newDiskSize *strongunits.GiB
|
||||
newRootful *bool
|
||||
)
|
||||
|
||||
vmName := defaultMachineName
|
||||
@ -111,15 +109,15 @@ func setMachine(cmd *cobra.Command, args []string) error {
|
||||
}
|
||||
|
||||
if cmd.Flags().Changed("rootful") {
|
||||
newRootful = &setFlags.Rootful
|
||||
setOpts.Rootful = &setFlags.Rootful
|
||||
}
|
||||
if cmd.Flags().Changed("cpus") {
|
||||
mc.Resources.CPUs = setFlags.CPUs
|
||||
newCPUs = &mc.Resources.CPUs
|
||||
setOpts.CPUs = &mc.Resources.CPUs
|
||||
}
|
||||
if cmd.Flags().Changed("memory") {
|
||||
mc.Resources.Memory = setFlags.Memory
|
||||
newMemory = &mc.Resources.Memory
|
||||
setOpts.Memory = &mc.Resources.Memory
|
||||
}
|
||||
if cmd.Flags().Changed("disk-size") {
|
||||
if setFlags.DiskSize <= mc.Resources.DiskSize {
|
||||
@ -127,20 +125,19 @@ func setMachine(cmd *cobra.Command, args []string) error {
|
||||
}
|
||||
mc.Resources.DiskSize = setFlags.DiskSize
|
||||
newDiskSizeGB := strongunits.GiB(setFlags.DiskSize)
|
||||
newDiskSize = &newDiskSizeGB
|
||||
setOpts.DiskSize = &newDiskSizeGB
|
||||
}
|
||||
if cmd.Flags().Changed("user-mode-networking") {
|
||||
// TODO This needs help
|
||||
setOpts.UserModeNetworking = &setFlags.UserModeNetworking
|
||||
}
|
||||
if cmd.Flags().Changed("usb") {
|
||||
// TODO This needs help
|
||||
setOpts.USBs = &setFlags.USBs
|
||||
}
|
||||
|
||||
// At this point, we have the known changed information, etc
|
||||
// Walk through changes to the providers if they need them
|
||||
if err := provider.SetProviderAttrs(mc, newCPUs, newMemory, newDiskSize, newRootful); err != nil {
|
||||
if err := provider.SetProviderAttrs(mc, setOpts); err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
|
@ -79,19 +79,23 @@ func (a AppleHVStubber) RemoveAndCleanMachines(_ *define.MachineDirs) error {
|
||||
return nil
|
||||
}
|
||||
|
||||
func (a AppleHVStubber) SetProviderAttrs(mc *vmconfigs.MachineConfig, cpus, memory *uint64, newDiskSize *strongunits.GiB, newRootful *bool) error {
|
||||
if newDiskSize != nil {
|
||||
if err := resizeDisk(mc, *newDiskSize); err != nil {
|
||||
func (a AppleHVStubber) SetProviderAttrs(mc *vmconfigs.MachineConfig, opts define.SetOptions) error {
|
||||
if opts.DiskSize != nil {
|
||||
if err := resizeDisk(mc, *opts.DiskSize); err != nil {
|
||||
return err
|
||||
}
|
||||
}
|
||||
|
||||
if newRootful != nil && mc.HostUser.Rootful != *newRootful {
|
||||
if err := mc.SetRootful(*newRootful); err != nil {
|
||||
if opts.Rootful != nil && mc.HostUser.Rootful != *opts.Rootful {
|
||||
if err := mc.SetRootful(*opts.Rootful); err != nil {
|
||||
return err
|
||||
}
|
||||
}
|
||||
|
||||
if opts.USBs != nil {
|
||||
return fmt.Errorf("changing USBs not supported for applehv machines")
|
||||
}
|
||||
|
||||
// VFKit does not require saving memory, disk, or cpu
|
||||
return nil
|
||||
}
|
||||
|
@ -68,15 +68,6 @@ type ListResponse struct {
|
||||
UserModeNetworking bool
|
||||
}
|
||||
|
||||
type SetOptions struct {
|
||||
CPUs *uint64
|
||||
DiskSize *uint64
|
||||
Memory *uint64
|
||||
Rootful *bool
|
||||
UserModeNetworking *bool
|
||||
USBs *[]string
|
||||
}
|
||||
|
||||
type SSHOptions struct {
|
||||
Username string
|
||||
Args []string
|
||||
@ -101,7 +92,7 @@ type VM interface {
|
||||
Init(opts define.InitOptions) (bool, error)
|
||||
Inspect() (*InspectInfo, error)
|
||||
Remove(name string, opts RemoveOptions) (string, func() error, error)
|
||||
Set(name string, opts SetOptions) ([]error, error)
|
||||
Set(name string, opts define.SetOptions) ([]error, error)
|
||||
SSH(name string, opts SSHOptions) error
|
||||
Start(name string, opts StartOptions) error
|
||||
State(bypass bool) (define.Status, error)
|
||||
|
12
pkg/machine/define/setopts.go
Normal file
12
pkg/machine/define/setopts.go
Normal file
@ -0,0 +1,12 @@
|
||||
package define
|
||||
|
||||
import "github.com/containers/common/pkg/strongunits"
|
||||
|
||||
type SetOptions struct {
|
||||
CPUs *uint64
|
||||
DiskSize *strongunits.GiB
|
||||
Memory *uint64
|
||||
Rootful *bool
|
||||
UserModeNetworking *bool
|
||||
USBs *[]string
|
||||
}
|
@ -290,7 +290,7 @@ func stateConversion(s hypervctl.EnabledState) (define.Status, error) {
|
||||
return define.Unknown, fmt.Errorf("unknown state: %q", s.String())
|
||||
}
|
||||
|
||||
func (h HyperVStubber) SetProviderAttrs(mc *vmconfigs.MachineConfig, cpus, memory *uint64, newDiskSize *strongunits.GiB, newRootful *bool) error {
|
||||
func (h HyperVStubber) SetProviderAttrs(mc *vmconfigs.MachineConfig, opts define.SetOptions) error {
|
||||
var (
|
||||
cpuChanged, memoryChanged bool
|
||||
)
|
||||
@ -308,35 +308,35 @@ func (h HyperVStubber) SetProviderAttrs(mc *vmconfigs.MachineConfig, cpus, memor
|
||||
return errors.New("unable to change settings unless vm is stopped")
|
||||
}
|
||||
|
||||
if newRootful != nil && mc.HostUser.Rootful != *newRootful {
|
||||
if err := mc.SetRootful(*newRootful); err != nil {
|
||||
if opts.Rootful != nil && mc.HostUser.Rootful != *opts.Rootful {
|
||||
if err := mc.SetRootful(*opts.Rootful); err != nil {
|
||||
return err
|
||||
}
|
||||
}
|
||||
|
||||
if newDiskSize != nil {
|
||||
if err := resizeDisk(*newDiskSize, mc.ImagePath); err != nil {
|
||||
if opts.DiskSize != nil {
|
||||
if err := resizeDisk(*opts.DiskSize, mc.ImagePath); err != nil {
|
||||
return err
|
||||
}
|
||||
}
|
||||
if cpus != nil {
|
||||
if opts.CPUs != nil {
|
||||
cpuChanged = true
|
||||
}
|
||||
if memory != nil {
|
||||
if opts.Memory != nil {
|
||||
memoryChanged = true
|
||||
}
|
||||
|
||||
if cpuChanged || memoryChanged {
|
||||
err := vm.UpdateProcessorMemSettings(func(ps *hypervctl.ProcessorSettings) {
|
||||
if cpuChanged {
|
||||
ps.VirtualQuantity = *cpus
|
||||
ps.VirtualQuantity = *opts.CPUs
|
||||
}
|
||||
}, func(ms *hypervctl.MemorySettings) {
|
||||
if memoryChanged {
|
||||
ms.DynamicMemoryEnabled = false
|
||||
ms.VirtualQuantity = *memory
|
||||
ms.Limit = *memory
|
||||
ms.Reservation = *memory
|
||||
ms.VirtualQuantity = *opts.Memory
|
||||
ms.Limit = *opts.Memory
|
||||
ms.Reservation = *opts.Memory
|
||||
}
|
||||
})
|
||||
if err != nil {
|
||||
@ -344,6 +344,10 @@ func (h HyperVStubber) SetProviderAttrs(mc *vmconfigs.MachineConfig, cpus, memor
|
||||
}
|
||||
}
|
||||
|
||||
if opts.USBs != nil {
|
||||
return fmt.Errorf("changing USBs not supported for hyperv machines")
|
||||
}
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
|
@ -64,8 +64,7 @@ func (q *QEMUStubber) setQEMUCommandLine(mc *vmconfigs.MachineConfig) error {
|
||||
q.Command.SetVirtfsMount(mount.Source, mount.Tag, securityModel, mount.ReadOnly)
|
||||
}
|
||||
|
||||
// TODO
|
||||
// v.QEMUConfig.Command.SetUSBHostPassthrough(v.USBs)
|
||||
q.Command.SetUSBHostPassthrough(mc.Resources.USBs)
|
||||
|
||||
return nil
|
||||
}
|
||||
@ -243,19 +242,27 @@ func (q *QEMUStubber) resizeDisk(newSize strongunits.GiB, diskPath *define.VMFil
|
||||
return nil
|
||||
}
|
||||
|
||||
func (q *QEMUStubber) SetProviderAttrs(mc *vmconfigs.MachineConfig, cpus, memory *uint64, newDiskSize *strongunits.GiB, newRootful *bool) error {
|
||||
if newDiskSize != nil {
|
||||
if err := q.resizeDisk(*newDiskSize, mc.ImagePath); err != nil {
|
||||
func (q *QEMUStubber) SetProviderAttrs(mc *vmconfigs.MachineConfig, opts define.SetOptions) error {
|
||||
if opts.DiskSize != nil {
|
||||
if err := q.resizeDisk(*opts.DiskSize, mc.ImagePath); err != nil {
|
||||
return err
|
||||
}
|
||||
}
|
||||
|
||||
if newRootful != nil && mc.HostUser.Rootful != *newRootful {
|
||||
if err := mc.SetRootful(*newRootful); err != nil {
|
||||
if opts.Rootful != nil && mc.HostUser.Rootful != *opts.Rootful {
|
||||
if err := mc.SetRootful(*opts.Rootful); err != nil {
|
||||
return err
|
||||
}
|
||||
}
|
||||
|
||||
if opts.USBs != nil {
|
||||
usbs, err := command.ParseUSBs(*opts.USBs)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
mc.Resources.USBs = usbs
|
||||
}
|
||||
|
||||
// Because QEMU does nothing with these hardware attributes, we can simply return
|
||||
return nil
|
||||
}
|
||||
|
@ -104,7 +104,7 @@ func Init(opts machineDefine.InitOptions, mp vmconfigs.VMProvider) (*vmconfigs.M
|
||||
return nil, err
|
||||
}
|
||||
|
||||
mc, err := vmconfigs.NewMachineConfig(opts, dirs, sshIdentityPath)
|
||||
mc, err := vmconfigs.NewMachineConfig(opts, dirs, sshIdentityPath, mp.VMType())
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
@ -5,7 +5,6 @@ import (
|
||||
"net/url"
|
||||
"time"
|
||||
|
||||
"github.com/containers/common/pkg/strongunits"
|
||||
gvproxy "github.com/containers/gvisor-tap-vsock/pkg/types"
|
||||
"github.com/containers/podman/v5/pkg/machine/define"
|
||||
"github.com/containers/podman/v5/pkg/machine/ignition"
|
||||
@ -114,7 +113,7 @@ type VMProvider interface { //nolint:interfacebloat
|
||||
MountVolumesToVM(mc *MachineConfig, quiet bool) error
|
||||
Remove(mc *MachineConfig) ([]string, func() error, error)
|
||||
RemoveAndCleanMachines(dirs *define.MachineDirs) error
|
||||
SetProviderAttrs(mc *MachineConfig, cpus, memory *uint64, newDiskSize *strongunits.GiB, newRootful *bool) error
|
||||
SetProviderAttrs(mc *MachineConfig, opts define.SetOptions) error
|
||||
StartNetworking(mc *MachineConfig, cmd *gvproxy.GvproxyCommand) error
|
||||
PostStartNetworking(mc *MachineConfig) error
|
||||
StartVM(mc *MachineConfig) (func() error, func() error, error)
|
||||
|
@ -14,6 +14,7 @@ import (
|
||||
"github.com/containers/podman/v5/pkg/machine/connection"
|
||||
"github.com/containers/podman/v5/pkg/machine/define"
|
||||
"github.com/containers/podman/v5/pkg/machine/lock"
|
||||
"github.com/containers/podman/v5/pkg/machine/qemu/command"
|
||||
"github.com/containers/podman/v5/utils"
|
||||
"github.com/sirupsen/logrus"
|
||||
)
|
||||
@ -40,7 +41,7 @@ var (
|
||||
type RemoteConnectionType string
|
||||
|
||||
// NewMachineConfig creates the initial machine configuration file from cli options
|
||||
func NewMachineConfig(opts define.InitOptions, dirs *define.MachineDirs, sshIdentityPath string) (*MachineConfig, error) {
|
||||
func NewMachineConfig(opts define.InitOptions, dirs *define.MachineDirs, sshIdentityPath string, vmtype define.VMType) (*MachineConfig, error) {
|
||||
mc := new(MachineConfig)
|
||||
mc.Name = opts.Name
|
||||
mc.dirs = dirs
|
||||
@ -58,12 +59,21 @@ func NewMachineConfig(opts define.InitOptions, dirs *define.MachineDirs, sshIden
|
||||
}
|
||||
mc.configPath = cf
|
||||
|
||||
if vmtype != define.QemuVirt && len(opts.USBs) > 0 {
|
||||
return nil, fmt.Errorf("USB host passthrough not supported for %s machines", vmtype)
|
||||
}
|
||||
|
||||
usbs, err := command.ParseUSBs(opts.USBs)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
// System Resources
|
||||
mrc := ResourceConfig{
|
||||
CPUs: opts.CPUS,
|
||||
DiskSize: opts.DiskSize,
|
||||
Memory: opts.Memory,
|
||||
USBs: nil, // Needs to be filled in by providers?
|
||||
USBs: usbs,
|
||||
}
|
||||
mc.Resources = mrc
|
||||
|
||||
|
@ -1105,7 +1105,7 @@ func setupWslProxyEnv() (hasProxy bool) {
|
||||
return
|
||||
}
|
||||
|
||||
func (v *MachineVM) Set(_ string, opts machine.SetOptions) ([]error, error) {
|
||||
func (v *MachineVM) Set(_ string, opts define.SetOptions) ([]error, error) {
|
||||
// If one setting fails to be applied, the others settings will not fail and still be applied.
|
||||
// The setting(s) that failed to be applied will have its errors returned in setErrors
|
||||
var setErrors []error
|
||||
|
Reference in New Issue
Block a user