Skip to content

Commit e970ff7

Browse files
authored
Merge pull request #266 from rancher-sandbox/proxy
Setup proxy environment variables from system settings
2 parents 2c65a04 + f76c0e4 commit e970ff7

File tree

7 files changed

+141
-25
lines changed

7 files changed

+141
-25
lines changed

pkg/cidata/cidata.go

Lines changed: 46 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -35,6 +35,48 @@ var (
3535
}
3636
)
3737

38+
func setupEnv(y *limayaml.LimaYAML) (map[string]string, error) {
39+
// Start with the proxy variables from the system settings.
40+
env, err := osutil.ProxySettings()
41+
if err != nil {
42+
return env, err
43+
}
44+
// env.* settings from lima.yaml override system settings without giving a warning
45+
for name, value := range y.Env {
46+
env[name] = value
47+
}
48+
// Current process environment setting override both system settings and env.*
49+
lowerVars := []string{"ftp_proxy", "http_proxy", "https_proxy", "no_proxy"}
50+
upperVars := make([]string, len(lowerVars))
51+
for i, name := range lowerVars {
52+
upperVars[i] = strings.ToUpper(name)
53+
}
54+
for _, name := range append(lowerVars, upperVars...) {
55+
if value, ok := os.LookupEnv(name); ok {
56+
if _, ok := env[name]; ok && value != env[name] {
57+
logrus.Infof("Overriding %q value %q with %q from limactl process environment",
58+
name, env[name], value)
59+
}
60+
env[name] = value
61+
}
62+
}
63+
// Make sure uppercase variants have the same value as lowercase ones.
64+
// If both are set, the lowercase variant value takes precedence.
65+
for _, lowerName := range lowerVars {
66+
upperName := strings.ToUpper(lowerName)
67+
if _, ok := env[lowerName]; ok {
68+
if _, ok := env[upperName]; ok && env[lowerName] != env[upperName] {
69+
logrus.Warnf("Changing %q value from %q to %q to match %q",
70+
upperName, env[upperName], env[lowerName], lowerName)
71+
}
72+
env[upperName] = env[lowerName]
73+
} else if _, ok := env[upperName]; ok {
74+
env[lowerName] = env[upperName]
75+
}
76+
}
77+
return env, nil
78+
}
79+
3880
func GenerateISO9660(instDir, name string, y *limayaml.LimaYAML) error {
3981
if err := limayaml.Validate(*y, false); err != nil {
4082
return err
@@ -55,7 +97,6 @@ func GenerateISO9660(instDir, name string, y *limayaml.LimaYAML) error {
5597
SlirpNICName: qemu.SlirpNICName,
5698
SlirpGateway: qemu.SlirpGateway,
5799
SlirpDNS: qemu.SlirpDNS,
58-
Env: y.Env,
59100
}
60101

61102
// change instance id on every boot so network config will be processed again
@@ -86,6 +127,10 @@ func GenerateISO9660(instDir, name string, y *limayaml.LimaYAML) error {
86127
args.Networks = append(args.Networks, Network{MACAddress: nw.MACAddress, Interface: nw.Interface})
87128
}
88129

130+
args.Env, err = setupEnv(y)
131+
if err != nil {
132+
return err
133+
}
89134
if len(y.DNS) > 0 {
90135
for _, addr := range y.DNS {
91136
args.DNSAddresses = append(args.DNSAddresses, addr.String())

pkg/cidata/template.go

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -39,7 +39,7 @@ type TemplateArgs struct {
3939
SlirpNICName string
4040
SlirpGateway string
4141
SlirpDNS string
42-
Env map[string]*string
42+
Env map[string]string
4343
DNSAddresses []string
4444
}
4545

pkg/limayaml/default.yaml

Lines changed: 4 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -177,9 +177,10 @@ networks:
177177
# # Any port still not matched by a rule will not be forwarded (ignored)
178178

179179
# Extra environment variables that will be loaded into the VM at start up.
180-
# These variables are currently only consumed by internal init scripts, not by the user shell.
181-
# This field is experimental and may change in a future release of Lima.
182-
# https://github.com/lima-vm/lima/pull/200
180+
# These variables are consumed by internal init scripts, and also added
181+
# to /etc/environment.
182+
# If you set any of "ftp_proxy", "http_proxy", "https_proxy", or "no_proxy", then
183+
# Lima will automatically set an uppercase variant to the same value as well.
183184
# env:
184185
# KEY: value
185186

pkg/limayaml/limayaml.go

Lines changed: 17 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -7,23 +7,23 @@ import (
77
)
88

99
type LimaYAML struct {
10-
Arch Arch `yaml:"arch,omitempty"`
11-
Images []File `yaml:"images"` // REQUIRED
12-
CPUs int `yaml:"cpus,omitempty"`
13-
Memory string `yaml:"memory,omitempty"` // go-units.RAMInBytes
14-
Disk string `yaml:"disk,omitempty"` // go-units.RAMInBytes
15-
Mounts []Mount `yaml:"mounts,omitempty"`
16-
SSH SSH `yaml:"ssh,omitempty"` // REQUIRED (FIXME)
17-
Firmware Firmware `yaml:"firmware,omitempty"`
18-
Video Video `yaml:"video,omitempty"`
19-
Provision []Provision `yaml:"provision,omitempty"`
20-
Containerd Containerd `yaml:"containerd,omitempty"`
21-
Probes []Probe `yaml:"probes,omitempty"`
22-
PortForwards []PortForward `yaml:"portForwards,omitempty"`
23-
Networks []Network `yaml:"networks,omitempty"`
24-
Network NetworkDeprecated `yaml:"network,omitempty"` // DEPRECATED, use `networks` instead
25-
Env map[string]*string `yaml:"env,omitempty"` // EXPERIMENAL, see default.yaml
26-
DNS []net.IP `yaml:"dns,omitempty"`
10+
Arch Arch `yaml:"arch,omitempty"`
11+
Images []File `yaml:"images"` // REQUIRED
12+
CPUs int `yaml:"cpus,omitempty"`
13+
Memory string `yaml:"memory,omitempty"` // go-units.RAMInBytes
14+
Disk string `yaml:"disk,omitempty"` // go-units.RAMInBytes
15+
Mounts []Mount `yaml:"mounts,omitempty"`
16+
SSH SSH `yaml:"ssh,omitempty"` // REQUIRED (FIXME)
17+
Firmware Firmware `yaml:"firmware,omitempty"`
18+
Video Video `yaml:"video,omitempty"`
19+
Provision []Provision `yaml:"provision,omitempty"`
20+
Containerd Containerd `yaml:"containerd,omitempty"`
21+
Probes []Probe `yaml:"probes,omitempty"`
22+
PortForwards []PortForward `yaml:"portForwards,omitempty"`
23+
Networks []Network `yaml:"networks,omitempty"`
24+
Network NetworkDeprecated `yaml:"network,omitempty"` // DEPRECATED, use `networks` instead
25+
Env map[string]string `yaml:"env,omitempty"`
26+
DNS []net.IP `yaml:"dns,omitempty"`
2727
}
2828

2929
type Arch = string

pkg/osutil/dns_darwin.go

Lines changed: 50 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,11 @@
11
package osutil
22

3-
import "github.com/lima-vm/lima/pkg/sysprof"
3+
import (
4+
"fmt"
5+
"strings"
6+
7+
"github.com/lima-vm/lima/pkg/sysprof"
8+
)
49

510
func DNSAddresses() ([]string, error) {
611
nwData, err := sysprof.NetworkData()
@@ -23,3 +28,47 @@ func DNSAddresses() ([]string, error) {
2328
}
2429
return addresses, nil
2530
}
31+
32+
func proxyURL(proxy string, port int) string {
33+
if !strings.Contains(proxy, "://") {
34+
proxy = "http://" + proxy
35+
}
36+
if port != 0 {
37+
proxy = fmt.Sprintf("%s:%d", proxy, port)
38+
}
39+
return proxy
40+
}
41+
42+
func ProxySettings() (map[string]string, error) {
43+
nwData, err := sysprof.NetworkData()
44+
if err != nil {
45+
return nil, err
46+
}
47+
env := make(map[string]string)
48+
if len(nwData) > 0 {
49+
// In case "en0" is not found, use the proxies of the first interface
50+
proxies := nwData[0].Proxies
51+
for _, nw := range nwData {
52+
if nw.Interface == "en0" {
53+
proxies = nw.Proxies
54+
break
55+
}
56+
}
57+
// Proxies with a username are not going to work because the password is stored in a keychain.
58+
// If users are fine with exposing the username/password, they can set the proxy to
59+
// "http://username:[email protected]" in the system settings (or in lima.yaml).
60+
if proxies.FTPEnable == "yes" && proxies.FTPUser == "" {
61+
env["ftp_proxy"] = proxyURL(proxies.FTPProxy, proxies.FTPPort)
62+
}
63+
if proxies.HTTPEnable == "yes" && proxies.HTTPUser == "" {
64+
env["http_proxy"] = proxyURL(proxies.HTTPProxy, proxies.HTTPPort)
65+
}
66+
if proxies.HTTPSEnable == "yes" && proxies.HTTPSUser == "" {
67+
env["https_proxy"] = proxyURL(proxies.HTTPSProxy, proxies.HTTPSPort)
68+
}
69+
// Not setting up "no_proxy" variable; the values from the proxies.ExceptionList are
70+
// not understood by most applications checking "no_proxy". The default value would
71+
// be "*.local,169.254/16". Users can always specify env.no_proxy in lima.yaml.
72+
}
73+
return env, nil
74+
}

pkg/osutil/dns_others.go

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -7,3 +7,7 @@ func DNSAddresses() ([]string, error) {
77
// TODO: parse /etc/resolv.conf?
88
return []string{}, nil
99
}
10+
11+
func ProxySettings() (map[string]string, error) {
12+
return make(map[string]string), nil
13+
}

pkg/sysprof/network_darwin.go

Lines changed: 19 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -5,10 +5,27 @@ type SPNetworkDataType struct {
55
}
66

77
type NetworkDataType struct {
8-
DNS DNS `json:"DNS"`
9-
Interface string `json:"interface"`
8+
DNS DNS `json:"DNS"`
9+
Interface string `json:"interface"`
10+
Proxies Proxies `json:"Proxies"`
1011
}
1112

1213
type DNS struct {
1314
ServerAddresses []string `json:"ServerAddresses"`
1415
}
16+
17+
type Proxies struct {
18+
ExceptionList []string `json:"ExceptionList"` // default: ["*.local", "169.254/16"]
19+
FTPEnable string `json:"FTPEnable"`
20+
FTPPort int `json:"FTPPort"`
21+
FTPProxy string `json:"FTPProxy"`
22+
FTPUser string `json:"FTPUser"`
23+
HTTPEnable string `json:"HTTPEnable"`
24+
HTTPPort int `json:"HTTPPort"`
25+
HTTPProxy string `json:"HTTPProxy"`
26+
HTTPUser string `json:"HTTPUser"`
27+
HTTPSEnable string `json:"HTTPSEnable"`
28+
HTTPSPort int `json:"HTTPSPort"`
29+
HTTPSProxy string `json:"HTTPSProxy"`
30+
HTTPSUser string `json:"HTTPSUser"`
31+
}

0 commit comments

Comments
 (0)