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

Watch for devfile dependencies #6020

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
20 changes: 20 additions & 0 deletions pkg/libdevfile/generator/component.go
Original file line number Diff line number Diff line change
Expand Up @@ -70,3 +70,23 @@ func GetKubernetesComponent(params KubernetesComponentParams) v1alpha2.Component
}
return cmp
}

type OpenshiftComponentParams struct {
Name string
Attributes *attributes.Attributes

Openshift *v1alpha2.OpenshiftComponent
}

func GetOpenshiftComponent(params OpenshiftComponentParams) v1alpha2.Component {
cmp := v1alpha2.Component{
Name: params.Name,
ComponentUnion: v1alpha2.ComponentUnion{
Openshift: params.Openshift,
},
}
if params.Attributes != nil {
cmp.Attributes = *params.Attributes
}
return cmp
}
22 changes: 22 additions & 0 deletions pkg/libdevfile/testdata/child-devfile-commands-only.yaml
Original file line number Diff line number Diff line change
@@ -0,0 +1,22 @@
schemaVersion: 2.1.0
metadata:
name: child
parent:
uri: parent/parent-devfile-components-only.yaml
commands:
- exec:
commandLine: GOCACHE=${PROJECT_SOURCE}/.cache go build main.go
component: runtime
group:
isDefault: true
kind: build
workingDir: ${PROJECT_SOURCE}
id: build
- exec:
commandLine: ./main
component: runtime
group:
isDefault: true
kind: run
workingDir: ${PROJECT_SOURCE}
id: run
34 changes: 34 additions & 0 deletions pkg/libdevfile/testdata/child-devfile-complete.yaml
Original file line number Diff line number Diff line change
@@ -0,0 +1,34 @@
commands:
- exec:
commandLine: GOCACHE=${PROJECT_SOURCE}/.cache go build main.go
component: runtime
group:
isDefault: true
kind: build
workingDir: ${PROJECT_SOURCE}
id: build
- exec:
commandLine: ./main
component: runtime
group:
isDefault: true
kind: run
workingDir: ${PROJECT_SOURCE}
id: run
components:
- container:
endpoints:
- name: http
targetPort: 8080
image: quay.io/devfile/golang:latest
memoryLimit: 1024Mi
mountSources: true
name: runtime
- kubernetes:
uri: "manifest.yaml"
name: kube-cmp
metadata:
name: my-go-app
schemaVersion: 2.1.0
parent:
uri: parent/parent-devfile-empty.yaml
17 changes: 17 additions & 0 deletions pkg/libdevfile/testdata/child-devfile-components-only.yaml
Original file line number Diff line number Diff line change
@@ -0,0 +1,17 @@
schemaVersion: 2.1.0
metadata:
name: child
parent:
uri: "parent/parent-devfile-commands-only.yaml"
components:
- container:
endpoints:
- name: http
targetPort: 8080
image: quay.io/devfile/golang:latest
memoryLimit: 1024Mi
mountSources: true
name: runtime
- kubernetes:
uri: "manifest.yaml"
name: kube-cmp
5 changes: 5 additions & 0 deletions pkg/libdevfile/testdata/child-devfile.yaml
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
schemaVersion: 2.1.0
metadata:
name: child
parent:
uri: "parent/parent-devfile.yaml"
20 changes: 20 additions & 0 deletions pkg/libdevfile/testdata/parent/parent-devfile-commands-only.yaml
Original file line number Diff line number Diff line change
@@ -0,0 +1,20 @@
commands:
- exec:
commandLine: GOCACHE=${PROJECT_SOURCE}/.cache go build main.go
component: runtime
group:
isDefault: true
kind: build
workingDir: ${PROJECT_SOURCE}
id: build
- exec:
commandLine: ./main
component: runtime
group:
isDefault: true
kind: run
workingDir: ${PROJECT_SOURCE}
id: run
schemaVersion: 2.1.0
metadata:
name: parent
15 changes: 15 additions & 0 deletions pkg/libdevfile/testdata/parent/parent-devfile-components-only.yaml
Original file line number Diff line number Diff line change
@@ -0,0 +1,15 @@
components:
- container:
endpoints:
- name: http
targetPort: 8080
image: quay.io/devfile/golang:latest
memoryLimit: 1024Mi
mountSources: true
name: runtime
- kubernetes:
uri: "manifest.yaml"
name: kube-cmp
metadata:
name: my-go-app
schemaVersion: 2.1.0
3 changes: 3 additions & 0 deletions pkg/libdevfile/testdata/parent/parent-devfile-empty.yaml
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
metadata:
name: my-go-app
schemaVersion: 2.1.0
32 changes: 32 additions & 0 deletions pkg/libdevfile/testdata/parent/parent-devfile.yaml
Original file line number Diff line number Diff line change
@@ -0,0 +1,32 @@
commands:
- exec:
commandLine: GOCACHE=${PROJECT_SOURCE}/.cache go build main.go
component: runtime
group:
isDefault: true
kind: build
workingDir: ${PROJECT_SOURCE}
id: build
- exec:
commandLine: ./main
component: runtime
group:
isDefault: true
kind: run
workingDir: ${PROJECT_SOURCE}
id: run
components:
- container:
endpoints:
- name: http
targetPort: 8080
image: quay.io/devfile/golang:latest
memoryLimit: 1024Mi
mountSources: true
name: runtime
- kubernetes:
uri: "manifest.yaml"
name: kube-cmp
metadata:
name: my-go-app
schemaVersion: 2.1.0
123 changes: 123 additions & 0 deletions pkg/libdevfile/uris.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,123 @@
package libdevfile

import (
"errors"
"net/url"
"sort"
"strings"

"github.com/devfile/api/v2/pkg/apis/workspaces/v1alpha2"
"github.com/devfile/api/v2/pkg/attributes"
"github.com/devfile/api/v2/pkg/validation"
"github.com/devfile/library/pkg/devfile/parser"
"github.com/devfile/library/pkg/devfile/parser/data/v2/common"
)

const _importSourceAttributeUriPrefix = "uri: "

// GetReferencedLocalFiles returns the local files referenced by the Devfile. This includes:
// - the non-inlined Kubernetes and Openshift components
// - the Dockerfiles of Image components
// - the parent devfile
// - resursively, the local files referenced by the parent Devfile
// The passed Devfile must be flattened
func GetReferencedLocalFiles(devfileObj parser.DevfileObj) (result []string, err error) {

setResult := map[string]struct{}{}

parent := devfileObj.Data.GetParent()
if parent != nil {
return nil, errors.New("devfile must be flattened")
}

components, err := devfileObj.Data.GetComponents(common.DevfileOptions{})
if err != nil {
return nil, err
}

for _, component := range components {
var componentType v1alpha2.ComponentType
componentType, err = common.GetComponentType(component)
if err != nil {
return nil, err
}

switch componentType {
case v1alpha2.KubernetesComponentType:
setResult, err = appendUriIfFile(setResult, component.Kubernetes.Uri)
if err != nil {
return nil, err
}

case v1alpha2.OpenshiftComponentType:
setResult, err = appendUriIfFile(setResult, component.Openshift.Uri)
if err != nil {
return nil, err
}

case v1alpha2.ImageComponentType:
if component.Image.Dockerfile != nil {
setResult, err = appendUriIfFile(setResult, component.Image.Dockerfile.Uri)
if err != nil {
return nil, err
}
}
}

setResult, err = getFromAttributes(setResult, component.Attributes)
if err != nil {
return nil, err
}
}

commands, err := devfileObj.Data.GetCommands(common.DevfileOptions{})
if err != nil {
return nil, err
}
for _, command := range commands {
setResult, err = getFromAttributes(setResult, command.Attributes)
if err != nil {
return nil, err
}
}

result = make([]string, 0, len(setResult))
for k := range setResult {
result = append(result, k)
}
sort.Strings(result)
return result, nil
}

// appendUriIfFile appends uri to the result if the uri is a local path
func appendUriIfFile(result map[string]struct{}, uri string) (map[string]struct{}, error) {
if uri != "" {
u, err := url.Parse(uri)
if err != nil {
return nil, err
}
if u.Scheme == "" {
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Just curious - is the file URI scheme something possible here to reference local files? Or should we always expect files relative to the devfile.yaml? The Devfile spec is pretty vague about this:

Location in a file fetched from a uri.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I'm pretty sure it is related to the directory containing the devfile. For example, the doc for parent URI is:

URI Reference of a parent devfile YAML file. It can be a full URL or a relative URI with the current devfile as the base URI.

result[uri] = struct{}{}
}
}
return result, nil
}

// getFromAttributes extracts paths from attributes entries with key "api.devfile.io/imported-from"
// containing a uri reference as a local path
func getFromAttributes(result map[string]struct{}, attributes attributes.Attributes) (map[string]struct{}, error) {
if val, ok := attributes[validation.ImportSourceAttribute]; ok {
strVal := string(val.Raw)
strVal = strings.Trim(strVal, `"`)
if strings.HasPrefix(strVal, _importSourceAttributeUriPrefix) {
parentUri := strings.TrimLeft(strVal, _importSourceAttributeUriPrefix)
var err error
result, err = appendUriIfFile(result, parentUri)
if err != nil {
return nil, err
}
}
}

return result, nil
}
Loading