Odo: unable to push devfile, if there is no .odo

Created on 6 Apr 2020  Â·  18Comments  Â·  Source: openshift/odo

I have a project that contains devfile.yaml but no .odo.

The .odo directory should not be required!

â–¶ odo push
 ✗  The current directory does not represent an odo component. Use 'odo create' to create component here or switch to directory with a component

/area devfile
/priority high
/area component

arecomponent aredevfile has-user-story kinbug prioritHigh triagready

All 18 comments

ping @GeekArthur

@yangcao77 Can you explain this to @kadel as this error handling is from your url PR #2762 ?

This is an expected behavior. .odo folder is required for devfile component.
Same as odo1 component, odo2 component requires odo create before other commands being executed.
odo create would save the component's namespace and also component's name into the env.yaml file under .odo/env/.
Any resources creation actions would need those information.

odo create would save the component's namespace and also component's name into the env.yaml file under .odo/env/.
Any resources creation actions would need those information.

If I already have a devfile.yaml .odo/env/. should not be required to get the application running.
All values in .odo/env/ should have sensible defaults or autodetected.

  • For component name we can use directory name.
  • Namespace shoudl not be required either as by default the currently active namespace as it is set in KUBECONFIG should be used. (see https://github.com/openshift/odo/issues/2285#issuecomment-597177628)
  • Even for URLs we don't need (almost) anything in .odo/env/ if there is a previewURL in devfile #2858 . Saying almost because url on k8s will require a host which can't be stored in devfile. The solution is described in #2858

Namespace is not a required parameter, but is expected to save in env.yaml file. If we always use the currently active namespace and do not have a static namespace for the component, it would cause errors. (We've seen that error in our PR build, because the tests run in parallel, and the namespace switches.)
We want user to run odo create before any other commands, so we can assume a devfile already exist for other commands that requires a devfile. (e.g. push, or url creation/deletion with a --now flag). And we can also assume the componentName and namespace is defined.

But if a devfile already exist, but env.yaml not. Even if we can use the currently active namespace and use directory name as component name, we still need to write the component name & namespace into env.yaml to avoid user runningodo create again with a different component name, or namespace switching.
That means, for all commands, we need to check the env.yaml file and write those two info if the file does not exist.
@elsony Any thoughts?

Namespace is not a required parameter, but is expected to save in env.yaml file. If we always use the currently active namespace and do not have a static namespace for the component, it would cause errors. (We've seen that error in our PR build, because the tests run in parallel, and the namespace switches.)

You could still optionally run odo create --project myproject to set the namespace in env.yaml. But by default, it won't be set.
Otherwise, it feels a little bit weird if you do this:

odo project create myproject1
odo component create java mycomponent
odo push
# now I want to push this component to a different project
odo project create myproject2
odo push
# NOT OK: this will push it again to myproject1

But maybe it is just me and we can solve it with some clear messaging like adding output to odo create that it will explain that the namespace was "permanently" and also explicitly saying in the odo push output to what namespace we are pushing it.

The following behavior seems more natural to me:

odo project create myproject
odo component create java mycomponent
odo push

# now I want to push this component to different project
odo project create myproject2
odo push
# OK: pushed to myproject2


# Now I have decided that I want to always use project1
odo config set project myproject1
odo push
# now push will always push to myproject1
# I want to always push to specific project
odo project create myproject1
odo component create java mycomponent --project myproject1
# the previous command will save the `namespace: myproject1` to `env.yaml`
odo push
# OK: pushing to  myproject1

odo project create myproject2
odo push 
# OK: still pushing to myproject1 because it is set in `env.yaml`

We want user to run odo create before any other commands, so we can assume a devfile already exist for other commands that requires a devfile. (e.g. push, or url creation/deletion with a --now flag). And we can also assume the componentName and namespace is defined.

Devfile can exist even before odo create is executed one of the important cases that we need to support is when there already is a devfile in the repo (user might create its own, or it was populated by some other tool like Che for example).

Starting from existing repo with devfile.yaml needs to be as simple as git clone https://github.com/example/example && odo push

If I run odo create ... in non-interactive mode I get error ✗ This directory already contains a devfile.yaml, please delete it and run the component creation command again

I see odo create command as a bootstrapping command that will help me get started and generate devfile.yaml and optionally env.yaml for me.

If someone already used odo create and created the devfile.yaml, and then pushed it to the git repo (.odo/env should never be committed to git) I should be able to run just odo push without running odo create again.

We could do something in between.

  • odo push will work without .odo/env/env.yaml with defaults as described before.
  • odo create in a directory without devfile.yaml will work as it does now. It always populates .odo/env/env.yaml with current namespace and other values.
  • odo config set project, odo config set name will set a namespace and component name in env.yaml even in a directory without .odo but with already existing devfile.yaml. This will essentially bootstrap the full odo component allowing anyone to start with existing devfile.yaml and add some odo specific configurations.

Namespace is not a required parameter, but is expected to save in env.yaml file. If we always use the currently active namespace and do not have a static namespace for the component, it would cause errors.

odo push will work without .odo/env/env.yaml with defaults as described before.

Can we make odo push smart enough to check if .odo/env/env.yaml is present in the directory? If it's not present but devfile.yaml is present, can odo push automagically create .odo/env/env.yaml with some well-informed defaults?

By well-informed defaults I mean:

  • it should use project/namespace which is currently set in the KUBECONFIG.
  • it should create a component name based on pwd (but I have a reservation against this and would suggest some random string getting appended to component name otherwise a user might have two different nodejs components for two different directories at /home/dshah/project1/nodejs and /home/dshah/project2/nodejs. We can do something similar to what metadata.generateName does for other use cases. This will create one component named nodejs-random-string-1 and nodejs-random-string-2. So user won't accidentally push/modify something for one component from the directory for other component. This is not related to this discussion so I can open a new issue if there's not one already.)

What odo push would then do is, just call the same code that odo create calls if it detects that .odo/env/env.yaml is not present in the pwd.

The following behavior seems more natural to me:

odo project create myproject
odo component create java mycomponent
odo push

# now I want to push this component to different project
odo project create myproject2
odo push
# OK: pushed to myproject2


# Now I have decided that I want to always use project1
odo config set project myproject1
odo push
# now push will always push to myproject1

TBH, this sounds quite confusing to me. Whatever we decide to go with, we must make sure to explicitly mention this in the documentation along with a scenario. :wink:

Can we make odo push smart enough to check if .odo/env/env.yaml

One aspect about env.yaml is that, it’s a file used for cluster specific information. My first question would be, that would this file be a mandate for each user?
Now that might be the case but as there are things in the env.yaml that would later End up in devfile. When we reach that state, we cannot rely on env.yaml for smart push.

One aspect about env.yaml is that, it’s a file used for cluster specific information. My first question would be, that would this file be a mandate for each user?

It won't be required. But if you run odo push and there is no env.yaml it will get automatically created.

Now that might be the case but as there are things in the env.yaml that would later End up in devfile. When we reach that state, we cannot rely on env.yaml for smart push.

I don't follow

So the final approach I would like to propose here would be -

  • odo create in a directory with or without a devfile.yaml (with experimental mode= on) will always populates .odo/env/env.yaml with current namespace and other values. if there is no namespace that can be detected then

    • either fail or use default

  • odo push will use env.yaml file if its available else it will use defaults . assuming if the env.yaml is not present the user didn't go through the standard odo create process and actually cloned someone's odo component and due to that the component would be freshly created which means its ok to have a fresh component name and project name.
  • odo push in case if it doesn't find the env.yaml, should create the env.yaml before it starts doing any cluster operations.
  • odo config set project, odo config set name will set a namespace and component name in env.yaml even in a directory without .odo but with already existing devfile.yaml. This will essentially bootstrap the full odo component allowing anyone to start with existing devfile.yaml and add some odo specific configurations.
  • odo project create <project> can create a project and set it in KUBECONFIG as well as env.yaml only if there is no project present because that's the most conventional this command could become without being unpredictable i.e.

    • odo project create <project-name> sets env.yaml when there is not project/default project present in env.yaml

    • odo project create <project-name> will not set env.yaml if the project is already set.

if there is no namespace that can be detected then

  • either fail or use default

default namespace is not accessible to normal users, AFAIK. Unless you're saying we use sane defaults, as discussed earlier.

odo push will use env.yaml file if its available else it will use defaults . assuming if the env.yaml is not present the user didn't go through the standard odo create process and actually cloned someone's odo component and due to that the component would be freshly created which means its ok to have a fresh component name and project name.
odo push in case if it doesn't find the env.yaml, should create the env.yaml before it starts doing any cluster operations.

This is same as the smart push thing we discussed above, right? Or is there some disparity?

  • odo config set project, odo config set name will set a namespace and component name in env.yaml even in a directory without .odo but with already existing devfile.yaml. This will essentially bootstrap the full odo component allowing anyone to start with existing devfile.yaml and add some odo specific configurations.

Which means that like odo push, you propose to make odo config smart as well but only for set project and set name sub commands, right? Correct me if I'm wrong.

  • odo project create <project> can create a project and set it in KUBECONFIG as well as env.yaml only if there is no project present because that's the most conventional this command could become without being unpredictable i.e.

    • odo project create <project-name> sets env.yaml when there is not project/default project present in env.yaml
    • odo project create <project-name> will not set env.yaml if the project is already set.

This sounds like the right thing to do.

But overall, I think we're going to add a lot of ambiguity to a few important commands that form the base of the users' workflow when they're using odo. Besides this, we also have struggled with this conversation in #2285.

IMO, striving for a binary behaviour might be a good thing to end up with less ambiguous behaviours. With so many different possibilities that we're discussing here, odo consumers (CLI users and plugin devs alike) would have a tough time to grok the behaviour and would have to keep coming back to documentation to make sure they're not missing something. It would be a developer and test mayhem as well. I'd request we rethink because it sounds like a UX mess to me.

IMO, striving for a binary behaviour might be a good thing to end up with less ambiguous behaviours. With so many different possibilities that we're discussing here, odo consumers (CLI users and plugin devs alike) would have a tough time to grok the behaviour and would have to keep coming back to documentation to make sure they're not missing something. It would be a developer and test mayhem as well. I'd request we rethink because it sounds like a UX mess to me.

@dharmit do you have other solution in mind?

  • odo push in case if it doesn't find the env.yaml, should create the env.yaml before it starts doing any cluster operations.

+1 with one additional point. The fact that the project and the component name is saved and persistent needs to be communicated to the user.

Something like this:

$ odo push

Pushing component "my-component" to a project "my-project"

This is the first time you are pushing this component.
The component name and project are going to be persistent in the odo configuration.
You can use `odo config` command to change it later.

@dharmit do you have other solution in mind?

I'd suggest we go ahead with what we're discussing about odo push creating an env.yaml if it doesn't find one. But adding similar capabilities to odo config set project and odo config set name can be kept for later time if we receive request from users. I'm saying this because it's about adding functionality to sub commands unlike odo push. Also, someone using odo config commands first thing after cloning a repo containing devfile.yaml doesn't sound like a frequent scenario to me.

Don't get me wrong, I understand the intention. It's just that I don't think it's required right now.

As for the below approach,

  • odo project create <project> can create a project and set it in KUBECONFIG as well as env.yaml only if there is no project present because that's the most conventional this command could become without being unpredictable i.e.

    • odo project create <project-name> sets env.yaml when there is not project/default project present in env.yaml

    • odo project create <project-name> will not set env.yaml if the project is already set.

I agree it makes sense. But it must be clearly laid out in docs so that there's no room for confusion among users and/or developers.

/remove-triage needs-information
/triage ready

Created the first user story to address changes required in odo push command https://github.com/openshift/odo/issues/3144

this is fixed
/close

@kadel: Closing this issue.

In response to this:

this is fixed
/close

Instructions for interacting with me using PR comments are available here. If you have questions or suggestions related to my behavior, please file an issue against the kubernetes/test-infra repository.

Was this page helpful?
0 / 5 - 0 ratings

Related issues

kadel picture kadel  Â·  8Comments

cmoulliard picture cmoulliard  Â·  8Comments

anandrkskd picture anandrkskd  Â·  5Comments

maysunfaisal picture maysunfaisal  Â·  8Comments

prietyc123 picture prietyc123  Â·  3Comments