Skip to content

sys-apps/ignition: support IPv4 and IPv6 #2824

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

Draft
wants to merge 1 commit into
base: main
Choose a base branch
from
Draft
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
Original file line number Diff line number Diff line change
@@ -0,0 +1,200 @@
From 05a301e9aea81b9f8ed54bc81d42e56774647305 Mon Sep 17 00:00:00 2001
From: Mathieu Tortuyaux <[email protected]>
Date: Fri, 11 Apr 2025 16:04:21 +0200
Subject: [PATCH 1/3] scaleway: support IPv4 and IPv6 for metadata endpoint

Signed-off-by: Mathieu Tortuyaux <[email protected]>
---
internal/providers/scaleway/scaleway.go | 28 ++++++++++++++++---------
1 file changed, 18 insertions(+), 10 deletions(-)

diff --git a/internal/providers/scaleway/scaleway.go b/internal/providers/scaleway/scaleway.go
index d25b9aab..d987dc50 100644
--- a/internal/providers/scaleway/scaleway.go
+++ b/internal/providers/scaleway/scaleway.go
@@ -24,28 +24,36 @@ import (

"github.com/flatcar/ignition/v2/config/v3_6_experimental/types"
"github.com/flatcar/ignition/v2/internal/platform"
- "github.com/flatcar/ignition/v2/internal/providers/util"
"github.com/flatcar/ignition/v2/internal/resource"

"github.com/coreos/vcontext/report"
)

var (
- userdataURL = url.URL{
- Scheme: "http",
- Host: "169.254.42.42",
- Path: "user_data/cloud-init",
+ userdataURLs = map[string]url.URL{
+ resource.IPv4: {
+ Scheme: "http",
+ Host: "169.254.42.42",
+ Path: "user_data/cloud-init",
+ },
+ resource.IPv6: {
+ Scheme: "http",
+ Host: "[fd00:42::42]",
+ Path: "user_data/cloud-init",
+ },
}
)

func init() {
platform.Register(platform.Provider{
- Name: "scaleway",
- Fetch: fetchConfig,
+ Name: "scaleway",
+ Fetch: func(f *resource.Fetcher) (types.Config, report.Report, error) {
+ return resource.FetchConfigDualStack(f, userdataURLs, fetchConfig)
+ },
})
}

-func fetchConfig(f *resource.Fetcher) (types.Config, report.Report, error) {
+func fetchConfig(f *resource.Fetcher, userdataURL url.URL) ([]byte, error) {
// For security reason, Scaleway requires to query user data with a source port below 1024.
port := func() int {
return rand.Intn(1022) + 1
@@ -55,8 +63,8 @@ func fetchConfig(f *resource.Fetcher) (types.Config, report.Report, error) {
LocalPort: port,
})
if err != nil && err != resource.ErrNotFound {
- return types.Config{}, report.Report{}, err
+ return nil, err
}

- return util.ParseConfig(f.Logger, data)
+ return data, nil
}
--
2.45.3

From 61f109ac80a18f82705d8d45351bf0da284af778 Mon Sep 17 00:00:00 2001
From: Mathieu Tortuyaux <[email protected]>
Date: Fri, 11 Apr 2025 16:05:31 +0200
Subject: [PATCH 2/3] url: support both IPv4 and IPv6

This defines a wrapper that will try in paralell both IPv4 and IPv6 when
the provider declares those two IPs.

Signed-off-by: Mathieu Tortuyaux <[email protected]>
---
internal/resource/url.go | 42 ++++++++++++++++++++++++++++++++++++++++
1 file changed, 42 insertions(+)

diff --git a/internal/resource/url.go b/internal/resource/url.go
index 4d7a895d..c6c01927 100644
--- a/internal/resource/url.go
+++ b/internal/resource/url.go
@@ -36,9 +36,13 @@ import (
configErrors "github.com/flatcar/ignition/v2/config/shared/errors"
"github.com/flatcar/ignition/v2/internal/log"
"github.com/flatcar/ignition/v2/internal/util"
+ "github.com/coreos/vcontext/report"
"golang.org/x/oauth2/google"
"google.golang.org/api/option"

+ "github.com/flatcar/ignition/v2/config/v3_6_experimental/types"
+ providersUtil "github.com/flatcar/ignition/v2/internal/providers/util"
+
"github.com/Azure/azure-sdk-for-go/sdk/azidentity"
"github.com/Azure/azure-sdk-for-go/sdk/storage/azblob"
"github.com/aws/aws-sdk-go/aws"
@@ -52,6 +56,11 @@ import (
"github.com/vincent-petithory/dataurl"
)

+const (
+ IPv4 = "ipv4"
+ IPv6 = "ipv6"
+)
+
var (
ErrSchemeUnsupported = errors.New("unsupported source scheme")
ErrPathNotAbsolute = errors.New("path is not absolute")
@@ -725,3 +734,36 @@ func (f *Fetcher) parseARN(arnURL string) (string, string, string, string, error
key := strings.Join(urlSplit[1:], "/")
return bucket, key, "", regionHint, nil
}
+
+// FetchConfigDualStack is a function that takes care of fetching Ignition configuration on systems where IPv4 only, IPv6 only or both are available.
+func FetchConfigDualStack(f *Fetcher, userdataURLs map[string]url.URL, fetchConfig func(*Fetcher, url.URL) ([]byte, error)) (types.Config, report.Report, error) {
+ var (
+ data []byte
+ err error
+ )
+ success := make(chan string, 1)
+
+ fetch := func(ip url.URL) {
+ data, err = fetchConfig(f, ip)
+ if err != nil {
+ f.Logger.Err("fetching configuration for %s: %v", ip, err)
+ return
+ }
+
+ success <- ip.String()
+ }
+
+ if ipv4, ok := userdataURLs[IPv4]; ok {
+ go fetch(ipv4)
+ }
+
+ if ipv6, ok := userdataURLs[IPv6]; ok {
+ go fetch(ipv6)
+ }
+
+ // Wait for one success. (i.e wait for the first configuration to be available)
+ ip := <-success
+ f.Logger.Debug("got configuration from: %s", ip)
+
+ return providersUtil.ParseConfig(f.Logger, data)
+}
--
2.45.3

From 7558c8ebf09633fc934affa7e80bd925f73d74a8 Mon Sep 17 00:00:00 2001
From: Mathieu Tortuyaux <[email protected]>
Date: Fri, 11 Apr 2025 16:14:33 +0200
Subject: [PATCH 3/3] url: try local port on both IP stacks

Signed-off-by: Mathieu Tortuyaux <[email protected]>
---
internal/resource/url.go | 10 +++++++++-
1 file changed, 9 insertions(+), 1 deletion(-)

diff --git a/internal/resource/url.go b/internal/resource/url.go
index c6c01927..9a39c14f 100644
--- a/internal/resource/url.go
+++ b/internal/resource/url.go
@@ -25,6 +25,7 @@ import (
"io"
"net"
"net/http"
+ "net/netip"
"net/url"
"os"
"strings"
@@ -339,10 +340,17 @@ func (f *Fetcher) fetchFromHTTP(u url.URL, dest io.Writer, opts FetchOptions) er
p int
)

+ host := u.Hostname()
+ addr, _ := netip.ParseAddr(host)
+ network := "tcp6"
+ if addr.Is4() {
+ network = "tcp4"
+ }
+
// Assert that the port is not already used.
for {
p = opts.LocalPort()
- l, err := net.Listen("tcp4", fmt.Sprintf(":%d", p))
+ l, err := net.Listen(network, fmt.Sprintf(":%d", p))
if err != nil && errors.Is(err, syscall.EADDRINUSE) {
continue
} else if err == nil {
--
2.45.3

Original file line number Diff line number Diff line change
Expand Up @@ -60,6 +60,7 @@ PATCHES=(
"${FILESDIR}/0018-docs-Add-re-added-platforms-to-docs-to-pass-tests.patch"
"${FILESDIR}/0019-usr-share-oem-oem.patch"
"${FILESDIR}/0020-internal-exec-stages-mount-Mount-oem.patch"
"${FILESDIR}/tormath1-ipv6.patch"
)

src_compile() {
Expand Down
Loading