-
Notifications
You must be signed in to change notification settings - Fork 63
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
Parent Devfiles #25
Comments
@l0rd Could the project devfile also include additional components not referenced in the stack devfile (e.g. new containers, plugins, etc)? |
That's a good question. I think that we need to discuss that. There are 2 possible behaviors. Eventual components or commands in the project devfile:
The replace behavior is consistent with what we are doing with the project. But "augmenting" a stack with extra components looks like an interesting use case. |
The goal is to allow user to refer to an existing devfile to reuse and modify/customerize it. Therefore, ideally, we should have a way to cover both adding definition and modifying existing one. |
Makes sense @elsony. We need to decide how we specify if a component/command is supposed to replace or extend a stack components/commands. Using IDs/aliases is an option. |
I implemented the related changes, API-wise and spec-wise, in the proposal-25-variant-1-define-stacks. I also added related examples of both:
|
How do I try out the PoC ? :) |
The only thing to try out on the Che side for now is playing with the syntax / API by running Openshift.io on this branch: As soon as the workspace is opened, you should be able to:
I'm still working on the implementation side of this POC to include this parent mechanism into the existing Workspace CRD controller POC. |
Here is a link to the demo of the POC implementation of this proposal on the Che side: |
The new details provided in the issue description have been reviewed and approved today |
@davidfestal @l0rd @elsony If a devfile has a container defined with some env vars
and the parent has a container defination with some extra env vars
should these env vars be appended? e.g
or should the parent's env vars be replaced? |
There was a discussion about that on gitter. Basically in this case we should use the Strategic Merge Patch and append the env variables. |
If we are using Strategic Merge Path why we need the This syntax is way too confusing. And it is not how Strategic Merge Path works in Kubernetes. schemaVersion: 2.0.0
metadata:
name: nodejs-app
parent:
uri: https://(...)/nodejs/devfile.yaml # <--- Parent referenced by `uri`, registry `id`
# or `kubernetes` devworkspace
components: # <--- Parent configuration can be customized
- container:
name: vsx-installer
env:
- name: VSX_LIST
value: java-dbg.vsix,java.vsix
components: # <--- components are added to parent's components
- container:
name: tooling # <--- should not match the name of a parent component
image: busybox
commands: # <--- commands are added to parent's commands
(...) Something like the following example can do the same with a much clearer syntax. schemaVersion: 2.0.0
metadata:
name: nodejs-app
parent:
uri: https://(...)/nodejs/devfile.yaml # <--- Parent referenced by `uri`, registry `id`
components:
- container:
name: tooling
image: busybox
- container:
name: vsx-installer
env:
- name: VSX_LIST
value: java-dbg.vsix,java.vsix
commands:
(...) if we want to provide more control over overriding or merging we can implement |
@kadel There's still a difference, schema-wise, between the The ones inside It seems to me that mixing complete definition of devfile elements (root elements), with devfile partial fragments (overrides) is just mixing to things that are different in nature. In consequence it would force us to recursively remove any mandatory field from the Devfile schema. If you take the By the way, the current definition was designed to be consistent between Of course, in the current design, when you have root devfile elements, the root devfile elements should not exist (with the same name or id) in the parent or in any of the plugins. This is an error.
Sure, but isn't it another part of the subject, that would be implemented later on ? |
To be honest, this is really confusing for users. If the only reason to do this is to make validation of required fields easier than it is not a good tradeoff. |
We have to take in account how plugins are overriden as well. |
Also documentation is different in overrides than in root-level elements, for example:
|
Maybe it could make sense to only allow overriding existing elements in both parent and plugin scopes. Would it make it :
|
We discussed this during devfile 2.0 meeting, and agreed that the proposal in previous comment seems the way to go, and a good tradeof between consistency, schema-aware validation and clarity for the users. It clearly defines the place where an element (component, command or project) can be added. Either:
The following example summarizes it: schemaVersion: 2.0.0
metadata:
name: parent-and-plugin-overriding
type: workspace
# First inherit from a Java technical stack as a parent
parent:
id: redhat/java-stack/latest
# Here we override *EXISTING* elements from the parent.
# That's why it is *INSIDE* the `parent` element scope
# If a new command / project / component element is added here that doesn't exist
# in the parent, this will trigger an error
commands:
# We're just overriding the `workingDir` field and MAVEN_OPTS env variable of the existing build command.
- exec:
id: build
workingDir: '${PROJECTS_ROOT}/spring-boot-http-booster'
env:
- name: MAVEN_OPTS
value: "-Xmx400m"
components:
# We're just changing the memory limit and the volume size of the java plugin that exists in the parent.
- plugin:
id: redhat/java8/latest
components:
- container:
name: vscode-java
memoryLimit: 2Gi
- volume:
name: m2
size: 2G
# Now, in the main Devfile body, we add *NEW ELEMENTS*.
# If a command / project / component element with the same key (name or id) exists in the parent or in any plugin,
# then this will trigger an error
projects:
- name: spring-boot-http-booster
git:
location: https://github.com/snowdrop/spring-boot-http-booster
branch: master
components:
# New plugin that is not present in the parent stack
# We can override an existing command of this plugin to change the working directory
- plugin:
id: redhat/dependency-analytics/latest
commands:
- exec:
id: analyze
workingDir: '${PROJECTS_ROOT}/spring-boot-http-booster'
# New container that is not present in the parent stack
# and contains the developer personal tooling
- container:
name: my-personnal-tooling
image: myrepo/mytooling:latest
mountSources: true
commands:
# New command that is not present in the parent stack
# and refers to the new personnal tooling container
- exec:
id:my-own-command
component: my-personnal-tooling
workingDir: '${PROJECTS_ROOT}/spring-boot-http-booster'
commandLine: ... We didn't discuss the case of |
The strategic merge patch overriding mechanism has been implemented in PR #98 according to the agreement described in comment #25 (comment) |
* Prepare GO model for overriding * Keyed interface and union normalizing implementation * Gather all union definitions in a single file. In the future these definitions could be generated automatically from the api source code. * Basic union normalizing tests * Implement overriding logic * Add overriding tests. The test yaml files provide useful hints about how the overriding works according to strategic merge patch rules * Add a schema for overrides and enhance markdown support to support code blocks. * Add missing required fields: `targetPort` in `Kubernetes`-like components * Generate files (crds,go and schemas) * Add schemas for yaml files of overriding tests * Add directives * Add additional vendors * Add a command to run tests * Support the case when no `.theia` folder exists * Only override in parent or plugin scope and add new elements only in the main devfile body. * Add the merge of events. * Remove the Events from the Overrides struct * Generate CRDs and schemas * Accommodate repo renaming Signed-off-by: David Festal <dfestal@redhat.com> * Run go fmt on changes * Run go mod tidy * Minor code cleanups and formatting * Regenerate schemas after rebasing to fix PR check Signed-off-by: Angel Misevski <amisevsk@redhat.com> Co-authored-by: David Festal <dfestal@dfestal.remote.csb> Co-authored-by: Angel Misevski <amisevsk@redhat.com>
@davidfestal @kadel It looks like the parent and plugin overriding and strategic merge patch have been implemented. Can this issue be closed off or is there anything still outstanding for this item? |
@elsony Yes, it has been impmemented. So I assume we can close this issue. However, if possible, I'd like to update the description first, according to the last agreement described in comment #25 (comment). Also, do you think it would be necessary to agree on where is the reference implementation of this specified logic, before closing the issue ? |
Done |
Confirmed the existing odo code is already using the strategic merge patch code as the api repo. Closing this issue. |
We want to experiment how the
Devfile
format could be used to define a stack.Requirements
1. Parent devfile
A parent devfile is a devfile published somewhere where
odo
or Che can readit. Like a gist, a registry or a kubernetes resource (see
referencing parents
below).A parent devfile is a regular devfile and includes components (for build and runtime), one or more code sample projects, events and commands to build and run the sample applications.
Any devfile that references a parent devfile will inherit its components, events and commands but won't inherit the code sample.
2. Referencing parents: uri, id or kubernetes
A parent devfile can be referenced in 3 different ways. Using its
id
if it has been published in a registry:Using the URI if it has been published on a static http server (like gist or pastebin):
Using a Kubernetes resource name, namespace if it has been deployed on a Kubernete cluster as a
DevWorkspaceTemplate
:3. Customizing parent configuration
When referencing a parent, a devfile should be able to customize its configuration. The syntax to customize a parent configuration is similar to kustomize:
The place where an customizable element (component, command or project) should be defined is clearly driven by the following rule. It is either:
parent
element itself if it is an override of an existing parent element,As a consequence;
As for the
events
element it is not really customizable: Due to the structure of theEvents
object, we can only add command bindings to some event. Overriding an existing command binding doesn't really makes sense. That's why we only allow events in the main devfile body, and not in the overrides. And the resulting events are the merge of the event objects coming from the parent, the plugins, and the main devfile body.An Example
The parent devfile is published on github repo: https://raw.githubusercontent.com/eclipse/che-devfile-registry/master/devfiles/nodejs/devfile.yaml
The following devfile references it:
The text was updated successfully, but these errors were encountered: