1
1
package release
2
2
3
3
import (
4
- "archive/tar"
5
4
"bytes"
6
5
"context"
7
6
"encoding/json"
8
7
"fmt"
9
8
"io"
10
9
"os"
11
- "path"
12
10
"path/filepath"
13
11
"sync"
14
12
"time"
@@ -20,11 +18,13 @@ import (
20
18
21
19
"k8s.io/apimachinery/pkg/apis/meta/v1/unstructured"
22
20
"k8s.io/apimachinery/pkg/runtime/schema"
21
+ "k8s.io/apimachinery/pkg/util/sets"
23
22
"k8s.io/cli-runtime/pkg/genericiooptions"
24
23
"k8s.io/client-go/rest"
25
24
kcmdutil "k8s.io/kubectl/pkg/cmd/util"
26
25
"k8s.io/kubectl/pkg/util/templates"
27
26
27
+ configv1 "github.com/openshift/api/config/v1"
28
28
imagev1 "github.com/openshift/api/image/v1"
29
29
"github.com/openshift/library-go/pkg/image/dockerv1client"
30
30
"github.com/openshift/library-go/pkg/manifest"
@@ -349,17 +349,16 @@ func (o *ExtractOptions) Run(ctx context.Context) error {
349
349
}
350
350
}
351
351
352
- tarEntryCallbacks := []extract. TarEntryFunc {}
352
+ var manifestsCallbacks []func ( string , []manifest. Manifest , io. Reader , []configv1. ClusterVersionCapability ) ( bool , error )
353
353
354
- var manifestErrs []error
354
+ var waitAll bool
355
+ inclusionConfig := manifestInclusionConfiguration {}
355
356
if o .ExtractManifests {
356
357
expectedProviderSpecKind := credRequestCloudProviderSpecKindMapping [o .Cloud ]
357
-
358
- include := func (m * manifest.Manifest ) error { return nil } // default to including everything
359
358
if o .Included {
360
359
context := "connected cluster"
361
- inclusionConfig := manifestInclusionConfiguration {}
362
360
if o .InstallConfig == "" {
361
+ waitAll = true
363
362
inclusionConfig , err = findClusterIncludeConfig (ctx , o .RESTConfig )
364
363
} else {
365
364
inclusionConfig , err = findClusterIncludeConfigFromInstallConfig (ctx , o .InstallConfig )
@@ -377,11 +376,10 @@ func (o *ExtractOptions) Run(ctx context.Context) error {
377
376
return fmt .Errorf ("unrecognized platform for CredentialsRequests: %q" , * inclusionConfig .Platform )
378
377
}
379
378
}
380
- include = newIncluder (inclusionConfig )
381
379
}
382
380
383
- tarEntryCallbacks = append (tarEntryCallbacks , func (hdr * tar. Header , _ extract. LayerInfo , r io.Reader ) (bool , error ) {
384
- if hdr . Name == "image-references" && ! o .CredentialsRequests {
381
+ manifestsCallbacks = append (manifestsCallbacks , func (name string , ms []manifest. Manifest , r io.Reader , enabled []configv1. ClusterVersionCapability ) (cont bool , err error ) {
382
+ if name == "image-references" && ! o .CredentialsRequests {
385
383
buf := & bytes.Buffer {}
386
384
if _ , err := io .Copy (buf , r ); err != nil {
387
385
return false , fmt .Errorf ("unable to load image-references from release payload: %w" , err )
@@ -399,7 +397,7 @@ func (o *ExtractOptions) Run(ctx context.Context) error {
399
397
400
398
out := o .Out
401
399
if o .Directory != "" {
402
- out , err = os .Create (filepath .Join (o .Directory , hdr . Name ))
400
+ out , err = os .Create (filepath .Join (o .Directory , name ))
403
401
if err != nil {
404
402
return false , err
405
403
}
@@ -409,10 +407,10 @@ func (o *ExtractOptions) Run(ctx context.Context) error {
409
407
return true , err
410
408
}
411
409
return true , nil
412
- } else if hdr . Name == "release-metadata" && ! o .CredentialsRequests {
410
+ } else if name == "release-metadata" && ! o .CredentialsRequests {
413
411
out := o .Out
414
412
if o .Directory != "" {
415
- out , err = os .Create (filepath .Join (o .Directory , hdr . Name ))
413
+ out , err = os .Create (filepath .Join (o .Directory , name ))
416
414
if err != nil {
417
415
return false , err
418
416
}
@@ -424,22 +422,18 @@ func (o *ExtractOptions) Run(ctx context.Context) error {
424
422
return true , nil
425
423
}
426
424
427
- if ext := path .Ext (hdr .Name ); len (ext ) == 0 || ! (ext == ".yaml" || ext == ".yml" || ext == ".json" ) {
428
- return true , nil
429
- }
430
- klog .V (4 ).Infof ("Found manifest %s" , hdr .Name )
431
- ms , err := manifest .ParseManifests (r )
432
- if err != nil {
433
- manifestErrs = append (manifestErrs , errors .Wrapf (err , "error parsing %s" , hdr .Name ))
434
- return true , nil
435
- }
436
-
437
425
for i := len (ms ) - 1 ; i >= 0 ; i -- {
438
426
if o .Included && o .CredentialsRequests && ms [i ].GVK == credentialsRequestGVK && len (ms [i ].Obj .GetAnnotations ()) == 0 {
439
427
klog .V (4 ).Infof ("Including %s for manual CredentialsRequests, despite lack of annotations" , ms [i ].String ())
440
- } else if err := include (& ms [i ]); err != nil {
441
- klog .V (4 ).Infof ("Excluding %s: %s" , ms [i ].String (), err )
442
- ms = append (ms [:i ], ms [i + 1 :]... )
428
+ } else if o .Included {
429
+ clusterVersionCapabilitiesStatus := & configv1.ClusterVersionCapabilitiesStatus {
430
+ KnownCapabilities : append (inclusionConfig .Capabilities .KnownCapabilities , configv1 .KnownClusterVersionCapabilities ... ),
431
+ EnabledCapabilities : append (inclusionConfig .Capabilities .EnabledCapabilities , enabled ... ),
432
+ }
433
+ if err := ms [i ].Include (inclusionConfig .ExcludeIdentifier , inclusionConfig .RequiredFeatureSet , inclusionConfig .Profile , clusterVersionCapabilitiesStatus , inclusionConfig .Overrides ); err != nil {
434
+ klog .V (4 ).Infof ("Excluding %s: %s" , ms [i ].String (), err )
435
+ ms = append (ms [:i ], ms [i + 1 :]... )
436
+ }
443
437
}
444
438
}
445
439
@@ -470,20 +464,20 @@ func (o *ExtractOptions) Run(ctx context.Context) error {
470
464
471
465
out := o .Out
472
466
if o .Directory != "" {
473
- out , err = os .Create (filepath .Join (o .Directory , hdr . Name ))
467
+ out , err = os .Create (filepath .Join (o .Directory , name ))
474
468
if err != nil {
475
- return false , errors .Wrapf (err , "error creating manifest in %s" , hdr . Name )
469
+ return false , errors .Wrapf (err , "error creating manifest in %s" , name )
476
470
}
477
471
}
478
472
if out != nil {
479
473
for _ , m := range manifestsToWrite {
480
474
yamlBytes , err := yaml .JSONToYAML (m .Raw )
481
475
if err != nil {
482
- return false , errors .Wrapf (err , "error serializing manifest in %s" , hdr . Name )
476
+ return false , errors .Wrapf (err , "error serializing manifest in %s" , name )
483
477
}
484
478
fmt .Fprintf (out , "---\n " )
485
479
if _ , err := out .Write (yamlBytes ); err != nil {
486
- return false , errors .Wrapf (err , "error writing manifest in %s" , hdr . Name )
480
+ return false , errors .Wrapf (err , "error writing manifest in %s" , name )
487
481
}
488
482
}
489
483
}
@@ -493,24 +487,23 @@ func (o *ExtractOptions) Run(ctx context.Context) error {
493
487
494
488
fileFound := false
495
489
if o .File != "" {
496
- tarEntryCallbacks = append (tarEntryCallbacks , func (hdr * tar. Header , _ extract. LayerInfo , r io.Reader ) (bool , error ) {
497
- if hdr . Name != o .File {
490
+ manifestsCallbacks = append (manifestsCallbacks , func (name string , _ []manifest. Manifest , r io.Reader , _ []configv1. ClusterVersionCapability ) (bool , error ) {
491
+ if name != o .File {
498
492
return true , nil
499
493
}
500
494
fileFound = true
501
495
_ , err := io .Copy (o .Out , r )
502
496
return false , err
503
497
})
504
498
}
505
-
506
- if len (tarEntryCallbacks ) > 0 {
507
- tarEntryCallbacksDone := make ([]bool , len (tarEntryCallbacks ))
508
- opts .TarEntryCallback = func (hdr * tar.Header , layer extract.LayerInfo , r io.Reader ) (bool , error ) {
509
- for i , callback := range tarEntryCallbacks {
499
+ manifestsCallback := func (name string , ms []manifest.Manifest , r io.Reader , enabled []configv1.ClusterVersionCapability ) (bool , error ) {
500
+ if len (manifestsCallbacks ) > 0 {
501
+ tarEntryCallbacksDone := make ([]bool , len (manifestsCallbacks ))
502
+ for i , callback := range manifestsCallbacks {
510
503
if tarEntryCallbacksDone [i ] {
511
504
continue
512
505
}
513
- if cont , err := callback (hdr , layer , r ); err != nil {
506
+ if cont , err := callback (name , ms , r , enabled ); err != nil {
514
507
return cont , err
515
508
} else if ! cont {
516
509
tarEntryCallbacksDone [i ] = true
@@ -525,8 +518,13 @@ func (o *ExtractOptions) Run(ctx context.Context) error {
525
518
526
519
return false , nil
527
520
}
521
+ return true , nil
528
522
}
529
523
524
+ manifestReceiver := NewManifestReceiver (manifestsCallback , waitAll , sets .New [string ]("image-references" , "release-metadata" ), inclusionConfig )
525
+ opts .TarEntryCallback = manifestReceiver .TarEntryCallback
526
+ opts .TarEntryCallbackDoneCallback = manifestReceiver .TarEntryCallbackDoneCallback
527
+
530
528
if err := opts .Run (); err != nil {
531
529
return err
532
530
}
@@ -553,8 +551,8 @@ func (o *ExtractOptions) Run(ctx context.Context) error {
553
551
554
552
// Only output manifest errors if manifests were being extracted.
555
553
// Do not return an error so current operation, e.g. mirroring, continues.
556
- if o .ExtractManifests && len (manifestErrs ) > 0 {
557
- fmt .Fprintf (o .ErrOut , "Errors: %s\n " , errorList (manifestErrs ))
554
+ if o .ExtractManifests && len (manifestReceiver . ManifestErrs ) > 0 {
555
+ fmt .Fprintf (o .ErrOut , "Errors: %s\n " , errorList (manifestReceiver . ManifestErrs ))
558
556
}
559
557
560
558
return nil
0 commit comments