@@ -6,8 +6,10 @@ package cmd
6
6
7
7
import (
8
8
"context"
9
+ "crypto/tls"
9
10
"fmt"
10
11
"net"
12
+ "net/http"
11
13
"strconv"
12
14
"strings"
13
15
"time"
@@ -164,7 +166,7 @@ func (r *PodReconciler) Reconcile(ctx context.Context, req reconcile.Request) (r
164
166
component string
165
167
labelToUpdate string
166
168
167
- waitTimeout time.Duration = 1 * time .Second
169
+ waitTimeout time.Duration = 5 * time .Second
168
170
)
169
171
170
172
switch {
@@ -173,8 +175,6 @@ func (r *PodReconciler) Reconcile(ctx context.Context, req reconcile.Request) (r
173
175
labelToUpdate = fmt .Sprintf (registryFacadeLabel , namespace )
174
176
ipAddress = pod .Status .HostIP
175
177
port = strconv .Itoa (registryFacadePort )
176
- // wait for kube-proxy sync to avoid connection refused due to missing nodeport rules
177
- waitTimeout = 15 * time .Second
178
178
case strings .HasPrefix (pod .Name , wsDaemon ):
179
179
component = wsDaemon
180
180
labelToUpdate = fmt .Sprintf (wsdaemonLabel , namespace )
@@ -206,14 +206,13 @@ func (r *PodReconciler) Reconcile(ctx context.Context, req reconcile.Request) (r
206
206
207
207
if ! IsPodReady (& pod ) {
208
208
// not ready. Wait until the next update.
209
- log .WithField ("pod" , pod .Name ).Info ("pod is not yet ready" )
210
209
return reconcile.Result {}, nil
211
210
}
212
211
213
212
var node corev1.Node
214
213
err = r .Get (ctx , types.NamespacedName {Name : nodeName }, & node )
215
214
if err != nil {
216
- return reconcile.Result {}, fmt .Errorf ("failed to get node %s: %w" , nodeName , err )
215
+ return reconcile.Result {}, fmt .Errorf ("obtaining node %s: %w" , nodeName , err )
217
216
}
218
217
219
218
if node .Labels [labelToUpdate ] == "true" {
@@ -223,7 +222,14 @@ func (r *PodReconciler) Reconcile(ctx context.Context, req reconcile.Request) (r
223
222
224
223
err = waitForTCPPortToBeReachable (ipAddress , port , 30 * time .Second )
225
224
if err != nil {
226
- return reconcile.Result {}, fmt .Errorf ("Unexpected error waiting for probe URL: %v" , err )
225
+ return reconcile.Result {}, fmt .Errorf ("waiting for TCP port: %v" , err )
226
+ }
227
+
228
+ if component == registryFacade {
229
+ err = waitForRegistryFacade (ipAddress , port , 30 * time .Second )
230
+ if err != nil {
231
+ return reconcile.Result {}, fmt .Errorf ("waiting for registry-facade: %v" , err )
232
+ }
227
233
}
228
234
229
235
time .Sleep (waitTimeout )
@@ -299,3 +305,62 @@ func waitForTCPPortToBeReachable(host string, port string, timeout time.Duration
299
305
}
300
306
}
301
307
}
308
+
309
+ func waitForRegistryFacade (host , port string , timeout time.Duration ) error {
310
+ ctx , cancel := context .WithTimeout (context .Background (), timeout )
311
+ defer cancel ()
312
+
313
+ ticker := time .NewTicker (1 * time .Second )
314
+ defer ticker .Stop ()
315
+
316
+ transport := newDefaultTransport ()
317
+ transport .TLSClientConfig = & tls.Config {
318
+ InsecureSkipVerify : true ,
319
+ }
320
+
321
+ client := & http.Client {
322
+ Transport : transport ,
323
+ }
324
+
325
+ dummyURL := fmt .Sprintf ("https://%v:%v/v2/remote/not-a-valid-image/manifests/latest" , host , port )
326
+
327
+ for {
328
+ select {
329
+ case <- ctx .Done ():
330
+ return fmt .Errorf ("port %v on host %v never reachable" , port , host )
331
+ case <- ticker .C :
332
+ req , err := http .NewRequest (http .MethodGet , dummyURL , nil )
333
+ if err != nil {
334
+ log .WithError (err ).Error ("unexpected error building HTTP request" )
335
+ continue
336
+ }
337
+
338
+ req .Header .Set ("Accept" , "application/vnd.oci.image.manifest.v1+json, application/vnd.oci.image.index.v1+json" )
339
+ resp , err := client .Do (req )
340
+ if err != nil {
341
+ log .WithError (err ).Error ("unexpected error during HTTP request" )
342
+ continue
343
+ }
344
+ resp .Body .Close ()
345
+
346
+ if resp .StatusCode == http .StatusNotFound {
347
+ return nil
348
+ }
349
+ }
350
+ }
351
+ }
352
+
353
+ func newDefaultTransport () * http.Transport {
354
+ return & http.Transport {
355
+ DialContext : (& net.Dialer {
356
+ Timeout : 1 * time .Second ,
357
+ KeepAlive : 1 * time .Second ,
358
+ DualStack : false ,
359
+ }).DialContext ,
360
+ MaxIdleConns : 0 ,
361
+ MaxIdleConnsPerHost : 1 ,
362
+ IdleConnTimeout : 5 * time .Second ,
363
+ ExpectContinueTimeout : 5 * time .Second ,
364
+ DisableKeepAlives : true ,
365
+ }
366
+ }
0 commit comments