Skip to content

Handle multiple IP addresses#1366

Closed
Nevon wants to merge 2 commits intoabiosoft:mainfrom
Nevon:handle-multiple-addresses
Closed

Handle multiple IP addresses#1366
Nevon wants to merge 2 commits intoabiosoft:mainfrom
Nevon:handle-multiple-addresses

Conversation

@Nevon
Copy link
Contributor

@Nevon Nevon commented Aug 5, 2025

I'm opening this mostly for the sake of discussion. I'm not sure if this is the right decision to make.

A network interface can have more than one address assigned. Currently, colima kind of assumes that the interface will only have one address. When getting the IP address from the col0 interface, if that interface has more than one address assigned, the returned string will be something like: 192.168.105.3\n192.168.105.2. You can see this in the output of for example colima list where the second IP breaks the line and appears visually in the first column of the table:

PROFILE    STATUS     ARCH       CPUS    MEMORY    DISK      RUNTIME       ADDRESS
default    Running    aarch64    3       8GiB      100GiB    docker+k3s    192.168.105.3
192.168.105.2

In the JSON output, the ip_address field will be a string with the value "192.168.105.3\n192.168.105.2".

This PR changes two things:

  1. Return a list of IPs rather than a single IP. In the plain text output this will be rendered as 192.168.105.3, 192.168.105.2. This changes the JSON output of ip_address from string to []string.
  2. Return an explicit error when trying to install k3s with multiple IPs assigned to the interface (see K3S install fails when network interface has multiple addresses #1362 (comment)). This might not be the right idea, but we need to somehow pick an address to use for --advertised-address.


w := tabwriter.NewWriter(cmd.OutOrStdout(), 4, 8, 4, ' ', 0)
_, _ = fmt.Fprintln(w, "PROFILE\tSTATUS\tARCH\tCPUS\tMEMORY\tDISK\tRUNTIME\tADDRESS")
_, _ = fmt.Fprintln(w, "PROFILE\tSTATUS\tARCH\tCPUS\tMEMORY\tDISK\tRUNTIME\tADDRESSES")
Copy link
Owner

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I think I would prefer to leave the wording as singular.

if status.IPAddress != "" {
log.Println("address:", status.IPAddress)
if len(status.IPAddress) > 0 {
log.Println("addresses:", strings.Join(status.IPAddress, ", "))
Copy link
Owner

@abiosoft abiosoft Aug 5, 2025

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I prefer the singular wording here.

Comment on lines +18 to +29
ips := limautil.IPAddress(config.CurrentProfile().ID)
masterAddress := c.guest.Get(masterAddressKey)

var ip string
for _, addr := range ips {
if addr != masterAddress {
ip = addr
break
}
}

if ip == "" {
Copy link
Owner

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Sorry for the lack of code comment.

What is being done here is to prevent provisioning the kubeconfig when it is already done. If the value was previously set, the provisioning is ignored. i.e. same IP address, no need for an update.

Suggested change
ips := limautil.IPAddress(config.CurrentProfile().ID)
masterAddress := c.guest.Get(masterAddressKey)
var ip string
for _, addr := range ips {
if addr != masterAddress {
ip = addr
break
}
}
if ip == "" {
ips := limautil.IPAddress(config.CurrentProfile().ID)
masterAddress := c.guest.Get(masterAddressKey)
for _, addr := range ips {
if addr == masterAddress {

The logic should be that if any of the ips matches masterAddress, there should be a return.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Gotcha. The question though is what to do if we have multiple IPs. Currently the config provisioning assumes that there will be just one IP.

Copy link
Owner

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

That's why I'm considering introducing an optional --k3s-advertise-address flag.
The other option would be to inspect the k3s args and deduce the address from there (if set).

Comment on lines +49 to +53
output := strings.TrimSpace(buf.String())
if output == "" {
return []string{}
}
return strings.Split(output, "\n")
Copy link
Owner

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This should handle it.

Suggested change
output := strings.TrimSpace(buf.String())
if output == "" {
return []string{}
}
return strings.Split(output, "\n")
return strings.Fields(buf.String())

@abiosoft
Copy link
Owner

abiosoft commented Aug 5, 2025

Thanks for this.

Kindly attend to the code suggestions and the conflict and we should be good to go.

if status.IPAddress != "" {
log.Println("address:", status.IPAddress)
if len(status.IPAddress) > 0 {
log.Println("addresses:", strings.Join(status.IPAddress, ", "))
Copy link
Owner

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested change
log.Println("addresses:", strings.Join(status.IPAddress, ", "))
log.Println("address:", strings.Join(status.IPAddress, ", "))


w := tabwriter.NewWriter(cmd.OutOrStdout(), 4, 8, 4, ' ', 0)
_, _ = fmt.Fprintln(w, "PROFILE\tSTATUS\tARCH\tCPUS\tMEMORY\tDISK\tRUNTIME\tADDRESS")
_, _ = fmt.Fprintln(w, "PROFILE\tSTATUS\tARCH\tCPUS\tMEMORY\tDISK\tRUNTIME\tADDRESSES")
Copy link
Owner

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested change
_, _ = fmt.Fprintln(w, "PROFILE\tSTATUS\tARCH\tCPUS\tMEMORY\tDISK\tRUNTIME\tADDRESSES")
_, _ = fmt.Fprintln(w, "PROFILE\tSTATUS\tARCH\tCPUS\tMEMORY\tDISK\tRUNTIME\tADDRESS")

@Nevon
Copy link
Contributor Author

Nevon commented Aug 5, 2025

With the merge of #1365 I think it's no longer appropriate to produce an error from the k3s cluster install when there are multiple IPs assigned to the interface, since you can now make it work with --k3s-arg="--advertise-address=$IP" --k3s-arg="--node-ip=$IP"

@abiosoft
Copy link
Owner

abiosoft commented Aug 6, 2025

With the merge of #1365 I think it's no longer appropriate to produce an error from the k3s cluster install when there are multiple IPs assigned to the interface, since you can now make it work with --k3s-arg="--advertise-address=$IP" --k3s-arg="--node-ip=$IP"

Yeah, that is accurate.

@Nevon
Copy link
Contributor Author

Nevon commented Aug 8, 2025

I'm going to close this PR for now. I think the user interface for when there are multiple IPs probably needs to be thought through a bit first.

I've solved my own problem by not using assigning a fixed IP when creating a Colima instance with kubernetes enabled, so I don't really have a strong need for this anymore. If someone else has that need and wants to finish it up they're welcome to use this code or not.

@Nevon Nevon closed this Aug 8, 2025
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants