Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
7 changes: 7 additions & 0 deletions cmd/start.go
Original file line number Diff line number Diff line change
Expand Up @@ -45,6 +45,7 @@ Run 'colima template' to set the default configurations or 'colima start --edit'
" colima start --arch aarch64\n" +
" colima start --dns 1.1.1.1 --dns 8.8.8.8\n" +
" colima start --dns-host example.com=1.2.3.4\n" +
" colima start --gateway-address 192.168.6.2\n" +
" colima start --kubernetes --k3s-arg='\"--disable=coredns,servicelb,traefik,local-storage,metrics-server\"'",
Args: cobra.MaximumNArgs(1),
RunE: func(cmd *cobra.Command, args []string) error {
Expand Down Expand Up @@ -210,6 +211,9 @@ func init() {
}
}

// Gateway Address
startCmd.Flags().StringVar(&startCmdArgs.Network.GatewayAddress, "gateway-address", "192.168.5.2", "gateway address")

// binfmt
startCmd.Flags().BoolVar(&startCmdArgs.Flags.Binfmt, "binfmt", true, binfmtDesc)

Expand Down Expand Up @@ -518,6 +522,9 @@ func prepareConfig(cmd *cobra.Command) {
if !cmd.Flag("dns-host").Changed {
startCmdArgs.Network.DNSHosts = current.Network.DNSHosts
}
if !cmd.Flag("gateway-address").Changed {
startCmdArgs.Network.GatewayAddress = current.Network.GatewayAddress
}
if !cmd.Flag("env").Changed {
startCmdArgs.Env = current.Env
}
Expand Down
1 change: 1 addition & 0 deletions config/config.go
Original file line number Diff line number Diff line change
Expand Up @@ -88,6 +88,7 @@ type Network struct {
Mode string `yaml:"mode"` // shared, bridged
BridgeInterface string `yaml:"interface"`
PreferredRoute bool `yaml:"preferredRoute"`
GatewayAddress string `yaml:"gatewayAddress"`
}

// Mount is volume mount
Expand Down
31 changes: 31 additions & 0 deletions config/configmanager/configmanager.go
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@ package configmanager

import (
"fmt"
"net"
"os"
"strings"

Expand Down Expand Up @@ -80,6 +81,12 @@ func ValidateConfig(c config.Config) error {
return fmt.Errorf("invalid port forwarder: '%s'", c.PortForwarder)
}

if c.Network.GatewayAddress != "" {
if err := validateGatewayAddress(c.Network.GatewayAddress); err != nil {
return err
}
}

return nil
}

Expand Down Expand Up @@ -108,3 +115,27 @@ func Teardown() error {
}
return nil
}

// Validates that gateway is a valid IPv4 address and that the last octet is “2”.
// Lima uses the last octet as 2 for gateways.
func validateGatewayAddress(gateway string) error {
ip := net.ParseIP(gateway)
if ip == nil {
return fmt.Errorf("gateway %q is not a valid IP address", gateway)
}
ip4 := ip.To4()
if ip4 == nil {
return fmt.Errorf("gateway %q is not IPv4", gateway)
}

parts := strings.Split(gateway, ".")
if len(parts) != 4 {
return fmt.Errorf("gateway %q does not have 4 octets", gateway)
}

if parts[3] != "2" {
return fmt.Errorf("the last octet of gateway %q is not 2", gateway)
}

return nil
}
9 changes: 9 additions & 0 deletions embedded/defaults/colima.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -107,6 +107,15 @@ network:
# Default: false
hostAddresses: false

# Custom gateway address for the virtual machine.
# The last octet needs to be 2.
#
# EXAMPLE
# gatewayAddress: 192.168.10.2
#
# Default: 192.168.5.2
gatewayAddress: 192.168.5.2

# ===================================================================== #
# ADVANCED CONFIGURATION
# ===================================================================== #
Expand Down
21 changes: 14 additions & 7 deletions environment/vm/lima/dns.go
Original file line number Diff line number Diff line change
Expand Up @@ -9,15 +9,10 @@ import (
)

const (
localhostAddr = "127.0.0.1"
gatewayAddr = "192.168.5.2"
localhostAddr = "127.0.0.1"
defaultGatewayAddress = "192.168.5.2"
)

var dnsHosts = map[string]string{
"host.docker.internal": gatewayAddr,
"host.lima.internal": gatewayAddr,
}

func hasDnsmasq(l *limaVM) bool {
// check if dnsmasq is installed
return l.RunQuiet("sh", "-c", `apt list | grep 'dnsmasq\/' | grep '\[installed'`) == nil
Expand All @@ -30,6 +25,18 @@ func (l *limaVM) setupDNS(conf config.Config) error {
return nil
}

// use custom gateway address
var gatewayAddr = defaultGatewayAddress
customGatewayAddress := conf.Network.GatewayAddress
if customGatewayAddress != "" {
gatewayAddr = customGatewayAddress
}

var dnsHosts = map[string]string{
"host.docker.internal": gatewayAddr,
"host.lima.internal": gatewayAddr,
}

internalIP := limautil.InternalIPAddress(config.CurrentProfile().ID)

// extra dns entries
Expand Down
5 changes: 3 additions & 2 deletions environment/vm/lima/lima.go
Original file line number Diff line number Diff line change
Expand Up @@ -111,7 +111,8 @@ func (l *limaVM) Start(ctx context.Context, conf config.Config) error {
return yamlutil.WriteYAML(l.limaConf, confFile)
})

a.Add(l.writeNetworkFile)
a.Add(func() error { return l.writeNetworkFile(conf) })

a.Add(func() error {
return l.host.Run(limactl, "start", "--tty=false", confFile)
})
Expand Down Expand Up @@ -166,7 +167,7 @@ func (l *limaVM) resume(ctx context.Context, conf config.Config) error {
return err
})

a.Add(l.writeNetworkFile)
a.Add(func() error { return l.writeNetworkFile(conf) })

a.Stage("starting")
a.Add(func() error {
Expand Down
12 changes: 12 additions & 0 deletions environment/vm/lima/limautil/network.go
Original file line number Diff line number Diff line change
Expand Up @@ -51,3 +51,15 @@ func getIPAddress(profileID, interfaceName string) string {
_ = cmd.Run()
return strings.TrimSpace(buf.String())
}

type LimaNetworkConfig struct {
Mode string `yaml:"mode"`
Gateway string `yaml:"gateway"`
Netmask string `yaml:"netmask"`
}

type LimaNetwork struct {
Networks struct {
UserV2 LimaNetworkConfig `yaml:"user-v2"`
} `yaml:"networks"`
}
20 changes: 19 additions & 1 deletion environment/vm/lima/network.go
Original file line number Diff line number Diff line change
Expand Up @@ -11,15 +11,33 @@ import (
"github.com/abiosoft/colima/environment/vm/lima/limautil"
"github.com/abiosoft/colima/util"
"github.com/sirupsen/logrus"
"gopkg.in/yaml.v3"
)

func (l *limaVM) writeNetworkFile() error {
func (l *limaVM) writeNetworkFile(conf config.Config) error {
networkFile := limautil.NetworkFile()
embeddedFile, err := embedded.Read("network/networks.yaml")
if err != nil {
return fmt.Errorf("error reading embedded network config file: %w", err)
}

// use custom gateway address
gatewayAddress := conf.Network.GatewayAddress
if gatewayAddress != "" {
var cfg limautil.LimaNetwork
if err := yaml.Unmarshal(embeddedFile, &cfg); err != nil {
return fmt.Errorf("error unmarshalling the `networks.yaml` file: %w", err)
}

cfg.Networks.UserV2.Gateway = gatewayAddress

out, err := yaml.Marshal(&cfg)
if err != nil {
return fmt.Errorf("error marshalling the `networks.yaml` file: %w", err)
}
embeddedFile = out
}

// if there are no running instances, clear network directory
if instances, err := limautil.RunningInstances(); err == nil && len(instances) == 0 {
if err := os.RemoveAll(limautil.NetworkAssetsDirectory()); err != nil {
Expand Down