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

odo add binding drops all YAML comments from the Devfile #5789

Open
rm3l opened this issue Jun 3, 2022 · 4 comments
Open

odo add binding drops all YAML comments from the Devfile #5789

rm3l opened this issue Jun 3, 2022 · 4 comments
Labels
kind/bug Categorizes issue or PR as related to a bug. lifecycle/frozen Indicates that an issue or PR should not be auto-closed due to staleness. priority/Medium Nice to have issue. Getting it done before priority changes would be great. status/blocked Denotes an issue or PR that is blocked on something (e.g., issue/PR in different repo)

Comments

@rm3l
Copy link
Member

rm3l commented Jun 3, 2022

/kind bug

What versions of software are you using?

Operating System:
Fedora release 36 (Thirty Six)

Output of odo version:
odo v3.0.0-alpha2 (ba7f1a1)

How did you run odo exactly?

❯ odo init --name my-sample-go --devfile go --starter go-starter

❯ git init && git add -A . && git commit -m "initial commit"

Now add a few comments in the devfile.yaml file.
This is just an example, but we can imagine users having more-complex Devfiles with many comments/documentation in them.

diff --git a/devfile.yaml b/devfile.yaml
index d39ff93..af9a6cd 100644
--- a/devfile.yaml
+++ b/devfile.yaml
@@ -1,5 +1,7 @@
+# User comments in the Devfile will get removed by running 'odo add binding'
 commands:
 - exec:
+    # Description of the build command
     commandLine: GOCACHE=${PROJECT_SOURCE}/.cache go build main.go
     component: runtime
     group:
@@ -8,6 +10,7 @@ commands:
     workingDir: ${PROJECT_SOURCE}
   id: build
 - exec:
+    # Description of the run command
     commandLine: ./main
     component: runtime
     group:
❯ git commit -am "Add comments to the Devfile"
[main 0718673] Add comments to the Devfile
 1 file changed, 3 insertions(+)

Now run odo add binding (either interactively or not), e.g.:

❯ odo add binding --service redis-standalone.Redis.redis.redis.opstreelabs.in --name my-sample-go-redis-standalone
 ✓  Successfully added the binding to the devfile.
Run `odo dev` to create it on the cluster.

Actual behavior

The Devfile has been updated, as expected, to include the ServiceBinding Kubernetes Component. But all YAML comments in it have been surprisingly removed at the same time:

diff --git a/devfile.yaml b/devfile.yaml
index af9a6cd..3112651 100644
--- a/devfile.yaml
+++ b/devfile.yaml
@@ -1,32 +1,58 @@
-# User comments in the Devfile will get removed by running 'odo add binding'
 commands:
 - exec:
-    # Description of the build command
     commandLine: GOCACHE=${PROJECT_SOURCE}/.cache go build main.go
     component: runtime
     group:
       isDefault: true
       kind: build
+    hotReloadCapable: false
     workingDir: ${PROJECT_SOURCE}
   id: build
 - exec:
-    # Description of the run command
     commandLine: ./main
     component: runtime
     group:
       isDefault: true
       kind: run
+    hotReloadCapable: false
     workingDir: ${PROJECT_SOURCE}
   id: run
 components:
 - container:
+    dedicatedPod: false
     endpoints:
     - name: http
+      secure: false
       targetPort: 8080
     image: golang:latest
     memoryLimit: 1024Mi
     mountSources: true
   name: runtime
+- kubernetes:
+    inlined: |
+      apiVersion: binding.operators.coreos.com/v1alpha1
+      kind: ServiceBinding
+      metadata:
+        creationTimestamp: null
+        name: my-sample-go-redis-standalone
+      spec:
+        application:
+          group: apps
+          name: my-sample-go-app
+          resource: deployments
+          version: v1
+        bindAsFiles: true
+        detectBindingResources: true
+        services:
+        - group: redis.redis.opstreelabs.in
+          id: my-sample-go-redis-standalone
+          kind: Redis
+          name: redis-standalone
+          resource: redis
+          version: v1beta1
+      status:
+        secret: ""
+  name: my-sample-go-redis-standalone
 metadata:
   description: Stack with the latest Go version
   displayName: Go Runtime

Expected behavior

Users might have spent some time adding comments and documentation to their Devfiles, which might be quite complex. So existing comments should not be removed, especially since we want the Devfile to be the main source of truth.

I guess we will have the same issue with any other commands that edit the Devfile.

@openshift-ci openshift-ci bot added the kind/bug Categorizes issue or PR as related to a bug. label Jun 3, 2022
@kadel kadel added the priority/Medium Nice to have issue. Getting it done before priority changes would be great. label Jul 18, 2022
@rm3l
Copy link
Member Author

rm3l commented Aug 3, 2022

TL;DR
This might need to remain as a known issue for now 😕

Summary of my quick investigations
Devfile marshaling and unmarshaling are currently not handled directly by odo, but done via the Devfile library, which uses sigs.k8s.io/yaml, which in turn relies on JSON to convert YAML to/from Go structs (like in parse.go).
The rationale behind this is explained in detail in this blog post.
In a nutshell, this allows to reuse JSON tags and any custom MarshalJSON and UnmarshalJSON methods, thus allowing consistent handling of both YAML and JSON (YAML being a superset of JSON).
Since JSON is data-only and does not have any such notion of comments, all comments in a YAML document are lost when converting it into JSON (via yaml.YAMLToJSON).

sigs.k8s.io/yaml is a fork of ghodss/yaml, which is a wrapper around go-yaml (v2). go-yaml v3 brings in comment handling, via a new Node representation that allows preserving comments near the data they describe.
So the recommended way to have comments preserved is via this Node representation, but I guess this will not allow consistent handling of both YAML and JSON.

Found the following open issues and discussions related to these:

While it certainly makes sense for the Devfile library to use sigs.k8s.io/yaml (to effectively reuse the JSON tags defined in the Devfile API objects or {Un,}MarshalJSON methods, like DevWorkspaceTemplateSpecContent and Attributes structs), if we want to preserve comments on the odo side, we might not need JSON as an intermediate pivot format, but maybe we could leverage gopkg.in/yaml.v3 directly. This would require more effort on our side.
But I am not sure it actually makes sense to handle this on our side. This should certainly be an issue on the Devfile library side.

@rm3l
Copy link
Member Author

rm3l commented Aug 8, 2022

Added this to the Devfile community call (just to open the discussion), but we didn't have enough time to start discussing it. We will discuss it at a later time.

@rm3l rm3l added the status/blocked Denotes an issue or PR that is blocked on something (e.g., issue/PR in different repo) label Aug 8, 2022
@rm3l
Copy link
Member Author

rm3l commented Aug 30, 2022

/status blocked

Issue created on the Devfile library side: devfile/api#919

@github-actions
Copy link
Contributor

A friendly reminder that this issue had no activity for 90 days. Stale issues will be closed after an additional 30 days of inactivity.

@github-actions github-actions bot added the lifecycle/stale Denotes an issue or PR has remained open with no activity and has become stale. label Oct 30, 2023
@rm3l rm3l added lifecycle/frozen Indicates that an issue or PR should not be auto-closed due to staleness. and removed lifecycle/stale Denotes an issue or PR has remained open with no activity and has become stale. labels Oct 31, 2023
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
kind/bug Categorizes issue or PR as related to a bug. lifecycle/frozen Indicates that an issue or PR should not be auto-closed due to staleness. priority/Medium Nice to have issue. Getting it done before priority changes would be great. status/blocked Denotes an issue or PR that is blocked on something (e.g., issue/PR in different repo)
Projects
Status: No status
Development

No branches or pull requests

2 participants