Skip to content

Commit 867bce8

Browse files
Merge pull request #30007 from neisw/trt-2163-incluster-disruption-images
TRT-2163: incluster disruption images
2 parents 851e33d + 357f954 commit 867bce8

File tree

7 files changed

+143
-115
lines changed

7 files changed

+143
-115
lines changed

pkg/monitortests/kubeapiserver/disruptioninclusterapiserver/monitortest.go

Lines changed: 14 additions & 22 deletions
Original file line numberDiff line numberDiff line change
@@ -1,20 +1,19 @@
11
package disruptioninclusterapiserver
22

33
import (
4-
"bytes"
54
"context"
65
_ "embed"
76
"fmt"
87
"net/url"
9-
"os/exec"
10-
"strings"
118
"time"
129

1310
"github.com/google/uuid"
1411
"github.com/sirupsen/logrus"
1512
utilerrors "k8s.io/apimachinery/pkg/util/errors"
1613

1714
"github.com/openshift/origin/pkg/monitortestlibrary/disruptionlibrary"
15+
"github.com/openshift/origin/pkg/test/extensions"
16+
"github.com/openshift/origin/test/extended/util/payload"
1817
"k8s.io/apimachinery/pkg/labels"
1918
"k8s.io/apimachinery/pkg/selection"
2019

@@ -304,34 +303,27 @@ func (i *InvariantInClusterDisruption) PrepareCollection(ctx context.Context, ad
304303
func (i *InvariantInClusterDisruption) StartCollection(ctx context.Context, adminRESTConfig *rest.Config, _ monitorapi.RecorderWriter) error {
305304
var err error
306305
log := logrus.WithField("monitorTest", "apiserver-incluster-availability").WithField("namespace", i.namespaceName).WithField("func", "StartCollection")
307-
log.Infof("payload image pull spec is %v", i.payloadImagePullSpec)
308306
if len(i.payloadImagePullSpec) == 0 {
309-
configClient, err := configclient.NewForConfig(adminRESTConfig)
307+
i.payloadImagePullSpec, err = extensions.DetermineReleasePayloadImage()
310308
if err != nil {
311309
return err
312310
}
313-
clusterVersion, err := configClient.ConfigV1().ClusterVersions().Get(ctx, "version", metav1.GetOptions{})
314-
if apierrors.IsNotFound(err) {
315-
i.notSupportedReason = "clusterversion/version not found and no image pull spec specified."
311+
312+
if len(i.payloadImagePullSpec) == 0 {
313+
log.Info("unable to determine payloadImagePullSpec")
314+
i.notSupportedReason = "no image pull spec specified."
316315
return nil
317316
}
318-
if err != nil {
319-
return err
320-
}
321-
i.payloadImagePullSpec = clusterVersion.Status.History[0].Image
322317
}
323318

324-
// runImageExtract extracts src from specified image to dst
325-
cmd := exec.Command("oc", "adm", "release", "info", i.payloadImagePullSpec, "--image-for=tests")
326-
out := &bytes.Buffer{}
327-
errOut := &bytes.Buffer{}
328-
cmd.Stdout = out
329-
cmd.Stderr = errOut
330-
if err := cmd.Run(); err != nil {
331-
i.notSupportedReason = fmt.Sprintf("unable to determine openshift-tests image: %v: %v", err, errOut.String())
332-
return nil
319+
log.Infof("payload image pull spec is %s", i.payloadImagePullSpec)
320+
321+
// Extract the openshift-tests image from the release payload
322+
oc := exutil.NewCLIForMonitorTest("default")
323+
i.openshiftTestsImagePullSpec, err = payload.ExtractImageFromReleasePayload(i.payloadImagePullSpec, "tests", oc)
324+
if err != nil {
325+
return fmt.Errorf("unable to determine openshift-tests image: %s: %v", i.payloadImagePullSpec, err)
333326
}
334-
i.openshiftTestsImagePullSpec = strings.TrimSpace(out.String())
335327
log.Infof("openshift-tests image pull spec is %v", i.openshiftTestsImagePullSpec)
336328

337329
i.adminRESTConfig = adminRESTConfig

pkg/monitortests/network/disruptionpodnetwork/monitortest.go

Lines changed: 2 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -91,14 +91,13 @@ func NewPodNetworkAvalibilityInvariant(info monitortestframework.MonitorTestInit
9191
func (pna *podNetworkAvalibility) PrepareCollection(ctx context.Context, adminRESTConfig *rest.Config, recorder monitorapi.RecorderWriter) error {
9292
deploymentID := uuid.New().String()
9393

94-
openshiftTestsImagePullSpec, err := GetOpenshiftTestsImagePullSpec(ctx, adminRESTConfig, pna.payloadImagePullSpec, nil)
94+
oc := util.NewCLIWithoutNamespace("openshift-tests")
95+
openshiftTestsImagePullSpec, err := GetOpenshiftTestsImagePullSpec(ctx, adminRESTConfig, pna.payloadImagePullSpec, oc)
9596
if err != nil {
9697
pna.notSupportedReason = &monitortestframework.NotSupportedError{Reason: fmt.Sprintf("unable to determine openshift-tests image: %v", err)}
9798
return pna.notSupportedReason
9899
}
99100

100-
// Skip on ROSA TRT-1869
101-
oc := util.NewCLIWithoutNamespace("openshift-tests")
102101
isManagedServiceCluster, err := util.IsManagedServiceCluster(ctx, oc.AdminKubeClient())
103102
if isManagedServiceCluster {
104103
pna.notSupportedReason = &monitortestframework.NotSupportedError{Reason: fmt.Sprintf("pod network tests are unschedulable on ROSA TRT-1869")}

pkg/monitortests/network/disruptionpodnetwork/utils.go

Lines changed: 13 additions & 25 deletions
Original file line numberDiff line numberDiff line change
@@ -1,20 +1,20 @@
11
package disruptionpodnetwork
22

33
import (
4-
"bytes"
54
"context"
65
"errors"
76
"fmt"
7+
88
"io/ioutil"
99
"os"
10-
"os/exec"
1110
"strings"
1211
"time"
1312

1413
"github.com/sirupsen/logrus"
1514

16-
configclient "github.com/openshift/client-go/config/clientset/versioned"
15+
"github.com/openshift/origin/pkg/test/extensions"
1716
exutil "github.com/openshift/origin/test/extended/util"
17+
"github.com/openshift/origin/test/extended/util/payload"
1818
apierrors "k8s.io/apimachinery/pkg/api/errors"
1919
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
2020
"k8s.io/client-go/rest"
@@ -24,35 +24,25 @@ import (
2424
// IN ginkgo environment, oc needs to be created before BeforeEach and passed in
2525
func GetOpenshiftTestsImagePullSpec(ctx context.Context, adminRESTConfig *rest.Config, suggestedPayloadImage string, oc *exutil.CLI) (string, error) {
2626
if len(suggestedPayloadImage) == 0 {
27-
configClient, err := configclient.NewForConfig(adminRESTConfig)
28-
if err != nil {
29-
return "", err
30-
}
31-
clusterVersion, err := configClient.ConfigV1().ClusterVersions().Get(ctx, "version", metav1.GetOptions{})
32-
if apierrors.IsNotFound(err) {
33-
return "", fmt.Errorf("clusterversion/version not found and no image pull spec specified")
34-
}
27+
var err error
28+
suggestedPayloadImage, err = extensions.DetermineReleasePayloadImage()
3529
if err != nil {
3630
return "", err
3731
}
38-
suggestedPayloadImage = clusterVersion.Status.History[0].Image
3932
}
4033

4134
logrus.Infof("payload image reported by CV: %v\n", suggestedPayloadImage)
4235
// runImageExtract extracts src from specified image to dst
43-
cmd := exec.Command("oc", "adm", "release", "info", suggestedPayloadImage, "--image-for=tests")
44-
out := &bytes.Buffer{}
45-
outStr := ""
46-
errOut := &bytes.Buffer{}
47-
cmd.Stdout = out
48-
cmd.Stderr = errOut
49-
if err := cmd.Run(); err != nil {
50-
logrus.WithError(err).Errorf("unable to determine openshift-tests image through exec: %v", errOut.String())
36+
37+
// Extract the openshift-tests image from the release payload
38+
openshiftTestsImagePullSpec, err := payload.ExtractImageFromReleasePayload(suggestedPayloadImage, "tests", oc)
39+
if err != nil {
40+
logrus.WithError(err).Errorf("unable to determine openshift-tests image through ExtractImageFromReleasePayload: %v", err)
5141
// Now try the wrapper to see if it makes a difference
5242
if oc == nil {
5343
oc = exutil.NewCLIWithoutNamespace("openshift-tests")
5444
}
55-
outStr, err = oc.Run("adm", "release", "info", suggestedPayloadImage).Args("--image-for=tests").Output()
45+
outStr, err := oc.Run("adm", "release", "info", suggestedPayloadImage).Args("--image-for=tests").Output()
5646
if err != nil {
5747
logrus.WithError(err).Errorf("unable to determine openshift-tests image through oc wrapper with default ps: %v", outStr)
5848

@@ -130,11 +120,9 @@ func GetOpenshiftTestsImagePullSpec(ctx context.Context, adminRESTConfig *rest.C
130120
} else {
131121
logrus.Infof("successfully getting image for test with oc wrapper with default ps: %s\n", outStr)
132122
}
133-
} else {
134-
outStr = out.String()
135-
}
136123

137-
openshiftTestsImagePullSpec := strings.TrimSpace(outStr)
124+
openshiftTestsImagePullSpec = strings.TrimSpace(outStr)
125+
}
138126
fmt.Printf("openshift-tests image pull spec is %v\n", openshiftTestsImagePullSpec)
139127

140128
return openshiftTestsImagePullSpec, nil

pkg/test/extensions/binary.go

Lines changed: 11 additions & 61 deletions
Original file line numberDiff line numberDiff line change
@@ -24,8 +24,6 @@ import (
2424
"github.com/pkg/errors"
2525
"github.com/sirupsen/logrus"
2626
"golang.org/x/mod/semver"
27-
kapierrs "k8s.io/apimachinery/pkg/api/errors"
28-
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
2927
"k8s.io/apimachinery/pkg/util/sets"
3028
"k8s.io/klog/v2"
3129
k8simage "k8s.io/kubernetes/test/utils/image"
@@ -35,7 +33,6 @@ import (
3533
"github.com/openshift/origin/pkg/clioptions/clusterdiscovery"
3634
"github.com/openshift/origin/pkg/clioptions/imagesetup"
3735
"github.com/openshift/origin/pkg/clioptions/upgradeoptions"
38-
"github.com/openshift/origin/test/extended/util"
3936
exutil "github.com/openshift/origin/test/extended/util"
4037
origingenerated "github.com/openshift/origin/test/extended/util/annotate/generated"
4138
"github.com/openshift/origin/test/extended/util/image"
@@ -417,69 +414,22 @@ func ExtractAllTestBinaries(ctx context.Context, parallelism int) (func(), TestB
417414
return nil, nil, errors.New("parallelism must be greater than zero")
418415
}
419416

420-
releaseImage, err := determineReleasePayloadImage()
417+
releaseImage, err := DetermineReleasePayloadImage()
421418
if err != nil {
422419
return nil, nil, errors.WithMessage(err, "couldn't determine release image")
423420
}
424421

425-
oc := util.NewCLIWithoutNamespace("default")
426-
427-
// To extract binaries bearing external tests, we must inspect the release
428-
// payload under tests as well as extract content from component images
429-
// referenced by that payload.
430-
// openshift-tests is frequently run in the context of a CI job, within a pod.
431-
// CI sets $RELEASE_IMAGE_LATEST to a pullspec for the release payload under test. This
432-
// pull spec resolve to:
433-
// 1. A build farm ci-op-* namespace / imagestream location (anonymous access permitted).
434-
// 2. A quay.io/openshift-release-dev location (for tests against promoted ART payloads -- anonymous access permitted).
435-
// 3. A registry.ci.openshift.org/ocp-<arch>/release:<tag> (request registry.ci.openshift.org token).
436-
// Within the pod, we don't necessarily have a pull-secret for #3 OR the component images
437-
// a payload references (which are private, unless in a ci-op-* imagestream).
438-
// We try the following options:
439-
// 1. If set, use the REGISTRY_AUTH_FILE environment variable to an auths file with
440-
// pull secrets capable of reading appropriate payload & component image
441-
// information.
442-
// 2. If it exists, use a file /run/secrets/ci.openshift.io/cluster-profile/pull-secret
443-
// (conventional location for pull-secret information for CI cluster profile).
444-
// 3. Use openshift-config secret/pull-secret from the cluster-under-test, if it exists
445-
// (Microshift does not).
446-
// 4. Use unauthenticated access to the payload image and component images.
447-
registryAuthFilePath := os.Getenv("REGISTRY_AUTH_FILE")
448-
449-
// if the environment variable is not set, extract the target cluster's
450-
// platform pull secret.
451-
if len(registryAuthFilePath) != 0 {
452-
logrus.Infof("Using REGISTRY_AUTH_FILE environment variable: %v", registryAuthFilePath)
453-
} else {
454-
455-
// See if the cluster-profile has stored a pull-secret at the conventional location.
456-
ciProfilePullSecretPath := "/run/secrets/ci.openshift.io/cluster-profile/pull-secret"
457-
_, err := os.Stat(ciProfilePullSecretPath)
458-
if !os.IsNotExist(err) {
459-
logrus.Infof("Detected %v; using cluster profile for image access", ciProfilePullSecretPath)
460-
registryAuthFilePath = ciProfilePullSecretPath
461-
} else {
462-
// Inspect the cluster-under-test and read its cluster pull-secret dockerconfigjson value.
463-
clusterPullSecret, err := oc.AdminKubeClient().CoreV1().Secrets("openshift-config").Get(context.Background(), "pull-secret", metav1.GetOptions{})
464-
if err != nil {
465-
if kapierrs.IsNotFound(err) {
466-
logrus.Warningf("Cluster has no openshift-config secret/pull-secret; falling back to unauthenticated image access")
467-
} else {
468-
return nil, nil, fmt.Errorf("unable to read ephemeral cluster pull secret: %w", err)
469-
}
470-
} else {
471-
tmpDir, err := os.MkdirTemp("", "external-binary")
472-
clusterDockerConfig := clusterPullSecret.Data[".dockerconfigjson"]
473-
registryAuthFilePath = filepath.Join(tmpDir, ".dockerconfigjson")
474-
err = os.WriteFile(registryAuthFilePath, clusterDockerConfig, 0600)
475-
if err != nil {
476-
return nil, nil, fmt.Errorf("unable to serialize target cluster pull-secret locally: %w", err)
477-
}
422+
tmpDir, err := os.MkdirTemp("", "external-binary")
423+
if err != nil {
424+
return nil, nil, fmt.Errorf("failed to create temporary directory: %w", err)
425+
}
478426

479-
defer os.RemoveAll(tmpDir)
480-
logrus.Infof("Using target cluster pull-secrets for registry auth")
481-
}
482-
}
427+
defer os.RemoveAll(tmpDir)
428+
429+
oc := exutil.NewCLIWithoutNamespace("default")
430+
registryAuthFilePath, err := DetermineRegistryAuthFilePath(tmpDir, oc)
431+
if err != nil {
432+
return nil, nil, fmt.Errorf("failed to determine registry auth file path: %w", err)
483433
}
484434

485435
externalBinaryProvider, err := NewExternalBinaryProvider(releaseImage, registryAuthFilePath)

pkg/test/extensions/provider.go

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -59,7 +59,7 @@ func NewExternalBinaryProvider(releaseImage, registryAuthfilePath string) (*Exte
5959
return nil, errors.WithMessagef(err, "error creating cache path %s", binDir)
6060
}
6161

62-
releasePayloadImageStream, releaseImage, err := extractReleaseImageStream(binDir, releaseImage, registryAuthfilePath)
62+
releasePayloadImageStream, releaseImage, err := ExtractReleaseImageStream(binDir, releaseImage, registryAuthfilePath)
6363
if err != nil {
6464
return nil, errors.WithMessage(err, "couldn't extract release payload image stream")
6565
}

pkg/test/extensions/util.go

Lines changed: 63 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -8,6 +8,7 @@ import (
88
"encoding/json"
99
"fmt"
1010
"io"
11+
kapierrs "k8s.io/apimachinery/pkg/api/errors"
1112
"os"
1213
"os/exec"
1314
"path"
@@ -159,7 +160,7 @@ func pullSpecToDirName(input string) string {
159160
return filepath.Clean(safeName)
160161
}
161162

162-
func determineReleasePayloadImage() (string, error) {
163+
func DetermineReleasePayloadImage() (string, error) {
163164
var releaseImage string
164165

165166
// Highest priority override is EXTENSIONS_PAYLOAD_OVERRIDE
@@ -230,9 +231,9 @@ func createBinPath(path string) error {
230231
return nil
231232
}
232233

233-
// extractReleaseImageStream extracts image references from the given releaseImage and returns
234+
// ExtractReleaseImageStream extracts image references from the given releaseImage and returns
234235
// an ImageStream object with tags associated with image-references from that payload.
235-
func extractReleaseImageStream(extractPath, releaseImage string,
236+
func ExtractReleaseImageStream(extractPath, releaseImage string,
236237
registryAuthFilePath string) (*imagev1.ImageStream, string, error) {
237238

238239
if _, err := os.Stat(path.Join(extractPath, "image-references")); err != nil {
@@ -269,3 +270,62 @@ func extractReleaseImageStream(extractPath, releaseImage string,
269270

270271
return is, releaseImage, nil
271272
}
273+
274+
func DetermineRegistryAuthFilePath(tmpDir string, oc *util.CLI) (string, error) {
275+
// To extract binaries bearing external tests, we must inspect the release
276+
// payload under tests as well as extract content from component images
277+
// referenced by that payload.
278+
// openshift-tests is frequently run in the context of a CI job, within a pod.
279+
// CI sets $RELEASE_IMAGE_LATEST to a pullspec for the release payload under test. This
280+
// pull spec resolve to:
281+
// 1. A build farm ci-op-* namespace / imagestream location (anonymous access permitted).
282+
// 2. A quay.io/openshift-release-dev location (for tests against promoted ART payloads -- anonymous access permitted).
283+
// 3. A registry.ci.openshift.org/ocp-<arch>/release:<tag> (request registry.ci.openshift.org token).
284+
// Within the pod, we don't necessarily have a pull-secret for #3 OR the component images
285+
// a payload references (which are private, unless in a ci-op-* imagestream).
286+
// We try the following options:
287+
// 1. If set, use the REGISTRY_AUTH_FILE environment variable to an auths file with
288+
// pull secrets capable of reading appropriate payload & component image
289+
// information.
290+
// 2. If it exists, use a file /run/secrets/ci.openshift.io/cluster-profile/pull-secret
291+
// (conventional location for pull-secret information for CI cluster profile).
292+
// 3. Use openshift-config secret/pull-secret from the cluster-under-test, if it exists
293+
// (Microshift does not).
294+
// 4. Use unauthenticated access to the payload image and component images.
295+
registryAuthFilePath := os.Getenv("REGISTRY_AUTH_FILE")
296+
297+
// if the environment variable is not set, extract the target cluster's
298+
// platform pull secret.
299+
if len(registryAuthFilePath) != 0 {
300+
logrus.Infof("Using REGISTRY_AUTH_FILE environment variable: %v", registryAuthFilePath)
301+
} else {
302+
303+
// See if the cluster-profile has stored a pull-secret at the conventional location.
304+
ciProfilePullSecretPath := "/run/secrets/ci.openshift.io/cluster-profile/pull-secret"
305+
_, err := os.Stat(ciProfilePullSecretPath)
306+
if !os.IsNotExist(err) {
307+
logrus.Infof("Detected %v; using cluster profile for image access", ciProfilePullSecretPath)
308+
registryAuthFilePath = ciProfilePullSecretPath
309+
} else {
310+
// Inspect the cluster-under-test and read its cluster pull-secret dockerconfigjson value.
311+
clusterPullSecret, err := oc.AdminKubeClient().CoreV1().Secrets("openshift-config").Get(context.Background(), "pull-secret", metav1.GetOptions{})
312+
if err != nil {
313+
if kapierrs.IsNotFound(err) {
314+
logrus.Warningf("Cluster has no openshift-config secret/pull-secret; falling back to unauthenticated image access")
315+
} else {
316+
return "", fmt.Errorf("unable to read ephemeral cluster pull secret: %w", err)
317+
}
318+
} else {
319+
clusterDockerConfig := clusterPullSecret.Data[".dockerconfigjson"]
320+
registryAuthFilePath = filepath.Join(tmpDir, ".dockerconfigjson")
321+
err = os.WriteFile(registryAuthFilePath, clusterDockerConfig, 0600)
322+
if err != nil {
323+
return "", fmt.Errorf("unable to serialize target cluster pull-secret locally: %w", err)
324+
}
325+
logrus.Infof("Using target cluster pull-secrets for registry auth")
326+
}
327+
}
328+
}
329+
330+
return registryAuthFilePath, nil
331+
}

0 commit comments

Comments
 (0)