Skip to content

Commit 9374278

Browse files
committed
sys-apps/ignition: support IPv4 and IPv6
Signed-off-by: Mathieu Tortuyaux <[email protected]>
1 parent 9da0017 commit 9374278

File tree

3 files changed

+224
-0
lines changed

3 files changed

+224
-0
lines changed
Lines changed: 223 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,223 @@
1+
From d99fea1ad2acf1154e0a7b80c5c915458da59990 Mon Sep 17 00:00:00 2001
2+
From: Mathieu Tortuyaux <[email protected]>
3+
Date: Fri, 11 Apr 2025 16:05:31 +0200
4+
Subject: [PATCH 1/4] url: support both IPv4 and IPv6
5+
6+
This defines a wrapper that will try in paralell both IPv4 and IPv6 when
7+
the provider declares those two IPs.
8+
9+
Signed-off-by: Mathieu Tortuyaux <[email protected]>
10+
---
11+
internal/resource/url.go | 65 ++++++++++++++++++++++++++++++++++++++++
12+
1 file changed, 65 insertions(+)
13+
14+
diff --git a/internal/resource/url.go b/internal/resource/url.go
15+
index 4d7a895d..a20aa6ca 100644
16+
--- a/internal/resource/url.go
17+
+++ b/internal/resource/url.go
18+
@@ -36,9 +36,13 @@ import (
19+
configErrors "github.com/flatcar/ignition/v2/config/shared/errors"
20+
"github.com/flatcar/ignition/v2/internal/log"
21+
"github.com/flatcar/ignition/v2/internal/util"
22+
+ "github.com/coreos/vcontext/report"
23+
"golang.org/x/oauth2/google"
24+
"google.golang.org/api/option"
25+
26+
+ "github.com/flatcar/ignition/v2/config/v3_6_experimental/types"
27+
+ providersUtil "github.com/flatcar/ignition/v2/internal/providers/util"
28+
+
29+
"github.com/Azure/azure-sdk-for-go/sdk/azidentity"
30+
"github.com/Azure/azure-sdk-for-go/sdk/storage/azblob"
31+
"github.com/aws/aws-sdk-go/aws"
32+
@@ -52,6 +56,11 @@ import (
33+
"github.com/vincent-petithory/dataurl"
34+
)
35+
36+
+const (
37+
+ IPv4 = "ipv4"
38+
+ IPv6 = "ipv6"
39+
+)
40+
+
41+
var (
42+
ErrSchemeUnsupported = errors.New("unsupported source scheme")
43+
ErrPathNotAbsolute = errors.New("path is not absolute")
44+
@@ -725,3 +734,59 @@ func (f *Fetcher) parseARN(arnURL string) (string, string, string, string, error
45+
key := strings.Join(urlSplit[1:], "/")
46+
return bucket, key, "", regionHint, nil
47+
}
48+
+
49+
+// FetchConfigDualStack is a function that takes care of fetching Ignition configuration on systems where IPv4 only, IPv6 only or both are available.
50+
+// From a high level point of view, this function will try to fetch in parallel Ignition configuration from IPv4 and/or IPv6 - if both endpoints are available, it will
51+
+// return the first configuration successfully fetched.
52+
+func FetchConfigDualStack(f *Fetcher, userdataURLs map[string]url.URL, fetchConfig func(*Fetcher, url.URL) ([]byte, error)) (types.Config, report.Report, error) {
53+
+ ctx, cancel := context.WithCancel(context.Background())
54+
+ defer cancel()
55+
+
56+
+ var (
57+
+ err error
58+
+ nbErrors int
59+
+ )
60+
+
61+
+ // cfg holds the configuration for a given IP
62+
+ cfg := make(map[url.URL][]byte)
63+
+
64+
+ // success hold the IP of the first successful configuration fetching
65+
+ success := make(chan url.URL, 1)
66+
+ errors := make(chan error, 2)
67+
+
68+
+ fetch := func(ctx context.Context, ip url.URL) {
69+
+ d, e := fetchConfig(f, ip)
70+
+ if e != nil {
71+
+ f.Logger.Err("fetching configuration for %s: %v", ip.String(), e)
72+
+ err = e
73+
+ errors <- e
74+
+ } else {
75+
+ cfg[ip] = d
76+
+ success <- ip
77+
+ }
78+
+ }
79+
+
80+
+ if ipv4, ok := userdataURLs[IPv4]; ok {
81+
+ go fetch(ctx, ipv4)
82+
+ }
83+
+
84+
+ if ipv6, ok := userdataURLs[IPv6]; ok {
85+
+ go fetch(ctx, ipv6)
86+
+ }
87+
+
88+
+ // Now wait for one success. (i.e wait for the first configuration to be available)
89+
+ select {
90+
+ case ip := <-success:
91+
+ f.Logger.Debug("got configuration from: %s", ip.String())
92+
+ return providersUtil.ParseConfig(f.Logger, cfg[ip])
93+
+ case <-errors:
94+
+ nbErrors++
95+
+ if nbErrors == 2 {
96+
+ f.Logger.Debug("all routines have failed to fetch configuration, returning last known error: %v", err)
97+
+ return types.Config{}, report.Report{}, err
98+
+ }
99+
+ }
100+
+
101+
+ // we should never reach this line
102+
+ return types.Config{}, report.Report{}, err
103+
+}
104+
--
105+
2.49.0
106+
107+
From df47f693e82161365c4866c00f9b31c3d7960d85 Mon Sep 17 00:00:00 2001
108+
From: Mathieu Tortuyaux <[email protected]>
109+
Date: Fri, 11 Apr 2025 16:14:33 +0200
110+
Subject: [PATCH 2/4] url: try local port on both IP stacks
111+
112+
Signed-off-by: Mathieu Tortuyaux <[email protected]>
113+
---
114+
internal/resource/url.go | 10 +++++++++-
115+
1 file changed, 9 insertions(+), 1 deletion(-)
116+
117+
diff --git a/internal/resource/url.go b/internal/resource/url.go
118+
index a20aa6ca..c2f4dd50 100644
119+
--- a/internal/resource/url.go
120+
+++ b/internal/resource/url.go
121+
@@ -25,6 +25,7 @@ import (
122+
"io"
123+
"net"
124+
"net/http"
125+
+ "net/netip"
126+
"net/url"
127+
"os"
128+
"strings"
129+
@@ -339,10 +340,17 @@ func (f *Fetcher) fetchFromHTTP(u url.URL, dest io.Writer, opts FetchOptions) er
130+
p int
131+
)
132+
133+
+ host := u.Hostname()
134+
+ addr, _ := netip.ParseAddr(host)
135+
+ network := "tcp6"
136+
+ if addr.Is4() {
137+
+ network = "tcp4"
138+
+ }
139+
+
140+
// Assert that the port is not already used.
141+
for {
142+
p = opts.LocalPort()
143+
- l, err := net.Listen("tcp4", fmt.Sprintf(":%d", p))
144+
+ l, err := net.Listen(network, fmt.Sprintf(":%d", p))
145+
if err != nil && errors.Is(err, syscall.EADDRINUSE) {
146+
continue
147+
} else if err == nil {
148+
--
149+
2.49.0
150+
151+
From 0aeb347397d6bf8f788d181fec1d917c31017a0e Mon Sep 17 00:00:00 2001
152+
From: Mathieu Tortuyaux <[email protected]>
153+
Date: Fri, 11 Apr 2025 16:04:21 +0200
154+
Subject: [PATCH 3/4] scaleway: support IPv4 and IPv6 for metadata endpoint
155+
156+
Signed-off-by: Mathieu Tortuyaux <[email protected]>
157+
---
158+
internal/providers/scaleway/scaleway.go | 28 ++++++++++++++++---------
159+
1 file changed, 18 insertions(+), 10 deletions(-)
160+
161+
diff --git a/internal/providers/scaleway/scaleway.go b/internal/providers/scaleway/scaleway.go
162+
index d25b9aab..d987dc50 100644
163+
--- a/internal/providers/scaleway/scaleway.go
164+
+++ b/internal/providers/scaleway/scaleway.go
165+
@@ -24,28 +24,36 @@ import (
166+
167+
"github.com/flatcar/ignition/v2/config/v3_6_experimental/types"
168+
"github.com/flatcar/ignition/v2/internal/platform"
169+
- "github.com/flatcar/ignition/v2/internal/providers/util"
170+
"github.com/flatcar/ignition/v2/internal/resource"
171+
172+
"github.com/coreos/vcontext/report"
173+
)
174+
175+
var (
176+
- userdataURL = url.URL{
177+
- Scheme: "http",
178+
- Host: "169.254.42.42",
179+
- Path: "user_data/cloud-init",
180+
+ userdataURLs = map[string]url.URL{
181+
+ resource.IPv4: {
182+
+ Scheme: "http",
183+
+ Host: "169.254.42.42",
184+
+ Path: "user_data/cloud-init",
185+
+ },
186+
+ resource.IPv6: {
187+
+ Scheme: "http",
188+
+ Host: "[fd00:42::42]",
189+
+ Path: "user_data/cloud-init",
190+
+ },
191+
}
192+
)
193+
194+
func init() {
195+
platform.Register(platform.Provider{
196+
- Name: "scaleway",
197+
- Fetch: fetchConfig,
198+
+ Name: "scaleway",
199+
+ Fetch: func(f *resource.Fetcher) (types.Config, report.Report, error) {
200+
+ return resource.FetchConfigDualStack(f, userdataURLs, fetchConfig)
201+
+ },
202+
})
203+
}
204+
205+
-func fetchConfig(f *resource.Fetcher) (types.Config, report.Report, error) {
206+
+func fetchConfig(f *resource.Fetcher, userdataURL url.URL) ([]byte, error) {
207+
// For security reason, Scaleway requires to query user data with a source port below 1024.
208+
port := func() int {
209+
return rand.Intn(1022) + 1
210+
@@ -55,8 +63,8 @@ func fetchConfig(f *resource.Fetcher) (types.Config, report.Report, error) {
211+
LocalPort: port,
212+
})
213+
if err != nil && err != resource.ErrNotFound {
214+
- return types.Config{}, report.Report{}, err
215+
+ return nil, err
216+
}
217+
218+
- return util.ParseConfig(f.Logger, data)
219+
+ return data, nil
220+
}
221+
--
222+
2.49.0
223+

sdk_container/src/third_party/coreos-overlay/sys-apps/ignition/ignition-9999.ebuild

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -60,6 +60,7 @@ PATCHES=(
6060
"${FILESDIR}/0018-docs-Add-re-added-platforms-to-docs-to-pass-tests.patch"
6161
"${FILESDIR}/0019-usr-share-oem-oem.patch"
6262
"${FILESDIR}/0020-internal-exec-stages-mount-Mount-oem.patch"
63+
"${FILESDIR}/tormath1-ipv6.patch"
6364
)
6465

6566
src_compile() {

0 commit comments

Comments
 (0)