mirror of
https://github.com/redhat-developer/odo.git
synced 2025-10-19 03:06:19 +03:00
Add podman version to odo version output (#6913)
* Show podman version in odo version; TODO: fix test and implement json Signed-off-by: Parthvi Vala <pvala@redhat.com> * Add integration test Signed-off-by: Parthvi Vala <pvala@redhat.com> * Add support for JSON Signed-off-by: Parthvi Vala <pvala@redhat.com> * Add documentation Signed-off-by: Parthvi Vala <pvala@redhat.com> * Fix missing OpenShift version Signed-off-by: Parthvi Vala <pvala@redhat.com> * Add warnings when unable to fetch version information Signed-off-by: Parthvi Vala <pvala@redhat.com> * Do not print warning when --client is used and review Signed-off-by: Parthvi Vala <pvala@redhat.com> --------- Signed-off-by: Parthvi Vala <pvala@redhat.com>
This commit is contained in:
@@ -906,4 +906,32 @@ If odo can't find any projects on the cluster that you have access to, it will s
|
||||
```shell
|
||||
$ odo list projects -o json
|
||||
{}
|
||||
```
|
||||
```
|
||||
|
||||
## odo version -o json
|
||||
The `odo version -o json` returns the version information about `odo`, cluster server and podman client.
|
||||
Use `--client` flag to only obtain version information about `odo`.
|
||||
```shell
|
||||
odo version -o json [--client]
|
||||
```
|
||||
```shell
|
||||
$ odo version -o json
|
||||
{
|
||||
"version": "v3.11.0",
|
||||
"gitCommit": "ea2d256e8",
|
||||
"cluster": {
|
||||
"serverURL": "https://kubernetes.docker.internal:6443",
|
||||
"kubernetes": {
|
||||
"version": "v1.25.9"
|
||||
},
|
||||
"openshift": {
|
||||
"version": "4.13.0"
|
||||
},
|
||||
},
|
||||
"podman": {
|
||||
"client": {
|
||||
"version": "4.5.1"
|
||||
}
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
28
docs/website/docs/command-reference/version.md
Normal file
28
docs/website/docs/command-reference/version.md
Normal file
@@ -0,0 +1,28 @@
|
||||
---
|
||||
title: odo version
|
||||
---
|
||||
|
||||
## Description
|
||||
The `odo version` command returns the version information about `odo`, cluster server and podman client.
|
||||
|
||||
## Running the Command
|
||||
The command takes an optional `--client` flag that only returns version information about `odo`.
|
||||
|
||||
The command will only print Openshift version if it is available.
|
||||
```shell
|
||||
odo version [--client] [-o json]
|
||||
```
|
||||
|
||||
<details>
|
||||
<summary>Example</summary>
|
||||
|
||||
```shell
|
||||
$ odo version
|
||||
odo v3.11.0 (a9e6cdc34)
|
||||
|
||||
Server: https://ab0bc42973f0043e7a2b9c24f5acddd6-9c1554c20c1ec323.elb.us-east-1.amazonaws.com:6443
|
||||
OpenShift: 4.13.0
|
||||
Kubernetes: v1.27.2+b451817
|
||||
Podman Client: 4.5.1
|
||||
```
|
||||
</details>
|
||||
47
pkg/api/version.go
Normal file
47
pkg/api/version.go
Normal file
@@ -0,0 +1,47 @@
|
||||
package api
|
||||
|
||||
/*
|
||||
{
|
||||
"version": "v3.11.0",
|
||||
"gitCommit": "0acf1a5af",
|
||||
"cluster": {
|
||||
"serverURL": "https://kubernetes.docker.internal:6443",
|
||||
"kubernetes": {
|
||||
"version": "v1.25.9"
|
||||
},
|
||||
"openshift": {
|
||||
"version": "4.13.0"
|
||||
}
|
||||
},
|
||||
"podman": {
|
||||
"client": {
|
||||
"version": "4.5.1"
|
||||
}
|
||||
}
|
||||
}
|
||||
*/
|
||||
|
||||
type OdoVersion struct {
|
||||
Version string `json:"version"`
|
||||
GitCommit string `json:"gitCommit"`
|
||||
Cluster *ClusterInfo `json:"cluster,omitempty"`
|
||||
Podman *PodmanInfo `json:"podman,omitempty"`
|
||||
}
|
||||
|
||||
type ClusterInfo struct {
|
||||
ServerURL string `json:"serverURL,omitempty"`
|
||||
Kubernetes *ClusterClientInfo `json:"kubernetes,omitempty"`
|
||||
OpenShift *ClusterClientInfo `json:"openshift,omitempty"`
|
||||
}
|
||||
|
||||
type ClusterClientInfo struct {
|
||||
Version string `json:"version,omitempty"`
|
||||
}
|
||||
|
||||
type PodmanInfo struct {
|
||||
Client *PodmanClientInfo `json:"client,omitempty"`
|
||||
}
|
||||
|
||||
type PodmanClientInfo struct {
|
||||
Version string `json:"version,omitempty"`
|
||||
}
|
||||
@@ -61,15 +61,15 @@ func (c *Client) GetServerVersion(timeout time.Duration) (*ServerInfo, error) {
|
||||
|
||||
// This will fetch the information about OpenShift Version
|
||||
coreGet := c.GetClient().CoreV1().RESTClient().Get()
|
||||
rawOpenShiftVersion, err := coreGet.AbsPath("/version/openshift").Do(context.TODO()).Raw()
|
||||
rawOpenShiftVersion, err := coreGet.AbsPath("/apis/config.openshift.io/v1/clusterversions/version").Do(context.TODO()).Raw()
|
||||
if err != nil {
|
||||
klog.V(3).Info("Unable to get OpenShift Version: ", err)
|
||||
} else {
|
||||
var openShiftVersion version.Info
|
||||
var openShiftVersion configv1.ClusterVersion
|
||||
if e := json.Unmarshal(rawOpenShiftVersion, &openShiftVersion); e != nil {
|
||||
return nil, fmt.Errorf("unable to unmarshal OpenShift version %v: %w", string(rawOpenShiftVersion), e)
|
||||
}
|
||||
info.OpenShiftVersion = openShiftVersion.GitVersion
|
||||
info.OpenShiftVersion = openShiftVersion.Status.Desired.Version
|
||||
}
|
||||
|
||||
// This will fetch the information about Kubernetes Version
|
||||
|
||||
@@ -3,6 +3,10 @@ package version
|
||||
import (
|
||||
"context"
|
||||
"fmt"
|
||||
"github.com/redhat-developer/odo/pkg/api"
|
||||
"github.com/redhat-developer/odo/pkg/log"
|
||||
"github.com/redhat-developer/odo/pkg/odo/commonflags"
|
||||
"github.com/redhat-developer/odo/pkg/podman"
|
||||
"os"
|
||||
"strings"
|
||||
|
||||
@@ -39,11 +43,12 @@ type VersionOptions struct {
|
||||
|
||||
// serverInfo contains the remote server information if the user asked for it, nil otherwise
|
||||
serverInfo *kclient.ServerInfo
|
||||
|
||||
clientset *clientset.Clientset
|
||||
podmanInfo podman.SystemVersionReport
|
||||
clientset *clientset.Clientset
|
||||
}
|
||||
|
||||
var _ genericclioptions.Runnable = (*VersionOptions)(nil)
|
||||
var _ genericclioptions.JsonOutputter = (*VersionOptions)(nil)
|
||||
|
||||
// NewVersionOptions creates a new VersionOptions instance
|
||||
func NewVersionOptions() *VersionOptions {
|
||||
@@ -56,17 +61,31 @@ func (o *VersionOptions) SetClientset(clientset *clientset.Clientset) {
|
||||
|
||||
// Complete completes VersionOptions after they have been created
|
||||
func (o *VersionOptions) Complete(ctx context.Context, cmdline cmdline.Cmdline, args []string) (err error) {
|
||||
if !o.clientFlag {
|
||||
// Let's fetch the info about the server, ignoring errors
|
||||
client, err := kclient.New()
|
||||
if o.clientFlag {
|
||||
return nil
|
||||
}
|
||||
|
||||
if err == nil {
|
||||
o.serverInfo, err = client.GetServerVersion(o.clientset.PreferenceClient.GetTimeout())
|
||||
if err != nil {
|
||||
klog.V(4).Info("unable to fetch the server version: ", err)
|
||||
}
|
||||
// Fetch the info about the server, ignoring errors
|
||||
if o.clientset.KubernetesClient != nil {
|
||||
o.serverInfo, err = o.clientset.KubernetesClient.GetServerVersion(o.clientset.PreferenceClient.GetTimeout())
|
||||
if err != nil {
|
||||
klog.V(4).Info("unable to fetch the server version: ", err)
|
||||
}
|
||||
}
|
||||
|
||||
if o.clientset.PodmanClient != nil {
|
||||
o.podmanInfo, err = o.clientset.PodmanClient.Version(ctx)
|
||||
if err != nil {
|
||||
klog.V(4).Info("unable to fetch the podman client version: ", err)
|
||||
}
|
||||
}
|
||||
|
||||
if o.serverInfo == nil {
|
||||
log.Warning("unable to fetch the cluster server version")
|
||||
}
|
||||
if o.podmanInfo.Client == nil {
|
||||
log.Warning("unable to fetch the podman client version")
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
@@ -75,33 +94,76 @@ func (o *VersionOptions) Validate(ctx context.Context) (err error) {
|
||||
return nil
|
||||
}
|
||||
|
||||
func (o *VersionOptions) RunForJsonOutput(ctx context.Context) (out interface{}, err error) {
|
||||
return o.run(), nil
|
||||
}
|
||||
|
||||
func (o *VersionOptions) run() api.OdoVersion {
|
||||
result := api.OdoVersion{
|
||||
Version: odoversion.VERSION,
|
||||
GitCommit: odoversion.GITCOMMIT,
|
||||
}
|
||||
|
||||
if o.clientFlag {
|
||||
return result
|
||||
}
|
||||
|
||||
if o.serverInfo != nil {
|
||||
clusterInfo := &api.ClusterInfo{
|
||||
ServerURL: o.serverInfo.Address,
|
||||
Kubernetes: &api.ClusterClientInfo{Version: o.serverInfo.KubernetesVersion},
|
||||
}
|
||||
if o.serverInfo.OpenShiftVersion != "" {
|
||||
clusterInfo.OpenShift = &api.ClusterClientInfo{Version: o.serverInfo.OpenShiftVersion}
|
||||
}
|
||||
result.Cluster = clusterInfo
|
||||
}
|
||||
|
||||
if o.podmanInfo.Client != nil {
|
||||
podmanInfo := &api.PodmanInfo{Client: &api.PodmanClientInfo{Version: o.podmanInfo.Client.Version}}
|
||||
result.Podman = podmanInfo
|
||||
}
|
||||
|
||||
return result
|
||||
}
|
||||
|
||||
// Run contains the logic for the odo service create command
|
||||
func (o *VersionOptions) Run(ctx context.Context) (err error) {
|
||||
// If verbose mode is enabled, dump all KUBECLT_* env variables
|
||||
// this is usefull for debuging oc plugin integration
|
||||
// If verbose mode is enabled, dump all KUBECTL_* env variables
|
||||
// this is useful for debugging oc plugin integration
|
||||
for _, v := range os.Environ() {
|
||||
if strings.HasPrefix(v, "KUBECTL_") {
|
||||
klog.V(4).Info(v)
|
||||
}
|
||||
}
|
||||
|
||||
fmt.Println("odo " + odoversion.VERSION + " (" + odoversion.GITCOMMIT + ")")
|
||||
odoVersion := o.run()
|
||||
fmt.Println("odo " + odoVersion.Version + " (" + odoVersion.GitCommit + ")")
|
||||
|
||||
if !o.clientFlag && o.serverInfo != nil {
|
||||
// make sure we only include OpenShift info if we actually have it
|
||||
openshiftStr := ""
|
||||
if len(o.serverInfo.OpenShiftVersion) > 0 {
|
||||
openshiftStr = fmt.Sprintf("OpenShift: %v\n", o.serverInfo.OpenShiftVersion)
|
||||
}
|
||||
fmt.Printf("\n"+
|
||||
"Server: %v\n"+
|
||||
"%v"+
|
||||
"Kubernetes: %v\n",
|
||||
o.serverInfo.Address,
|
||||
openshiftStr,
|
||||
o.serverInfo.KubernetesVersion)
|
||||
if o.clientFlag {
|
||||
return nil
|
||||
}
|
||||
|
||||
message := "\n"
|
||||
if odoVersion.Cluster != nil {
|
||||
cluster := odoVersion.Cluster
|
||||
message += fmt.Sprintf("Server: %v\n", cluster.ServerURL)
|
||||
|
||||
// make sure we only include OpenShift info if we actually have it
|
||||
if cluster.OpenShift != nil && cluster.OpenShift.Version != "" {
|
||||
message += fmt.Sprintf("OpenShift: %v\n", cluster.OpenShift.Version)
|
||||
}
|
||||
if cluster.Kubernetes != nil {
|
||||
message += fmt.Sprintf("Kubernetes: %v\n", cluster.Kubernetes.Version)
|
||||
}
|
||||
}
|
||||
|
||||
if odoVersion.Podman != nil && odoVersion.Podman.Client != nil {
|
||||
message += fmt.Sprintf("Podman Client: %v\n", odoVersion.Podman.Client.Version)
|
||||
}
|
||||
|
||||
fmt.Print(message)
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
@@ -118,7 +180,8 @@ func NewCmdVersion(name, fullName string, testClientset clientset.Clientset) *co
|
||||
return genericclioptions.GenericRun(o, testClientset, cmd, args)
|
||||
},
|
||||
}
|
||||
clientset.Add(versionCmd, clientset.PREFERENCE)
|
||||
commonflags.UseOutputFlag(versionCmd)
|
||||
clientset.Add(versionCmd, clientset.PREFERENCE, clientset.KUBERNETES_NULLABLE, clientset.PODMAN_NULLABLE)
|
||||
util.SetCommandGroup(versionCmd, util.UtilityGroup)
|
||||
|
||||
versionCmd.SetUsageTemplate(util.CmdUsageTemplate)
|
||||
|
||||
@@ -5,6 +5,7 @@ import (
|
||||
"context"
|
||||
"encoding/json"
|
||||
"fmt"
|
||||
"github.com/onsi/gomega/types"
|
||||
"os"
|
||||
"path/filepath"
|
||||
"regexp"
|
||||
@@ -324,6 +325,12 @@ func JsonPathContentContain(json string, path string, value string) {
|
||||
Expect(result.String()).To(ContainSubstring(value), fmt.Sprintf("content of path %q should contain %q but is %q", path, value, result.String()))
|
||||
}
|
||||
|
||||
// JsonPathSatisfies expects content of the path to satisfy all the matchers passed to it
|
||||
func JsonPathSatisfies(json string, path string, matchers ...types.GomegaMatcher) {
|
||||
result := gjson.Get(json, path)
|
||||
Expect(result.String()).Should(SatisfyAll(matchers...))
|
||||
}
|
||||
|
||||
// JsonPathDoesNotExist expects that the content of the path does not exist in the JSON string
|
||||
func JsonPathDoesNotExist(json string, path string) {
|
||||
result := gjson.Get(json, path)
|
||||
|
||||
@@ -74,3 +74,18 @@ func GetPodmanVersion() string {
|
||||
Expect(err).ToNot(HaveOccurred())
|
||||
return result.Client.Version
|
||||
}
|
||||
|
||||
// GenerateDelayedPodman returns a podman cmd that sleeps for delaySecond before responding;
|
||||
// this function is usually used in combination with PODMAN_CMD_INIT_TIMEOUT odo preference
|
||||
func GenerateDelayedPodman(commonVarContext string, delaySecond int) string {
|
||||
delayer := filepath.Join(commonVarContext, "podman-cmd-delayer")
|
||||
fileContent := fmt.Sprintf(`#!/bin/bash
|
||||
|
||||
echo Delaying command execution... >&2
|
||||
sleep %d
|
||||
echo "$@"
|
||||
`, delaySecond)
|
||||
err := CreateFileWithContentAndPerm(delayer, fileContent, 0755)
|
||||
Expect(err).ToNot(HaveOccurred())
|
||||
return delayer
|
||||
}
|
||||
|
||||
@@ -100,14 +100,7 @@ var _ = Describe("odo dev command tests", func() {
|
||||
// odo dev on cluster should not wait for the Podman client to initialize properly, if this client takes very long.
|
||||
// See https://github.com/redhat-developer/odo/issues/6575.
|
||||
// StartDevMode will time out if Podman client takes too long to initialize.
|
||||
delayer := filepath.Join(commonVar.Context, "podman-cmd-delayer")
|
||||
err = helper.CreateFileWithContentAndPerm(delayer, `#!/bin/bash
|
||||
|
||||
echo Delaying command execution... >&2
|
||||
sleep 10
|
||||
echo "$@"
|
||||
`, 0755)
|
||||
Expect(err).ShouldNot(HaveOccurred())
|
||||
delayer := helper.GenerateDelayedPodman(commonVar.Context, 10)
|
||||
|
||||
var devSession helper.DevSession
|
||||
devSession, err = helper.StartDevMode(helper.DevSessionOpts{
|
||||
|
||||
@@ -3,7 +3,6 @@ package integration
|
||||
import (
|
||||
. "github.com/onsi/ginkgo/v2"
|
||||
. "github.com/onsi/gomega"
|
||||
|
||||
"github.com/redhat-developer/odo/tests/helper"
|
||||
)
|
||||
|
||||
@@ -112,27 +111,94 @@ var _ = Describe("odo generic", func() {
|
||||
})
|
||||
})
|
||||
|
||||
When("executing odo version command", func() {
|
||||
var odoVersion string
|
||||
BeforeEach(func() {
|
||||
odoVersion = helper.Cmd("odo", "version").ShouldPass().Out()
|
||||
Context("executing odo version command", func() {
|
||||
const (
|
||||
reOdoVersion = `^odo\s*v[0-9]+.[0-9]+.[0-9]+(?:-\w+)?\s*\(\w+\)`
|
||||
reKubernetesVersion = `Kubernetes:\s*v[0-9]+.[0-9]+.[0-9]+((-\w+\.[0-9]+)?\+\w+)?`
|
||||
rePodmanVersion = `Podman Client:\s*[0-9]+.[0-9]+.[0-9]+((-\w+\.[0-9]+)?\+\w+)?`
|
||||
reJSONVersion = `^v{0,1}[0-9]+.[0-9]+.[0-9]+((-\w+\.[0-9]+)?\+\w+)?`
|
||||
)
|
||||
When("executing the complete command with server info", func() {
|
||||
var odoVersion string
|
||||
BeforeEach(func() {
|
||||
odoVersion = helper.Cmd("odo", "version").ShouldPass().Out()
|
||||
})
|
||||
for _, podman := range []bool{true, false} {
|
||||
podman := podman
|
||||
It("should show the version of odo major components including server login URL", helper.LabelPodmanIf(podman, func() {
|
||||
By("checking the human readable output", func() {
|
||||
Expect(odoVersion).Should(MatchRegexp(reOdoVersion))
|
||||
|
||||
// odo tests setup (CommonBeforeEach) is designed in a way that if a test is labelled with 'podman', it will not have cluster configuration
|
||||
// so we only test podman info on podman labelled test, and clsuter info otherwise
|
||||
// TODO (pvala): Change this behavior when we write tests that should be tested on both podman and cluster simultaneously
|
||||
// Ref: https://github.com/redhat-developer/odo/issues/6719
|
||||
if podman {
|
||||
Expect(odoVersion).Should(MatchRegexp(rePodmanVersion))
|
||||
Expect(odoVersion).To(ContainSubstring(helper.GetPodmanVersion()))
|
||||
} else {
|
||||
Expect(odoVersion).Should(MatchRegexp(reKubernetesVersion))
|
||||
serverURL := oc.GetCurrentServerURL()
|
||||
Expect(odoVersion).Should(ContainSubstring("Server: " + serverURL))
|
||||
if !helper.IsKubernetesCluster() {
|
||||
Expect(odoVersion).Should(ContainSubstring("OpenShift: "))
|
||||
}
|
||||
}
|
||||
})
|
||||
|
||||
By("checking the JSON output", func() {
|
||||
odoVersion = helper.Cmd("odo", "version", "-o", "json").ShouldPass().Out()
|
||||
Expect(helper.IsJSON(odoVersion)).To(BeTrue())
|
||||
helper.JsonPathSatisfies(odoVersion, "version", MatchRegexp(reJSONVersion))
|
||||
helper.JsonPathExist(odoVersion, "gitCommit")
|
||||
if podman {
|
||||
helper.JsonPathSatisfies(odoVersion, "podman.client.version", MatchRegexp(reJSONVersion), Equal(helper.GetPodmanVersion()))
|
||||
} else {
|
||||
helper.JsonPathSatisfies(odoVersion, "cluster.kubernetes.version", MatchRegexp(reJSONVersion))
|
||||
serverURL := oc.GetCurrentServerURL()
|
||||
helper.JsonPathContentIs(odoVersion, "cluster.serverURL", serverURL)
|
||||
if !helper.IsKubernetesCluster() {
|
||||
helper.JsonPathSatisfies(odoVersion, "cluster.openshift", Not(BeEmpty()))
|
||||
}
|
||||
}
|
||||
})
|
||||
}))
|
||||
}
|
||||
|
||||
for _, label := range []string{helper.LabelNoCluster, helper.LabelUnauth} {
|
||||
label := label
|
||||
It("should show the version of odo major components", Label(label), func() {
|
||||
Expect(odoVersion).Should(MatchRegexp(reOdoVersion))
|
||||
})
|
||||
}
|
||||
})
|
||||
|
||||
It("should show the version of odo major components including server login URL", func() {
|
||||
reOdoVersion := `^odo\s*v[0-9]+.[0-9]+.[0-9]+(?:-\w+)?\s*\(\w+\)`
|
||||
rekubernetesVersion := `Kubernetes:\s*v[0-9]+.[0-9]+.[0-9]+((-\w+\.[0-9]+)?\+\w+)?`
|
||||
Expect(odoVersion).Should(SatisfyAll(MatchRegexp(reOdoVersion), MatchRegexp(rekubernetesVersion)))
|
||||
serverURL := oc.GetCurrentServerURL()
|
||||
Expect(odoVersion).Should(ContainSubstring("Server: " + serverURL))
|
||||
When("podman client is bound to delay and odo version is run", Label(helper.LabelPodman), func() {
|
||||
var odoVersion string
|
||||
BeforeEach(func() {
|
||||
delayer := helper.GenerateDelayedPodman(commonVar.Context, 2)
|
||||
odoVersion = helper.Cmd("odo", "version").WithEnv("PODMAN_CMD="+delayer, "PODMAN_CMD_INIT_TIMEOUT=1s").ShouldPass().Out()
|
||||
})
|
||||
It("should not print podman version if podman cmd timeout has been reached", func() {
|
||||
Expect(odoVersion).Should(MatchRegexp(reOdoVersion))
|
||||
Expect(odoVersion).ToNot(ContainSubstring("Podman Client:"))
|
||||
})
|
||||
})
|
||||
It("should only print client info when using --client flag", func() {
|
||||
By("checking human readable output", func() {
|
||||
odoVersion := helper.Cmd("odo", "version", "--client").ShouldPass().Out()
|
||||
Expect(odoVersion).Should(MatchRegexp(reOdoVersion))
|
||||
Expect(odoVersion).ToNot(SatisfyAll(ContainSubstring("Server"), ContainSubstring("Kubernetes"), ContainSubstring("Podman Client")))
|
||||
})
|
||||
|
||||
It("should show the version of odo major components", Label(helper.LabelNoCluster), func() {
|
||||
reOdoVersion := `^odo\s*v[0-9]+.[0-9]+.[0-9]+(?:-\w+)?\s*\(\w+\)`
|
||||
Expect(odoVersion).Should(MatchRegexp(reOdoVersion))
|
||||
})
|
||||
It("should show the version of odo major components", Label(helper.LabelUnauth), func() {
|
||||
reOdoVersion := `^odo\s*v[0-9]+.[0-9]+.[0-9]+(?:-\w+)?\s*\(\w+\)`
|
||||
Expect(odoVersion).Should(MatchRegexp(reOdoVersion))
|
||||
By("checking JSON output", func() {
|
||||
odoVersion := helper.Cmd("odo", "version", "--client", "-o", "json").ShouldPass().Out()
|
||||
Expect(helper.IsJSON(odoVersion)).To(BeTrue())
|
||||
helper.JsonPathSatisfies(odoVersion, "version", MatchRegexp(reJSONVersion))
|
||||
helper.JsonPathExist(odoVersion, "gitCommit")
|
||||
helper.JsonPathSatisfies(odoVersion, "cluster", BeEmpty())
|
||||
helper.JsonPathSatisfies(odoVersion, "podman", BeEmpty())
|
||||
})
|
||||
})
|
||||
})
|
||||
|
||||
|
||||
Reference in New Issue
Block a user