Skip to content

Commit

Permalink
odo list follow up implementation (#3964)
Browse files Browse the repository at this point in the history
* initial work

* build the repr for devfile when walking the path

* introduce the devfile component

* make devfile component similar to s2i component

* resolve unit test

* major refactor and implement json out for standard components

* resolve lint

* use shorter check

* resolved some bugs

* resolve failing unit test

* resolve failing tests

* addressed denis's suggestions

* resolved failing intg tests

* resolve failing tests

* debug error

* add debugging

* more logging

* set namespace in kclient

* removed debugging

* addressed cdrage's comment
  • Loading branch information
girishramnani authored Sep 22, 2020
1 parent b3c126d commit a28e378
Show file tree
Hide file tree
Showing 13 changed files with 294 additions and 116 deletions.
96 changes: 86 additions & 10 deletions pkg/component/component.go
Original file line number Diff line number Diff line change
Expand Up @@ -4,15 +4,17 @@ import (
"bufio"
"bytes"
"fmt"
devfileParser "github.com/openshift/odo/pkg/devfile/parser"
"io"
"os"
"path/filepath"
"sort"
"strings"
"time"

devfileParser "github.com/openshift/odo/pkg/devfile/parser"

"github.com/openshift/odo/pkg/devfile/adapters/common"
"github.com/openshift/odo/pkg/devfile/parser"
"github.com/openshift/odo/pkg/kclient"

"github.com/openshift/odo/pkg/envinfo"
Expand Down Expand Up @@ -986,7 +988,7 @@ func getComponentFrom(info envinfo.LocalConfigProvider, componentType string) Co
}

// ListIfPathGiven lists all available component in given path directory
func ListIfPathGiven(client *occlient.Client, paths []string) (ComponentList, error) {
func ListIfPathGiven(client *occlient.Client, paths []string) ([]Component, error) {
var components []Component
var err error
for _, path := range paths {
Expand Down Expand Up @@ -1025,7 +1027,62 @@ func ListIfPathGiven(client *occlient.Client, paths []string) (ComponentList, er
})

}
return GetMachineReadableFormatForList(components), err
return components, err
}

func ListDevfileComponentsInPath(client *kclient.Client, paths []string) ([]DevfileComponent, error) {
var components []DevfileComponent
var err error
for _, path := range paths {
err = filepath.Walk(path, func(path string, f os.FileInfo, err error) error {
// we check for .odo/env/env.yaml folder first and then find devfile.yaml, this could be changed
// TODO: optimise this
if f != nil && strings.Contains(f.Name(), ".odo") {
// lets find if there is a devfile and an env.yaml
dir := filepath.Dir(path)
data, err := envinfo.NewEnvSpecificInfo(dir)
if err != nil {
return err
}

// if the .odo folder doesn't contain a proper env file
if data.GetName() == "" || data.GetApplication() == "" || data.GetNamespace() == "" {
return nil
}

// we just want to confirm if the devfile is correct
_, err = parser.Parse(filepath.Join(dir, "devfile.yaml"))
if err != nil {
return err
}
con, _ := filepath.Abs(filepath.Dir(path))

comp := NewDevfileComponent(data.GetName())
comp.Status.State = StateTypeUnknown
comp.Spec.App = data.GetApplication()
comp.Namespace = data.GetNamespace()
comp.Spec.Name = data.GetName()
comp.Status.Context = con

// since the config file maybe belong to a component of a different project
if client != nil {
client.Namespace = data.GetNamespace()
deployment, err := client.GetDeploymentByName(data.GetName())
if err != nil {
comp.Status.State = StateTypeNotPushed
} else if deployment != nil {
comp.Status.State = StateTypePushed
}
}

components = append(components, comp)
}

return nil
})

}
return components, err
}

// GetComponentSource what source type given component uses
Expand Down Expand Up @@ -1337,9 +1394,8 @@ func GetComponentState(client *occlient.Client, componentName, applicationName s
}
if c != nil {
return StateTypePushed
} else {
return StateTypeNotPushed
}
return StateTypeNotPushed
}

// GetComponent provides component definition
Expand Down Expand Up @@ -1476,20 +1532,40 @@ func getMachineReadableFormat(componentName, componentType string) Component {

}

// GetMachineReadableFormatForList returns list of components in machine readable format
func GetMachineReadableFormatForList(components []Component) ComponentList {
if len(components) == 0 {
components = []Component{}
// GetMachineReadableFormatForList returns list of devfile and s2i components in machine readable format
func GetMachineReadableFormatForList(s2iComps []Component) ComponentList {
if len(s2iComps) == 0 {
s2iComps = []Component{}
}

return ComponentList{
TypeMeta: metav1.TypeMeta{
Kind: "List",
APIVersion: apiVersion,
},
ListMeta: metav1.ListMeta{},
Items: components,
Items: s2iComps,
}
}

// GetMachineReadableFormatForCombinedCompList returns list of devfile and s2i components in machine readable format
func GetMachineReadableFormatForCombinedCompList(s2iComps []Component, devfileComps []DevfileComponent) CombinedComponentList {
if len(s2iComps) == 0 {
s2iComps = []Component{}
}
if len(devfileComps) == 0 {
devfileComps = []DevfileComponent{}
}

return CombinedComponentList{
TypeMeta: metav1.TypeMeta{
Kind: "List",
APIVersion: apiVersion,
},
ListMeta: metav1.ListMeta{},
S2IComponents: s2iComps,
DevfileComponents: devfileComps,
}
}

// getStorageFromConfig gets all the storage from the config
Expand Down
41 changes: 41 additions & 0 deletions pkg/component/devfile_component.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,41 @@
package component

import (
applabels "github.com/openshift/odo/pkg/application/labels"
componentlabels "github.com/openshift/odo/pkg/component/labels"
"github.com/openshift/odo/pkg/config"
appsv1 "k8s.io/api/apps/v1"
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
)

func NewDevfileComponent(componentName string) DevfileComponent {
return DevfileComponent{
TypeMeta: metav1.TypeMeta{
Kind: "DevfileComponent",
APIVersion: apiVersion,
},
ObjectMeta: metav1.ObjectMeta{
Name: componentName,
},
Spec: DevfileComponentSpec{
SourceType: string(config.LOCAL),
},
}
}

func DevfileComponentsFromDeployments(deployList *appsv1.DeploymentList) []DevfileComponent {
compList := []DevfileComponent{}
for _, deployment := range deployList.Items {
app := deployment.Labels[applabels.ApplicationLabel]
cmpType := deployment.Labels[componentlabels.ComponentTypeLabel]

comp := NewDevfileComponent(deployment.Name)
comp.Status.State = StateTypePushed
comp.Namespace = deployment.Namespace
comp.Spec.App = app
comp.Spec.Type = cmpType
comp.Spec.Name = deployment.Name
compList = append(compList, comp)
}
return compList
}
Original file line number Diff line number Diff line change
@@ -1,14 +1,15 @@
package parser
package component

import (
"github.com/openshift/odo/pkg/config"
"github.com/openshift/odo/pkg/devfile/parser"
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
)

func (d DevfileObj) ToRepresentation() ConfigurableRepr {
func ToDevfileRepresentation(d parser.DevfileObj) ConfigurableRepr {
confRepr := ConfigurableRepr{
Name: d.getMetadataName(),
Memory: d.getMemory(),
Name: d.GetMetadataName(),
Memory: d.GetMemory(),
}
var contReprs []ContainerRepr
components := d.Data.GetComponents()
Expand Down Expand Up @@ -38,7 +39,7 @@ func (d DevfileObj) ToRepresentation() ConfigurableRepr {
return confRepr
}

func (d DevfileObj) WrapFromJSONOutput(confRepr ConfigurableRepr) JSONConfigRepr {
func WrapFromJSONOutput(confRepr ConfigurableRepr) JSONConfigRepr {
return JSONConfigRepr{
TypeMeta: metav1.TypeMeta{
Kind: "DevfileConfiguration",
Expand Down
1 change: 1 addition & 0 deletions pkg/component/pushed_component.go
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@ package component

import (
"fmt"

appsv1 "github.com/openshift/api/apps/v1"
applabels "github.com/openshift/odo/pkg/application/labels"
componentlabels "github.com/openshift/odo/pkg/component/labels"
Expand Down
24 changes: 23 additions & 1 deletion pkg/component/types.go
Original file line number Diff line number Diff line change
Expand Up @@ -40,7 +40,29 @@ type ComponentStatus struct {
LinkedServices []string `json:"linkedServices,omitempty"`
}

// State represents component state
// CombinedComponentList is list of s2i and devfile components
type CombinedComponentList struct {
metav1.TypeMeta `json:",inline"`
metav1.ListMeta `json:"metadata,omitempty"`
S2IComponents []Component `json:"s2iComponents"`
DevfileComponents []DevfileComponent `json:"devfileComponents"`
}

type DevfileComponent struct {
metav1.TypeMeta `json:",inline"`
metav1.ObjectMeta `json:"metadata,omitempty"`
Spec DevfileComponentSpec `json:"spec,omitempty"`
Status ComponentStatus `json:"status,omitempty"`
}

type DevfileComponentSpec struct {
Name string `json:"componentName,omitempty"`
App string `json:"app,omitempty"`
Type string `json:"type,omitempty"`
SourceType string `json:"sourceType,omitempty"`
}

// State reperesents component state
type State string

const (
Expand Down
8 changes: 4 additions & 4 deletions pkg/devfile/parser/configurables.go
Original file line number Diff line number Diff line change
Expand Up @@ -75,11 +75,11 @@ func (d DevfileObj) IsSet(parameter string) bool {
if parameter, ok := AsDevfileSupportedParameter(parameter); ok {
switch parameter {
case "name":
return d.getMetadataName() != ""
return d.GetMetadataName() != ""
case "ports":
return d.hasPorts()
case "memory":
return d.getMemory() != ""
return d.GetMemory() != ""
}
}
return false
Expand Down Expand Up @@ -171,7 +171,7 @@ func (d DevfileObj) setMemory(memory string) error {
}
return d.WriteYamlDevfile()
}
func (d DevfileObj) getMemory() string {
func (d DevfileObj) GetMemory() string {
components := d.Data.GetComponents()
for _, component := range components {
if component.Container != nil {
Expand All @@ -184,7 +184,7 @@ func (d DevfileObj) getMemory() string {
return ""
}

func (d DevfileObj) getMetadataName() string {
func (d DevfileObj) GetMetadataName() string {
return d.Data.GetMetadata().Name
}

Expand Down
5 changes: 5 additions & 0 deletions pkg/envinfo/envinfo.go
Original file line number Diff line number Diff line change
Expand Up @@ -432,6 +432,11 @@ func (ei *EnvInfo) GetApplication() string {
return ei.componentSettings.AppName
}

// MatchComponent matches a component information provided by a devfile compoment with the local env info
func (ei *EnvInfo) MatchComponent(name, app, namespace string) bool {
return name == ei.GetName() && app == ei.GetApplication() && namespace == ei.GetNamespace()
}

// GetLink returns the EnvInfoLink, returns default if nil
func (ei *EnvInfo) GetLink() []EnvInfoLink {
if ei.componentSettings.Link == nil {
Expand Down
Loading

0 comments on commit a28e378

Please sign in to comment.