Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

odo list component shows components running on podman #6366

Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
13 changes: 8 additions & 5 deletions pkg/api/component-abstract.go
Original file line number Diff line number Diff line change
Expand Up @@ -2,11 +2,14 @@ package api

// ComponentAbstract represents a component as part of a list of components
type ComponentAbstract struct {
Name string `json:"name"`
ManagedBy string `json:"managedBy"`
ManagedByVersion string `json:"managedByVersion"`
RunningIn RunningModes `json:"runningIn"`
Type string `json:"projectType"`
Name string `json:"name"`
ManagedBy string `json:"managedBy"`
ManagedByVersion string `json:"managedByVersion"`
// RunningIn are the modes the component is running in, among Dev and Deploy
RunningIn RunningModes `json:"runningIn"`
Type string `json:"projectType"`
// RunningOn is the platform the component is running on, either cluster or podman
RunningOn string `json:"runningOn,omitempty"`
}

const (
Expand Down
26 changes: 14 additions & 12 deletions pkg/binding/list.go
Original file line number Diff line number Diff line change
Expand Up @@ -61,22 +61,24 @@ func (o *BindingClient) ListAllBindings(devfileObj *parser.DevfileObj, context s
}
}

specs, bindings, err := o.kubernetesClient.ListServiceBindingsFromAllGroups()
if err != nil {
return nil, nil, err
}

for i := range specs {
bindingList, err = o.process(bindingList, &specs[i])
if o.kubernetesClient != nil {
specs, bindings, err := o.kubernetesClient.ListServiceBindingsFromAllGroups()
if err != nil {
return nil, nil, err
}
}

for i := range bindings {
bindingList, err = o.process(bindingList, &bindings[i])
if err != nil {
return nil, nil, err
for i := range specs {
bindingList, err = o.process(bindingList, &specs[i])
if err != nil {
return nil, nil, err
}
}

for i := range bindings {
bindingList, err = o.process(bindingList, &bindings[i])
if err != nil {
return nil, nil, err
}
}
}

Expand Down
29 changes: 22 additions & 7 deletions pkg/component/component.go
Original file line number Diff line number Diff line change
Expand Up @@ -19,8 +19,10 @@ import (
"github.com/redhat-developer/odo/pkg/api"
"github.com/redhat-developer/odo/pkg/kclient"
odolabels "github.com/redhat-developer/odo/pkg/labels"
"github.com/redhat-developer/odo/pkg/odo/commonflags"
odocontext "github.com/redhat-developer/odo/pkg/odo/context"
"github.com/redhat-developer/odo/pkg/platform"
"github.com/redhat-developer/odo/pkg/podman"
"github.com/redhat-developer/odo/pkg/util"

corev1 "k8s.io/api/core/v1"
Expand Down Expand Up @@ -170,6 +172,7 @@ func ListAllClusterComponents(client kclient.ClientInterface, namespace string)
ManagedBy: managedBy,
Type: componentType,
ManagedByVersion: managedByVersion,
RunningOn: commonflags.RunOnCluster,
}
mode := odolabels.GetMode(labels)
componentFound := false
Expand Down Expand Up @@ -204,14 +207,26 @@ func ListAllClusterComponents(client kclient.ClientInterface, namespace string)
return components, nil
}

func ListAllComponents(client kclient.ClientInterface, namespace string, devObj *parser.DevfileObj, componentName string) ([]api.ComponentAbstract, string, error) {
var devfileComponents []api.ComponentAbstract
var err error
func ListAllComponents(client kclient.ClientInterface, podmanClient podman.Client, namespace string, devObj *parser.DevfileObj, componentName string) ([]api.ComponentAbstract, string, error) {
var (
allComponents []api.ComponentAbstract
)

if client != nil {
devfileComponents, err = ListAllClusterComponents(client, namespace)
clusterComponents, err := ListAllClusterComponents(client, namespace)
if err != nil {
return nil, "", err
}
allComponents = append(allComponents, clusterComponents...)
}

// PdomanClient can be nil if experimental mode is not active
if podmanClient != nil {
podmanComponents, err := podmanClient.ListAllComponents()
if err != nil {
return nil, "", err
}
allComponents = append(allComponents, podmanComponents...)
}

localComponent := api.ComponentAbstract{
Expand All @@ -225,12 +240,12 @@ func ListAllComponents(client kclient.ClientInterface, namespace string, devObj

componentInDevfile := ""
if localComponent.Name != "" {
if !Contains(localComponent, devfileComponents) {
devfileComponents = append(devfileComponents, localComponent)
if !Contains(localComponent, allComponents) {
allComponents = append(allComponents, localComponent)
}
componentInDevfile = localComponent.Name
}
return devfileComponents, componentInDevfile, nil
return allComponents, componentInDevfile, nil
}

func getResourcesForComponent(
Expand Down
6 changes: 5 additions & 1 deletion pkg/component/component_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -85,6 +85,7 @@ func TestListAllClusterComponents(t *testing.T) {
ManagedByVersion: "",
RunningIn: nil,
Type: "Unknown",
RunningOn: "cluster",
}},
wantErr: false,
},
Expand Down Expand Up @@ -125,12 +126,14 @@ func TestListAllClusterComponents(t *testing.T) {
ManagedByVersion: "",
RunningIn: nil,
Type: "Unknown",
RunningOn: "cluster",
}, {
Name: "svc1",
ManagedBy: "odo",
ManagedByVersion: "v3.0.0-beta3",
RunningIn: nil,
Type: "nodejs",
RunningOn: "cluster",
}},
wantErr: false,
},
Expand All @@ -156,7 +159,8 @@ func TestListAllClusterComponents(t *testing.T) {
"dev": true,
"deploy": true,
},
Type: "nodejs",
Type: "nodejs",
RunningOn: "cluster",
}},
wantErr: false,
},
Expand Down
2 changes: 1 addition & 1 deletion pkg/dev/podmandev/pod.go
Original file line number Diff line number Diff line change
Expand Up @@ -80,7 +80,6 @@ func createPodFromComponent(
}
}

// TODO add labels (for GetRunningPodFromSelector)
pod := corev1.Pod{
Spec: corev1.PodSpec{
Containers: containers,
Expand All @@ -97,6 +96,7 @@ func createPodFromComponent(

runtime := component.GetComponentRuntimeFromDevfileMetadata(devfileObj.Data.GetMetadata())
pod.SetLabels(labels.GetLabels(componentName, appName, runtime, labels.ComponentDevMode, true))
labels.SetProjectType(pod.GetLabels(), component.GetComponentTypeFromDevfileMetadata(devfileObj.Data.GetMetadata()))

return &pod, fwPorts, nil
}
Expand Down
1 change: 1 addition & 0 deletions pkg/dev/podmandev/pod_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -58,6 +58,7 @@ var (
"app.kubernetes.io/part-of": appName,
"component": devfileName,
"odo.dev/mode": labels.ComponentDevMode,
"odo.dev/project-type": "Not available",
},
},
Spec: corev1.PodSpec{
Expand Down
2 changes: 1 addition & 1 deletion pkg/odo/cli/cli.go
Original file line number Diff line number Diff line change
Expand Up @@ -180,7 +180,7 @@ func odoRootCmd(ctx context.Context, name, fullName string) *cobra.Command {
version.NewCmdVersion(version.RecommendedCommandName, util.GetFullName(fullName, version.RecommendedCommandName)),
preference.NewCmdPreference(ctx, preference.RecommendedCommandName, util.GetFullName(fullName, preference.RecommendedCommandName)),
telemetry.NewCmdTelemetry(telemetry.RecommendedCommandName),
list.NewCmdList(list.RecommendedCommandName, util.GetFullName(fullName, list.RecommendedCommandName)),
list.NewCmdList(ctx, list.RecommendedCommandName, util.GetFullName(fullName, list.RecommendedCommandName)),
build_images.NewCmdBuildImages(build_images.RecommendedCommandName, util.GetFullName(fullName, build_images.RecommendedCommandName)),
deploy.NewCmdDeploy(deploy.RecommendedCommandName, util.GetFullName(fullName, deploy.RecommendedCommandName)),
_init.NewCmdInit(_init.RecommendedCommandName, util.GetFullName(fullName, _init.RecommendedCommandName)),
Expand Down
10 changes: 7 additions & 3 deletions pkg/odo/cli/dev/dev.go
Original file line number Diff line number Diff line change
Expand Up @@ -101,12 +101,16 @@ func (o *DevOptions) Validate(ctx context.Context) error {
return clierrors.NewNoCommandInDevfileError("debug")
}

platform := fcontext.GetRunOn(ctx)
platform := fcontext.GetRunOn(ctx, commonflags.RunOnCluster)
switch platform {
case commonflags.RunOnCluster:
if o.clientset.KubernetesClient == nil {
return errors.New("no connection to cluster defined")
}
case commonflags.RunOnPodman:
if o.clientset.PodmanClient == nil {
return errors.New("unable to access podman. Do you have podman client installed?")
}
}
return nil
}
Expand All @@ -118,7 +122,7 @@ func (o *DevOptions) Run(ctx context.Context) (err error) {
path = filepath.Dir(devfilePath)
componentName = odocontext.GetComponentName(ctx)
variables = fcontext.GetVariables(ctx)
platform = fcontext.GetRunOn(ctx)
platform = fcontext.GetRunOn(ctx, commonflags.RunOnCluster)
)

var dest string
Expand Down Expand Up @@ -226,7 +230,7 @@ It forwards endpoints with any exposure values ('public', 'internal' or 'none')
clientset.FILESYSTEM,
clientset.INIT,
clientset.KUBERNETES_NULLABLE,
clientset.PODMAN,
clientset.PODMAN_NULLABLE,
clientset.PORT_FORWARD,
clientset.PREFERENCE,
clientset.STATE,
Expand Down
2 changes: 2 additions & 0 deletions pkg/odo/cli/feature/doc.go
Original file line number Diff line number Diff line change
@@ -1,2 +1,4 @@
// Package feature allows to determine whether a given feature is enabled or not at the CLI level.
// Active features are accumulated in a global `enabledFeatures` variable, and warning
// can be displayed with the DisplayWarnings function
package feature
18 changes: 17 additions & 1 deletion pkg/odo/cli/feature/features.go
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@ package feature

import (
"context"
"sort"

"github.com/redhat-developer/odo/pkg/log"
)
Expand All @@ -28,6 +29,8 @@ var (
isExperimental: true,
description: "flag: --run-on",
}

enabledFeatures = map[OdoFeature]struct{}{}
)

// IsEnabled returns whether the specified feature should be enabled or not.
Expand All @@ -42,8 +45,21 @@ func IsEnabled(ctx context.Context, feat OdoFeature) bool {
// Features marked as experimental are enabled only if the experimental mode is set
experimentalModeEnabled := isExperimentalModeEnabled(ctx)
if experimentalModeEnabled {
enabledFeatures[feat] = struct{}{}
}
return experimentalModeEnabled
}

func DisplayWarnings() {
features := make([]OdoFeature, 0, len(enabledFeatures))
for k := range enabledFeatures {
features = append(features, k)
}
sort.Slice(features, func(i, j int) bool {
return features[i].id < features[j].id
})
for _, feat := range features {
log.Experimentalf("Experimental mode enabled for %s. Use at your own risk. More details on https://odo.dev/docs/user-guides/advanced/experimental-mode",
feat.description)
}
return experimentalModeEnabled
}
55 changes: 46 additions & 9 deletions pkg/odo/cli/list/component/list.go
Original file line number Diff line number Diff line change
Expand Up @@ -10,13 +10,15 @@ import (
"github.com/spf13/cobra"

"github.com/redhat-developer/odo/pkg/api"
"github.com/redhat-developer/odo/pkg/odo/cli/feature"
"github.com/redhat-developer/odo/pkg/odo/cli/ui"
"github.com/redhat-developer/odo/pkg/odo/commonflags"

"github.com/redhat-developer/odo/pkg/component"

"github.com/redhat-developer/odo/pkg/log"
"github.com/redhat-developer/odo/pkg/odo/cmdline"
fcontext "github.com/redhat-developer/odo/pkg/odo/commonflags/context"
odocontext "github.com/redhat-developer/odo/pkg/odo/context"
"github.com/redhat-developer/odo/pkg/odo/genericclioptions"
"github.com/redhat-developer/odo/pkg/odo/genericclioptions/clientset"
Expand Down Expand Up @@ -91,7 +93,7 @@ func (lo *ListOptions) Run(ctx context.Context) error {

listSpinner.End(true)

HumanReadableOutput(list)
HumanReadableOutput(ctx, list)
return nil
}

Expand All @@ -104,20 +106,38 @@ func (lo *ListOptions) run(ctx context.Context) (api.ResourcesList, error) {
var (
devfileObj = odocontext.GetDevfileObj(ctx)
componentName = odocontext.GetComponentName(ctx)

kubeClient = lo.clientset.KubernetesClient
podmanClient = lo.clientset.PodmanClient
)
devfileComponents, componentInDevfile, err := component.ListAllComponents(
lo.clientset.KubernetesClient, lo.namespaceFilter, devfileObj, componentName)

switch fcontext.GetRunOn(ctx, "") {
case commonflags.RunOnCluster:
podmanClient = nil
case commonflags.RunOnPodman:
kubeClient = nil
}

allComponents, componentInDevfile, err := component.ListAllComponents(
kubeClient, podmanClient, lo.namespaceFilter, devfileObj, componentName)
if err != nil {
return api.ResourcesList{}, err
}

// RunningOn is displayed only when RunOn is active
if !feature.IsEnabled(ctx, feature.GenericRunOnFlag) {
for i := range allComponents {
allComponents[i].RunningOn = ""
}
}
return api.ResourcesList{
ComponentInDevfile: componentInDevfile,
Components: devfileComponents,
Components: allComponents,
}, nil
}

// NewCmdList implements the list odo command
func NewCmdComponentList(name, fullName string) *cobra.Command {
func NewCmdComponentList(ctx context.Context, name, fullName string) *cobra.Command {
o := NewListOptions()

var listCmd = &cobra.Command{
Expand All @@ -133,15 +153,18 @@ func NewCmdComponentList(name, fullName string) *cobra.Command {
Aliases: []string{"components"},
}
clientset.Add(listCmd, clientset.KUBERNETES_NULLABLE, clientset.FILESYSTEM)

if feature.IsEnabled(ctx, feature.GenericRunOnFlag) {
clientset.Add(listCmd, clientset.PODMAN_NULLABLE)
}
listCmd.Flags().StringVar(&o.namespaceFlag, "namespace", "", "Namespace for odo to scan for components")

commonflags.UseOutputFlag(listCmd)
commonflags.UseRunOnFlag(listCmd)

return listCmd
}

func HumanReadableOutput(list api.ResourcesList) {
func HumanReadableOutput(ctx context.Context, list api.ResourcesList) {
components := list.Components
if len(components) == 0 {
log.Error("There are no components deployed.")
Expand All @@ -151,7 +174,11 @@ func HumanReadableOutput(list api.ResourcesList) {
t := ui.NewTable()

// Create the header and then sort accordingly
t.AppendHeader(table.Row{"NAME", "PROJECT TYPE", "RUNNING IN", "MANAGED"})
headers := table.Row{"NAME", "PROJECT TYPE", "RUNNING IN", "MANAGED"}
if feature.IsEnabled(ctx, feature.GenericRunOnFlag) {
headers = append(headers, "RUNNING ON")
}
t.AppendHeader(headers)
t.SortBy([]table.SortBy{
{Name: "MANAGED", Mode: table.Asc},
{Name: "NAME", Mode: table.Dsc},
Expand Down Expand Up @@ -190,7 +217,17 @@ func HumanReadableOutput(list api.ResourcesList) {
managedBy = text.Colors{text.FgBlue}.Sprintf(managedBy)
}

t.AppendRow(table.Row{name, componentType, mode, managedBy})
row := table.Row{name, componentType, mode, managedBy}

if feature.IsEnabled(ctx, feature.GenericRunOnFlag) {
runningOn := comp.RunningOn
if runningOn == "" {
runningOn = "None"
}
row = append(row, runningOn)
}

t.AppendRow(row)
}
t.Render()

Expand Down
Loading