Skip to content

Commit fd7a277

Browse files
committed
kola/qemuexec: allow changing guest network
This is useful when you're nesting VMs and you want the first VM to be able to access the host. The default host address that QEMU assigns (e.g. 10.0.2.2, modifiable via the `host=...` netdev knob) doesn't always work because it's not actually an IP address owned by the host, but proxied by QEMU itself. So the source appears to come from localhost, but in some contexts (e.g. iSCSI), we need the host and the guest to agree that the same IP refers to the host. With this, one can start the first VM as usual (e.g. `cosa run`) and the second VM within with e.g. `cosa run --usernet-addr 10.0.3.0/24` and be able to talk back to the outer VM via the valid address 10.0.2.15. To be clear, this can all be done with passthrough QEMU args, so this is just about making it more convenient.
1 parent 87e92d0 commit fd7a277

File tree

4 files changed

+15
-7
lines changed

4 files changed

+15
-7
lines changed

mantle/cmd/kola/qemuexec.go

+5-2
Original file line numberDiff line numberDiff line change
@@ -73,6 +73,8 @@ var (
7373

7474
netboot string
7575
netbootDir string
76+
77+
usernetAddr string
7678
)
7779

7880
const maxAdditionalNics = 16
@@ -102,6 +104,7 @@ func init() {
102104
cmdQemuExec.Flags().StringVarP(&sshCommand, "ssh-command", "x", "", "Command to execute instead of spawning a shell")
103105
cmdQemuExec.Flags().StringVarP(&netboot, "netboot", "", "", "Filepath to BOOTP program (e.g. PXELINUX/GRUB binary or iPXE script")
104106
cmdQemuExec.Flags().StringVarP(&netbootDir, "netboot-dir", "", "", "Directory to serve over TFTP (default: BOOTP parent dir). If specified, --netboot is relative to this dir.")
107+
cmdQemuExec.Flags().StringVarP(&usernetAddr, "usernet-addr", "", "", "Guest IP network (QEMU default is '10.0.2.0/24')")
105108
}
106109

107110
func renderFragments(fragments []string, c *conf.Conf) error {
@@ -356,11 +359,11 @@ func runQemuExec(cmd *cobra.Command, args []string) error {
356359
if cpuCountHost {
357360
builder.Processors = -1
358361
}
359-
if usernet {
362+
if usernet || usernetAddr != "" {
360363
h := []platform.HostForwardPort{
361364
{Service: "ssh", HostPort: 0, GuestPort: 22},
362365
}
363-
builder.EnableUsermodeNetworking(h)
366+
builder.EnableUsermodeNetworking(h, usernetAddr)
364367
}
365368
if netboot != "" {
366369
builder.SetNetbootP(netboot, netbootDir)

mantle/platform/machine/qemu/cluster.go

+2-2
Original file line numberDiff line numberDiff line change
@@ -175,12 +175,12 @@ func (qc *Cluster) NewMachineWithQemuOptions(userdata *conf.UserData, options pl
175175
}
176176

177177
if len(options.HostForwardPorts) > 0 {
178-
builder.EnableUsermodeNetworking(options.HostForwardPorts)
178+
builder.EnableUsermodeNetworking(options.HostForwardPorts, "")
179179
} else {
180180
h := []platform.HostForwardPort{
181181
{Service: "ssh", HostPort: 0, GuestPort: 22},
182182
}
183-
builder.EnableUsermodeNetworking(h)
183+
builder.EnableUsermodeNetworking(h, "")
184184
}
185185
if options.AdditionalNics > 0 {
186186
builder.AddAdditionalNics(options.AdditionalNics)

mantle/platform/machine/qemuiso/cluster.go

+2-2
Original file line numberDiff line numberDiff line change
@@ -124,12 +124,12 @@ func (qc *Cluster) NewMachineWithQemuOptions(userdata *conf.UserData, options pl
124124
}
125125

126126
if len(options.HostForwardPorts) > 0 {
127-
builder.EnableUsermodeNetworking(options.HostForwardPorts)
127+
builder.EnableUsermodeNetworking(options.HostForwardPorts, "")
128128
} else {
129129
h := []platform.HostForwardPort{
130130
{Service: "ssh", HostPort: 0, GuestPort: 22},
131131
}
132-
builder.EnableUsermodeNetworking(h)
132+
builder.EnableUsermodeNetworking(h, "")
133133
}
134134

135135
if options.AdditionalNics > 0 {

mantle/platform/qemu.go

+6-1
Original file line numberDiff line numberDiff line change
@@ -478,6 +478,7 @@ type QemuBuilder struct {
478478
ignitionRendered bool
479479

480480
UsermodeNetworking bool
481+
usermodeNetworkingAddr string
481482
RestrictNetworking bool
482483
requestedHostForwardPorts []HostForwardPort
483484
additionalNics int
@@ -599,9 +600,10 @@ func virtio(arch, device, args string) string {
599600

600601
// EnableUsermodeNetworking configure forwarding for all requested ports,
601602
// via usermode network helpers.
602-
func (builder *QemuBuilder) EnableUsermodeNetworking(h []HostForwardPort) {
603+
func (builder *QemuBuilder) EnableUsermodeNetworking(h []HostForwardPort, usernetAddr string) {
603604
builder.UsermodeNetworking = true
604605
builder.requestedHostForwardPorts = h
606+
builder.usermodeNetworkingAddr = usernetAddr
605607
}
606608

607609
func (builder *QemuBuilder) SetNetbootP(filename, dir string) {
@@ -637,6 +639,9 @@ func (builder *QemuBuilder) setupNetworking() error {
637639
if builder.RestrictNetworking {
638640
netdev += ",restrict=on"
639641
}
642+
if builder.usermodeNetworkingAddr != "" {
643+
netdev += ",net=" + builder.usermodeNetworkingAddr
644+
}
640645
if builder.netbootP != "" {
641646
// do an early stat so we fail with a nicer error now instead of in the VM
642647
if _, err := os.Stat(filepath.Join(builder.netbootDir, builder.netbootP)); err != nil {

0 commit comments

Comments
 (0)