Skip to content

Commit 14ce51c

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 2749877 commit 14ce51c

File tree

8 files changed

+124
-0
lines changed

8 files changed

+124
-0
lines changed
Lines changed: 29 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,29 @@
1+
#!/bin/sh
2+
set -eux
3+
4+
DNS=""
5+
# NOTE: Busybox sh does not support `for ((i=0;i<$N;i++))` form
6+
for f in $(seq 0 $((LIMA_CIDATA_DNS - 1))); do
7+
dnsaddressvar="LIMA_CIDATA_DNS_${f}_ADDRESS"
8+
dnsaddress="$(eval echo \$"$dnsaddressvar")"
9+
if [ -z "${DNS}" ]; then
10+
DNS="${dnsaddress}"
11+
else
12+
DNS="${DNS} ${dnsaddress}"
13+
fi
14+
echo "nameserver ${dnsaddress}" >>/etc/resolv.conf
15+
done
16+
17+
if [ -n "${DNS}" ]; then
18+
RESOLVED=/etc/systemd/resolved.conf
19+
if [ -f "${RESOLVED}" ]; then
20+
sed -i "/DNS=/d" "${RESOLVED}"
21+
sed -i "/\[Resolve\]/a DNS=${DNS}" "${RESOLVED}"
22+
systemctl restart systemd-resolved.service
23+
fi
24+
25+
UDHCPC=/usr/share/udhcpc/default.script
26+
if [ -f "${UDHCPC}" ]; then
27+
sed -i "/export dns/a dns=\"${DNS}\"" "${UDHCPC}"
28+
fi
29+
fi

pkg/cidata/cidata.TEMPLATE.d/lima.env

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,10 @@ LIMA_CIDATA_MOUNTS={{ len .Mounts }}
44
{{- range $i, $val := .Mounts}}
55
LIMA_CIDATA_MOUNTS_{{$i}}_MOUNTPOINT={{$val}}
66
{{- end}}
7+
LIMA_CIDATA_DNS={{ len .DNSAddresses }}
8+
{{- range $i, $val := .DNSAddresses }}
9+
LIMA_CIDATA_DNS_{{$i}}_ADDRESS={{$val}}
10+
{{- end}}
711
{{- if .Containerd.User}}
812
LIMA_CIDATA_CONTAINERD_USER=1
913
{{- else}}

pkg/cidata/cidata.go

Lines changed: 6 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"
@@ -79,6 +80,11 @@ func GenerateISO9660(instDir, name string, y *limayaml.LimaYAML) error {
7980
args.Networks = append(args.Networks, Network{MACAddress: vde.MACAddress, Name: vde.Name})
8081
}
8182

83+
args.DNSAddresses, err = osutil.DNSAddresses()
84+
if err != nil {
85+
return err
86+
}
87+
8288
if err := ValidateTemplateArgs(args); err != nil {
8389
return err
8490
}

pkg/cidata/template.go

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -36,6 +36,7 @@ type TemplateArgs struct {
3636
Containerd Containerd
3737
Networks []Network
3838
SlirpGateway string
39+
DNSAddresses []string
3940
}
4041

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

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)