Skip to content

Commit

Permalink
Setup proxy environment variables from system settings
Browse files Browse the repository at this point in the history
env.* settings from lima.yaml will override system settings.

Process environment during instance creation override all.

Signed-off-by: Jan Dubois <[email protected]>
  • Loading branch information
jandubois committed Sep 23, 2021
1 parent bd624bd commit 9d12ab2
Show file tree
Hide file tree
Showing 7 changed files with 141 additions and 25 deletions.
47 changes: 46 additions & 1 deletion pkg/cidata/cidata.go
Original file line number Diff line number Diff line change
Expand Up @@ -34,6 +34,48 @@ var (
}
)

func setupEnv(y *limayaml.LimaYAML) (map[string]string, error) {
// Start with the proxy variables from the system settings.
env, err := osutil.ProxySettings()
if err != nil {
return env, err
}
// env.* settings from lima.yaml override system settings without giving a warning
for name, value := range y.Env {
env[name] = value
}
// Current process environment setting override both system settings and env.*
lowerVars := []string{"ftp_proxy", "http_proxy", "https_proxy", "no_proxy"}
upperVARS := make([]string, len(lowerVars))
for i, name := range lowerVars {
upperVARS[i] = strings.ToUpper(name)
}
for _, name := range append(lowerVars, upperVARS...) {
if value, ok := os.LookupEnv(name); ok {
if _, ok := env[name]; ok && value != env[name] {
logrus.Infof("Overriding %q value %q with %q from limactl process environment",
name, env[name], value)
}
env[name] = value
}
}
// Make sure uppercase variants have the same value as lowercase ones.
// If both are set, the lowercase variant value takes precedence.
for _, lowerName := range lowerVars {
upperName := strings.ToUpper(lowerName)
if _, ok := env[lowerName]; ok {
if _, ok := env[upperName]; ok && env[lowerName] != env[upperName] {
logrus.Warnf("Changing %q value from %q to %q to match %q",
upperName, env[upperName], env[lowerName], lowerName)
}
env[upperName] = env[lowerName]
} else if _, ok := env[upperName]; ok {
env[lowerName] = env[upperName]
}
}
return env, nil
}

func GenerateISO9660(instDir, name string, y *limayaml.LimaYAML) error {
if err := limayaml.Validate(*y, false); err != nil {
return err
Expand All @@ -54,7 +96,6 @@ func GenerateISO9660(instDir, name string, y *limayaml.LimaYAML) error {
SlirpNICName: qemu.SlirpNICName,
SlirpGateway: qemu.SlirpGateway,
SlirpDNS: qemu.SlirpDNS,
Env: y.Env,
}

pubKeys, err := sshutil.DefaultPubKeys(*y.SSH.LoadDotSSHPubKeys)
Expand Down Expand Up @@ -82,6 +123,10 @@ func GenerateISO9660(instDir, name string, y *limayaml.LimaYAML) error {
args.Networks = append(args.Networks, Network{MACAddress: nw.MACAddress, Interface: nw.Interface})
}

args.Env, err = setupEnv(y)
if err != nil {
return err
}
if len(y.DNS) > 0 {
for _, addr := range y.DNS {
args.DNSAddresses = append(args.DNSAddresses, addr.String())
Expand Down
2 changes: 1 addition & 1 deletion pkg/cidata/template.go
Original file line number Diff line number Diff line change
Expand Up @@ -38,7 +38,7 @@ type TemplateArgs struct {
SlirpNICName string
SlirpGateway string
SlirpDNS string
Env map[string]*string
Env map[string]string
DNSAddresses []string
}

Expand Down
7 changes: 4 additions & 3 deletions pkg/limayaml/default.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -177,9 +177,10 @@ networks:
# # Any port still not matched by a rule will not be forwarded (ignored)

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

Expand Down
34 changes: 17 additions & 17 deletions pkg/limayaml/limayaml.go
Original file line number Diff line number Diff line change
Expand Up @@ -7,23 +7,23 @@ import (
)

type LimaYAML struct {
Arch Arch `yaml:"arch,omitempty"`
Images []File `yaml:"images"` // REQUIRED
CPUs int `yaml:"cpus,omitempty"`
Memory string `yaml:"memory,omitempty"` // go-units.RAMInBytes
Disk string `yaml:"disk,omitempty"` // go-units.RAMInBytes
Mounts []Mount `yaml:"mounts,omitempty"`
SSH SSH `yaml:"ssh,omitempty"` // REQUIRED (FIXME)
Firmware Firmware `yaml:"firmware,omitempty"`
Video Video `yaml:"video,omitempty"`
Provision []Provision `yaml:"provision,omitempty"`
Containerd Containerd `yaml:"containerd,omitempty"`
Probes []Probe `yaml:"probes,omitempty"`
PortForwards []PortForward `yaml:"portForwards,omitempty"`
Networks []Network `yaml:"networks,omitempty"`
Network NetworkDeprecated `yaml:"network,omitempty"` // DEPRECATED, use `networks` instead
Env map[string]*string `yaml:"env,omitempty"` // EXPERIMENAL, see default.yaml
DNS []net.IP `yaml:"dns,omitempty"`
Arch Arch `yaml:"arch,omitempty"`
Images []File `yaml:"images"` // REQUIRED
CPUs int `yaml:"cpus,omitempty"`
Memory string `yaml:"memory,omitempty"` // go-units.RAMInBytes
Disk string `yaml:"disk,omitempty"` // go-units.RAMInBytes
Mounts []Mount `yaml:"mounts,omitempty"`
SSH SSH `yaml:"ssh,omitempty"` // REQUIRED (FIXME)
Firmware Firmware `yaml:"firmware,omitempty"`
Video Video `yaml:"video,omitempty"`
Provision []Provision `yaml:"provision,omitempty"`
Containerd Containerd `yaml:"containerd,omitempty"`
Probes []Probe `yaml:"probes,omitempty"`
PortForwards []PortForward `yaml:"portForwards,omitempty"`
Networks []Network `yaml:"networks,omitempty"`
Network NetworkDeprecated `yaml:"network,omitempty"` // DEPRECATED, use `networks` instead
Env map[string]string `yaml:"env,omitempty"`
DNS []net.IP `yaml:"dns,omitempty"`
}

type Arch = string
Expand Down
51 changes: 50 additions & 1 deletion pkg/osutil/dns_darwin.go
Original file line number Diff line number Diff line change
@@ -1,6 +1,11 @@
package osutil

import "github.com/lima-vm/lima/pkg/sysprof"
import (
"fmt"
"strings"

"github.com/lima-vm/lima/pkg/sysprof"
)

func DNSAddresses() ([]string, error) {
nwData, err := sysprof.NetworkData()
Expand All @@ -23,3 +28,47 @@ func DNSAddresses() ([]string, error) {
}
return addresses, nil
}

func proxyURL(proxy string, port int) string {
if !strings.Contains(proxy, "://") {
proxy = "http://" + proxy
}
if port != 0 {
proxy = fmt.Sprintf("%s:%d", proxy, port)
}
return proxy
}

func ProxySettings() (map[string]string, error) {
nwData, err := sysprof.NetworkData()
if err != nil {
return nil, err
}
env := make(map[string]string)
if len(nwData) > 0 {
// In case "en0" is not found, use the proxies of the first interface
proxies := nwData[0].Proxies
for _, nw := range nwData {
if nw.Interface == "en0" {
proxies = nw.Proxies
break
}
}
// Proxies with a username are not going to work because the password is stored in a keychain.
// If users are fine with exposing the username/password, they can set the proxy to
// "http://username:[email protected]" in the system settings (or in lima.yaml).
if proxies.FTPEnable == "yes" && proxies.FTPUser == "" {
env["ftp_proxy"] = proxyURL(proxies.FTPProxy, proxies.FTPPort)
}
if proxies.HTTPEnable == "yes" && proxies.HTTPUser == "" {
env["http_proxy"] = proxyURL(proxies.HTTPProxy, proxies.HTTPPort)
}
if proxies.HTTPSEnable == "yes" && proxies.HTTPSUser == "" {
env["https_proxy"] = proxyURL(proxies.HTTPSProxy, proxies.HTTPSPort)
}
// Not setting up "no_proxy" variable; the values from the proxies.ExceptionList are
// not understood by most applications checking "no_proxy". The default value would
// be "*.local,169.254/16". Users can always specify env.no_proxy in lima.yaml.
}
return env, nil
}
4 changes: 4 additions & 0 deletions pkg/osutil/dns_others.go
Original file line number Diff line number Diff line change
Expand Up @@ -7,3 +7,7 @@ func DNSAddresses() ([]string, error) {
// TODO: parse /etc/resolv.conf?
return []string{}, nil
}

func ProxySettings() (map[string]string, error) {
return make(map[string]string)
}
21 changes: 19 additions & 2 deletions pkg/sysprof/network_darwin.go
Original file line number Diff line number Diff line change
Expand Up @@ -5,10 +5,27 @@ type SPNetworkDataType struct {
}

type NetworkDataType struct {
DNS DNS `json:"DNS"`
Interface string `json:"interface"`
DNS DNS `json:"DNS"`
Interface string `json:"interface"`
Proxies Proxies `json:"proxies"`
}

type DNS struct {
ServerAddresses []string `json:"ServerAddresses"`
}

type Proxies struct {
ExceptionList []string `json:"ExceptionList"` // default: ["*.local", "169.254/16"]
FTPEnable string `json:"FTPEnable"`
FTPPort int `json:"FTPPort"`
FTPProxy string `json:"FTPProxy"`
FTPUser string `json:"FTPUser"`
HTTPEnable string `json:"HTTPEnable"`
HTTPPort int `json:"HTTPPort"`
HTTPProxy string `json:"HTTPProxy"`
HTTPUser string `json:"HTTPUser"`
HTTPSEnable string `json:"HTTPSEnable"`
HTTPSPort int `json:"HTTPSPort"`
HTTPSProxy string `json:"HTTPSProxy"`
HTTPSUser string `json:"HTTPSUser"`
}

0 comments on commit 9d12ab2

Please sign in to comment.