Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

OpenStack single-stack IPv6 support #1909

Draft
wants to merge 4 commits into
base: main
Choose a base branch
from

Conversation

yasminvalim
Copy link
Contributor

@yasminvalim yasminvalim commented Jul 15, 2024

In #1897 issue, we are requested to create support for IPv6 so Ignition can fetch the metadata in single-stack environments.

To achieve this, we added a new URL with the IPv6 endpoint. We also created logic to first attempt the IPv4 endpoint so If this fails, it will try the IPv6 one. If both endpoints fail, it will return the appropriate error.

@yasminvalim yasminvalim self-assigned this Jul 15, 2024
@yasminvalim yasminvalim marked this pull request as draft July 15, 2024 21:01
@yasminvalim yasminvalim force-pushed the openstack-support branch 2 times, most recently from 9e7cba8 to 87e4a48 Compare July 16, 2024 18:30
@travier
Copy link
Member

travier commented Jul 17, 2024

Not sure that will work. What happens if the instance is IPv6 only? Do requests fail differently than if the network is not up yet?

@travier
Copy link
Member

travier commented Jul 17, 2024

One of the principle behind Ignition is that it will retry indefinitely until the server explicitly returns an error.

@yasminvalim
Copy link
Contributor Author

Not sure that will work. What happens if the instance is IPv6 only? Do requests fail differently than if the network is not up yet?

I updated my code logic. In an IPv6-only instance, IPv4 will fail because it's not found and the resources will be returned from IPv6. If both fails it will return errors. The error will be handled with a message in dispatch function above. It makes sense?

One thing I need to consider is the possibility of having both IPv4 and IPv6 simultaneously. Is that possible? If yes, I need to handle this case as well.

@yasminvalim
Copy link
Contributor Author

One of the principle behind Ignition is that it will retry indefinitely until the server explicitly returns an error.

Nice. I guess this is being handled in func fetchConfig, right? There is a loop in there like this:

Loop:
	for {
		select {
		case <-ctx.Done():
			break Loop
		case <-errChan:
			dispatchCount--
			if dispatchCount == 0 {
				f.Logger.Info("couldn't fetch config")
				break Loop
			}
		}
	}

	return util.ParseConfig(f.Logger, data)
}

Thanks!

@travier
Copy link
Member

travier commented Jul 22, 2024

One thing I need to consider is the possibility of having both IPv4 and IPv6 simultaneously. Is that possible? If yes, I need to handle this case as well.

Yes, this is very common.

@yasminvalim
Copy link
Contributor Author

One thing I need to consider is the possibility of having both IPv4 and IPv6 simultaneously. Is that possible? If yes, I need to handle this case as well.

Yes, this is very common.

I updated the code to cover this scenarios. So, now the code looks like this:

  • If both endpoints have valid data, the results are combined and returned
    I used append, not sure if is the best approach.

  • If only one endpoint has valid data, that data is returned

  • If both endpoints fail, the appropriate error is returned with logs

  • If both endpoints return resource.ErrNotFound, the function returns nil

These should be the basic scenarios. Now, I'm working on running my code in the OpenStack environment and reading the necessary docs to test it correctly.

Thanks for reviewing and helping me with this task!

Copy link

@MaysaMacedo MaysaMacedo left a comment

Choose a reason for hiding this comment

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

Something to take into consideration:

Scheme: "http",
Host: "169.254.169.254",
Path: "openstack/latest/user_data",
}
ipv6MetadataServiceUrl = url.URL{
Scheme: "http",
Host: "[fe80::a9fe:a9fe]",

Choose a reason for hiding this comment

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

}
ipv6MetadataServiceUrl = url.URL{
Scheme: "http",
Host: fmt.Sprintf("[fe80::a9fe:a9fe%%%s]", url.PathEscape(iface)),
Copy link
Member

Choose a reason for hiding this comment

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

Maybe we need to change to [fe80::a9fe:a9fe%25%s] refer to https://docs.openstack.org/nova/latest/user/metadata.html#the-metadata-service

@yasminvalim yasminvalim force-pushed the openstack-support branch 3 times, most recently from f2979b8 to fa50682 Compare October 16, 2024 22:35
@yasminvalim yasminvalim force-pushed the openstack-support branch 5 times, most recently from e105dea to 1569e4c Compare January 6, 2025 13:46
Scheme: "http",
Host: "169.254.169.254",
Path: "openstack/latest/user_data",
}
metadataServiceUrlIPv6 = url.URL{
Scheme: "http",
Host: "fe80::a9fe:a9fe%",
Copy link
Collaborator

Choose a reason for hiding this comment

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

Have you tried having the host be [fe90::a9fe:a9fe%]? since you are getting an error on fetch due to improper escaping ?

Choose a reason for hiding this comment

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

I agree with @prestist . Looks like you're missing to enclose the host in square brackets.
At least it's documented here.
Maybe you will also need to add the interface name to the host once you have it, before calling FetchToBuffer

@yasminvalim
Copy link
Contributor Author

Hey team, I'm experiencing an error while trying to connect the server. I added some log to the code, then I ran openstack console log show <server-id> command and received the following:

[   18.648461] NetworkManager[808]: <info>  [1738700037.3670] dhcp6 (enp3s0): state changed new lease, address=fd2e:6f44:5dd8:c957::1bd
[   24.819235] ignition[918]: GET result: OK
[   24.826066] ignition[918]: failed to fetch config from metadata service: IPv4 succeeded, but IPv6 failed: parse "http://fe80::a9fe:a9fe%25/openstack/latest/user_data": invalid port ":a9fe%25" after host
[   24.852271] ignition[918]: Successfully fetched configuration from IPv4.
[   24.862505] ignition[918]: Fetching IPv6 address for metadata service...
[   24.872374] ignition[918]: Fetching zone id...
[   24.879246] ignition[918]: Checking interface: lo
[   24.886322] ignition[918]: Checking interface: enp3s0
[   24.893800] ignition[918]: Verificando se o IP �� IPv6: 10.1.0.179, resultado: false
[   24.904868] ignition[918]: Verificando se o IP �� IPv6: fd2e:6f44:5dd8:c957::1bd, resultado: true
[   24.917265] ignition[918]: Active interface found: enp3s0
[   24.925264] ignition[918]: Fetching from IPv6 metadata service at http://[fe80::a9fe:a9fe%%25enp3s0]/openstack/latest/user_data...
[   24.941718] ignition[918]: Fetching from IPv6 metadata service at http://fe80::a9fe:a9fe%25/openstack/latest/user_data...
[   24.960088] ignition[918]: IPv6 metadata service failed: parse "http://fe80::a9fe:a9fe%25/openstack/latest/user_data": invalid port ":a9fe%25" after host

Not sure why is not parsing correctly.

@yasminvalim
Copy link
Contributor Author

yasminvalim commented Feb 6, 2025

Mobbing session output:

We utilized an OpenStack environment to fetch and curl the IPv6, but were unable to get a result. Here are the logs:

[cloud-user@jcapitao-cs9-metadata-test ~]$ ip a
1: lo: <LOOPBACK,UP,LOWER_UP> mtu 65536 qdisc noqueue state UNKNOWN group default qlen 1000
	link/loopback 00:00:00:00:00:00 brd 00:00:00:00:00:00
	inet 127.0.0.1/8 scope host lo
   	valid_lft forever preferred_lft forever
	inet6 ::1/128 scope host
   	valid_lft forever preferred_lft forever
2: eth0: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1500 qdisc fq_codel state UP group default qlen 1000
	link/ether fa:16:3e:1f:f8:90 brd ff:ff:ff:ff:ff:ff
	altname enp0s3
	altname ens3
	inet 10.0.79.79/23 brd 10.0.79.255 scope global dynamic noprefixroute eth0
   	valid_lft 41025sec preferred_lft 41025sec
	inet6 2620:52:0:4e:f816:3eff:fe1f:f890/64 scope global dynamic noprefixroute
   	valid_lft 2591943sec preferred_lft 604743sec
	inet6 fe80::f816:3eff:fe1f:f890/64 scope link noprefixroute
   	valid_lft forever preferred_lft forever
[cloud-user@jcapitao-cs9-metadata-test ~]$ curl http://169.254.169.254/openstack/
2012-08-10
2013-04-04
2013-10-17
2015-10-15
2016-06-30
2016-10-06
2017-02-22
2018-08-27
2020-10-14
latest[cloud-user@jcapitao-cs9-metadata-test ~]$
[cloud-user@jcapitao-cs9-metadata-test ~]$ curl -v -g -6 'http://[fe80::a9fe:a9fe%25eth0]'
*   Trying fe80::a9fe:a9fe:80...
#... timeouts.

[EDIT] I was able to reproduce this commands in other machine and worked. It might be a older openstack version, since IPV6 support only came after Victoria release.

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.

5 participants