Skip to content

Commit fd4346f

Browse files
committed
Pass DNS addresses from en0 interface to guest instance
qemu user-mode networking is forwarding DNS to just a single DNS entry from the host. So if that entry does not resolve the query, there is no fallback. Signed-off-by: Jan Dubois <[email protected]>
1 parent deccdaf commit fd4346f

File tree

8 files changed

+102
-0
lines changed

8 files changed

+102
-0
lines changed

pkg/cidata/cidata.TEMPLATE.d/network-config

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -6,4 +6,11 @@ ethernets:
66
macaddress: '{{$nw.MACAddress}}'
77
dhcp4: true
88
set-name: {{$nw.Name}}
9+
{{- if and (eq $nw.Name $.SlirpNICName) (gt (len $.DNSAddresses) 0) }}
10+
nameservers:
11+
addresses:
12+
{{- range $ns := $.DNSAddresses }}
13+
- {{$ns}}
14+
{{- end }}
15+
{{- end }}
916
{{- end }}

pkg/cidata/cidata.go

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -16,6 +16,7 @@ import (
1616
"github.com/lima-vm/lima/pkg/iso9660util"
1717
"github.com/lima-vm/lima/pkg/limayaml"
1818
"github.com/lima-vm/lima/pkg/localpathutil"
19+
"github.com/lima-vm/lima/pkg/osutil"
1920
"github.com/lima-vm/lima/pkg/qemu/qemuconst"
2021
"github.com/lima-vm/lima/pkg/sshutil"
2122
"github.com/lima-vm/lima/pkg/store/filenames"
@@ -51,6 +52,7 @@ func GenerateISO9660(instDir, name string, y *limayaml.LimaYAML) error {
5152
User: u.Username,
5253
UID: uid,
5354
Containerd: Containerd{System: *y.Containerd.System, User: *y.Containerd.User},
55+
SlirpNICName: qemuconst.SlirpNICName,
5456
SlirpGateway: qemuconst.SlirpGateway,
5557
Env: y.Env,
5658
}
@@ -80,6 +82,11 @@ func GenerateISO9660(instDir, name string, y *limayaml.LimaYAML) error {
8082
args.Networks = append(args.Networks, Network{MACAddress: vde.MACAddress, Name: vde.Name})
8183
}
8284

85+
args.DNSAddresses, err = osutil.DNSAddresses()
86+
if err != nil {
87+
return err
88+
}
89+
8390
if err := ValidateTemplateArgs(args); err != nil {
8491
return err
8592
}

pkg/cidata/template.go

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -35,8 +35,10 @@ type TemplateArgs struct {
3535
Mounts []string // abs path, accessible by the User
3636
Containerd Containerd
3737
Networks []Network
38+
SlirpNICName string
3839
SlirpGateway string
3940
Env map[string]*string
41+
DNSAddresses []string
4042
}
4143

4244
func ValidateTemplateArgs(args TemplateArgs) error {

pkg/osutil/dns_darwin.go

Lines changed: 25 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,25 @@
1+
package osutil
2+
3+
import "github.com/lima-vm/lima/pkg/sysprof"
4+
5+
func DNSAddresses() ([]string, error) {
6+
nwData, err := sysprof.NetworkData()
7+
if err != nil {
8+
return nil, err
9+
}
10+
var addresses []string
11+
if len(nwData) > 0 {
12+
// Return DNS addresses from en0 interface
13+
for _, nw := range nwData {
14+
if nw.Interface == "en0" {
15+
addresses = nw.DNS.ServerAddresses
16+
break
17+
}
18+
}
19+
// In case "en0" is not found, use the addresses of the first interface
20+
if len(addresses) == 0 {
21+
addresses = nwData[0].DNS.ServerAddresses
22+
}
23+
}
24+
return addresses, nil
25+
}

pkg/osutil/dns_others.go

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,9 @@
1+
//go:build !darwin
2+
// +build !darwin
3+
4+
package osutil
5+
6+
func DNSAddresses() ([]string, error) {
7+
// TODO: parse /etc/resolv.conf?
8+
return []string{}, nil
9+
}

pkg/osutil/osutil_others.go

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,4 @@
1+
//go:build !linux
12
// +build !linux
23

34
package osutil

pkg/sysprof/network_darwin.go

Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,14 @@
1+
package sysprof
2+
3+
type SPNetworkDataType struct {
4+
SPNetworkDataType []NetworkDataType `json:"SPNetworkDataType"`
5+
}
6+
7+
type NetworkDataType struct {
8+
DNS DNS `json:"DNS"`
9+
Interface string `json:"interface"`
10+
}
11+
12+
type DNS struct {
13+
ServerAddresses []string `json:"ServerAddresses"`
14+
}

pkg/sysprof/sysprof_darwin.go

Lines changed: 37 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,37 @@
1+
package sysprof
2+
3+
import (
4+
"bytes"
5+
"encoding/json"
6+
"fmt"
7+
"os/exec"
8+
"sync"
9+
)
10+
11+
var (
12+
networkDataOnce sync.Once
13+
networkDataCached SPNetworkDataType
14+
networkDataError error
15+
)
16+
17+
func NetworkData() ([]NetworkDataType, error) {
18+
networkDataOnce.Do(func() {
19+
jsonBytes, networkDataError := SystemProfiler("SPNetworkDataType")
20+
if networkDataError == nil {
21+
networkDataError = json.Unmarshal(jsonBytes, &networkDataCached)
22+
}
23+
})
24+
return networkDataCached.SPNetworkDataType, networkDataError
25+
}
26+
27+
func SystemProfiler(dataType string) ([]byte, error) {
28+
var stdout, stderr bytes.Buffer
29+
cmd := exec.Command("system_profiler", dataType, "-json")
30+
cmd.Stdout = &stdout
31+
cmd.Stderr = &stderr
32+
if err := cmd.Run(); err != nil {
33+
return nil, fmt.Errorf("failed to run %v: stdout=%q, stderr=%q: %w",
34+
cmd.Args, stdout.String(), stderr.String(), err)
35+
}
36+
return stdout.Bytes(), nil
37+
}

0 commit comments

Comments
 (0)