Odo: devfile component created out of java-quarkus component contains url with invalid name `8080/http`

Created on 19 Oct 2020  ยท  25Comments  ยท  Source: openshift/odo

/kind bug

What versions of software are you using?

Operating System: Linux

Output of odo version: odo 2.0.0

How did you run odo exactly?

```odo crate java-quarkus --starter
Validation
โœ“ Checking devfile existence [32581ns]
โœ“ Checking devfile compatibility [42265ns]
โœ“ Creating a devfile component from registry: DefaultDevfileRegistry [47653ns]
โœ“ Validating devfile component [96807ns]

Starter Project
โœ“ Downloading starter project quarkus-ex from https://github.com/odo-devfiles/quarkus-ex [687ms]

Please use odo push command to create the component with source deployed


## Actual behavior

In not pushed state odo describe returns 8080/http name for the URL

```odo describe-o json
{
        "kind": "Component",
        "apiVersion": "odo.dev/v1alpha1",
        "metadata": {
                "name": "java-quarkus",
                "namespace": "myproject",
                "creationTimestamp": null
        },
        "spec": {
                "app": "app",
                "type": "java-quarkus",
                "urls": {
                        "kind": "List",
                        "apiVersion": "odo.dev/v1alpha1",
                        "metadata": {},
                        "items": [
                                {
                                        "kind": "url",
                                        "apiVersion": "odo.dev/v1alpha1",
                                        "metadata": {
                                                "name": "8080/http",
                                                "creationTimestamp": null
                                        },
                                        "spec": {
                                                "port": 8080,
                                                "secure": false,
                                                "kind": "route"
                                        },
                                        "status": {
                                                "state": "Not Pushed"
                                        }
                                }
                        ]
                },
                "storages": {
                        "kind": "List",
                        "apiVersion": "odo.dev/v1alpha1",
                        "metadata": {},
                        "items": [
                                {
                                        "kind": "storage",
                                        "apiVersion": "odo.dev/v1alpha1",
                                        "metadata": {
                                                "name": "m2",
                                                "creationTimestamp": null
                                        },
                                        "spec": {
                                                "size": "3Gi",
                                                "path": "/home/user/.m2",
                                                "containerName": "tools"
                                        }
                                }
                        ]
                },
                "ports": [
                        "5858"
                ]
        },
        "status": {
                "state": "Not Pushed"
        }
}

even with url name '8080/http` devfile validation goes through without errors

odo" push

Validation
 โœ“  Validating the devfile [40656ns]

Creating Kubernetes resources for component java-quarkus
 โœ“  Waiting for component to start [5s]

Applying URL changes
 โœ“  URL 8080-http: http://8080-http-java-quarkus-myproject.apps-crc.testing/ created

Syncing to component java-quarkus
 โœ“  Checking files for pushing [1ms]
 โœ“  Syncing files to the component [146ms]

Executing postStart event commands for component java-quarkus
 โœ“  Executing init-compile command "mvn -Dmaven.repo.local=/home/user/.m2/repository compile" [39s]

Executing devfile commands for component java-quarkus
 โœ“  Executing dev-run command "mvn -Dmaven.repo.local=/home/user/.m2/repository quarkus:dev", if not running [1s]

Pushing devfile component java-quarkus
 โœ“  Changes successfully pushed to component

After push odo describe returns 8080-http name for the component's URL

odo describe -o json
{
        "kind": "Component",
        "apiVersion": "odo.dev/v1alpha1",
        "metadata": {
                "name": "java-quarkus",
                "namespace": "myproject",
                "creationTimestamp": null
        },
        "spec": {
                "app": "app",
                "type": "java-quarkus",
                "urls": {
                        "kind": "List",
                        "apiVersion": "odo.dev/v1alpha1",
                        "metadata": {},
                        "items": [
                                {
                                        "kind": "url",
                                        "apiVersion": "odo.dev/v1alpha1",
                                        "metadata": {
                                                "name": "8080-http",
                                                "creationTimestamp": null
                                        },
                                        "spec": {
                                                "host": "8080-http-java-quarkus-myproject.apps-crc.testing",
                                                "protocol": "http",
                                                "port": 8080,
                                                "secure": false,
                                                "kind": "route",
                                                "path": "/"
                                        },
                                        "status": {
                                                "state": "Pushed"
                                        }
                                }
                        ]
                },
                "storages": {
                        "kind": "List",
                        "apiVersion": "odo.dev/v1alpha1",
                        "metadata": {},
                        "items": [
                                {
                                        "kind": "storage",
                                        "apiVersion": "odo.dev/v1alpha1",
                                        "metadata": {
                                                "name": "m2",
                                                "creationTimestamp": null
                                        },
                                        "spec": {
                                                "size": "3Gi",
                                                "path": "/home/user/.m2",
                                                "containerName": "tools"
                                        }
                                }
                        ]
                },
                "env": [
                        {
                                "name": "PROJECTS_ROOT",
                                "value": "/projects"
                        },
                        {
                                "name": "DEBUG_PORT",
                                "value": "5858"
                        }
                ],
                "ports": [
                        "5858"
                ]
        },
        "status": {
                "state": "Pushed"
        }
}

Expected behavior

If 8080/http should be originally 8080-http right after component is created. That name 8080/http with '/' should be caught during validation rather than replaced to 8080-http during deployment.

Any logs, error output, etc?

N/A

areadapter kinbug

Most helpful comment

I like the idea that odo is smart enough to do this but I also see that is kind of work would make it less transparent to odo. So while we get to the conclusion of things I have opened a PR to rename 8080/http to 8080-http.
registry PR link - https://github.com/odo-devfiles/registry/pull/58

All 25 comments

I like the idea that odo is smart enough to do this but I also see that is kind of work would make it less transparent to odo. So while we get to the conclusion of things I have opened a PR to rename 8080/http to 8080-http.
registry PR link - https://github.com/odo-devfiles/registry/pull/58

@kadel I was think what if this conversion is done when the devfile is downloaded so the moment someone uses any other commands they see - 8080-http instead of 8080/http. This can be done as part of post validation work in the parser?

actually I remembered that we need to decouple the url created from the name of the url. the name of the url should be "8080/http" but the url should have "8080-http". but this shouldn't change the name of the url to "8080-http"

so I tried doing the above where the name stays 8080/http but the metadata.name for the route becomes 8080/http-java-quarkus
which is invalid with error

unable to create route: error creating route: Route.route.openshift.io "8080/http-java-quarkus" is invalid: [metadata.name: Invalid value: "8080/http-java-quarkus": a DNS-1123 subdomain must consist of lower case alphanumeric characters

so now we either change the 8080/http the moment we download the devfile or we fail on validation @kadel

blocked on the decision

so now we either change the 8080/http the moment we download the devfile or we fail on validation @kadel

We should not change it. If the name is defined as 8080/http it either needs to stay like this or the validation needs to fail.
This depends on Devfile spec. Assuming the current definition where the endpoint name is just plain string without any other restriction the correct way is not to fail.

The problem is that we use an endpoint name for Ingress/Route name. We need to decouple these two fields.
When the Ingres/Route is generated we should generate valid metadata.name for Kubernetes resource (this can be based on endpoint name). And save the actual name as a label. From that point, the label value should be considered as an URL name.

If the user runs odo url create 8080/http or if devfile contains endpoint with name: 8080/http the odo should generate Ingress or Route with label odo.openshift.io/url-name: 8080/http.
We should use the value of this label everywhere in odo as an URL name (including in env.yaml).

If odo needs to query Cluster for url, it shouldn't query for the resource name, but it should always use label selectors.
For example, if odo needs a list of all URLs for a component named frontend in application myapp it should list all Ingress and Routes that have app.kubernetes.io/instance: frontend and app.kubernetes.io/part-of: myapp labels and in the output display values from odo.openshift.io/url-name label.
metadata.name should not play any role in this. Even if we would start using random generated metada.name everything should keep working (not suggesting that we should do this :-) )

yeah but the approach you are mentioning will break existing urls present in working devfile components. any transition plans? or plain old delete and create again?

So the approach with labels won't work :/ Label values must be alphanumeric with _ - . no other characters are allowed.
The only place we can store URL name in the cluster is as annotations, everything else will have restrictions.
I've opened an issue on the Devfile spec repo about this

one approach that came out of the discussion was to store the name in the annotations, but then the odo.openshift.io/url-name becomes an annotation and cannot be used in label selector so we can store

url-identifier in the label ( url-name would be misleading ) which converts / to - so label selection is possible and we have annotation that we use as a name.

We could have gone with just adding a validation for the url name but the architectural reasoning that @kadel provided was that we cannot drive the validation rules in the devfile spec based on odo's implementation detail.

I am thinking if I change many things in the url package that might conflict with the url refactor.

@kadel It is really a big usability problem right now. It affects especially initial user experience for quarkus projects. Because right after creating the project this leads to problems to open it in browser and new users left hanging with project that looks totally broken without no easy way out.

Is that possible as a hot fix just update url name in devfile to be the same as after deployment?

@dgolovin as we changed the url from 8080/http to 8080-http in quarkus to temporarily resolve the problem so currently is this an urgent issue?

@girishramnani just verified it. Works for me OOTB now.

A long term solution is needed here or else we would be changing devfiles in future whenever this occurs

solution -

one approach that came out of the discussion was to store the name in the annotations, but then the odo.openshift.io/url-name becomes an annotation and cannot be used in label selector so we can store

url-identifier in the label ( url-name would be misleading ) which converts / to - so label selection is possible and we have annotation that we use as a name.

We could have gone with just adding a validation for the url name but the architectural reasoning that @kadel provided was that we cannot drive the validation rules in the devfile spec based on odo's implementation detail.

Also this solution would be a breaking change - would break existing components

I've opened an issue on the Devfile spec repo about this

Can you share the issue number please? @kadel

Moving this out of this sprint for time being since the discussion and inputs need to come in from different teams involved in this.

the devfile spec was updated https://github.com/devfile/api/issues/201 Name and Id need to follow the same rules ad k8s names

so then this is a non-issue now? or we need to update the devfile library to close this issue? @kadel ?

Added to sprint just so we can discuss if we need to close this issue

So the idea here is that we need to validate if the current version of api ( currently in odo ) enforces the validation mentioned in https://github.com/devfile/api/issues/201 - if so then we can close this issue or else
the scope of this issue would be upgrade to the latest version of api

so to confirm this I created a nodejs devfile and changed the endpoint to look like this

      endpoints:
        - name: 3000/http
          targetPort: 3000

which is invalid.

And when I tried to push this devfile it failed

odo push
 โœ—  invalid devfile schema. errors :
- components.0.container.endpoints.0.name: Does not match pattern '^[a-z0-9]([-a-z0-9]*[a-z0-9])?$'

Now its not the most descriptive of errors but does enforce the validation. Should I consider this to complete the AC of this issue @kadel or we wanna enhance something here?

it gets cought in odo create

odo create nodejs --devfile devfile.yaml 
Devfile Object Validation
 โœ“  Creating a devfile component from devfile path: /Users/girish/GoProjects/src/github.com/openshift/odo/ts2/devfile.yaml [61260ns]
Validation
 โœ“  Validating if devfile name is correct [34581ns]
 โœ—  invalid devfile schema. errors :
- components.0.container.endpoints.0.name: Does not match pattern '^[a-z0-9]([-a-z0-9]*[a-z0-9])?$'

Confirmed that this should close the issue

Was this page helpful?
0 / 5 - 0 ratings