Skip to content

Update Devfile Import to use Kubernetes YAML definitions#12000

Merged
openshift-merge-robot merged 9 commits intoopenshift:masterfrom
maysunfaisal:devfile-outerloop-update-1
Oct 21, 2022
Merged

Update Devfile Import to use Kubernetes YAML definitions#12000
openshift-merge-robot merged 9 commits intoopenshift:masterfrom
maysunfaisal:devfile-outerloop-update-1

Conversation

@maysunfaisal
Copy link
Member

@maysunfaisal maysunfaisal commented Aug 29, 2022

Description

This PR updates the Devfile handler backend code to consume the Kubernetes YAML file definitions. For now, the devfile samples only have the Deployment definition in the YAML file but the next course of action would be to update the Service, Route definitions in the devfile sample

Fixes devfile/api#924

This PR just added the ability to read from Kubernetes YAML if the Devfile Kubernetes Component has inlined definition. If inlined is not present, it resorts to the previous way of generating Kubernetes resources. This should be compatible with previous OpenShift versions and the master branch

This PR also refactored some of the devfile backend code to keep it more clean and organized. Added tests to the devfile pkg since ODC didnt have go tests. Coverage %:

Screen Shot 2022-09-22 at 1 33 59 PM

How to test

(Check history for prev edit)

  • Devfile Import should work fine from the UI
  • If you are interested in testing the new approach, go to devfile-handler.go and update the following lines. Build and test it out by only importing a python devfile sample
         // Get devfile content and parse it using a library call in the future
	// devfileContentBytes := []byte(data.Devfile.DevfileContent)
	convert := true
	devfileObj, _, err = devfile.ParseDevfileAndValidate(parser.ParserArgs{
		// Data: devfileContentBytes,
		URL: "https://raw.githubusercontent.com/devfile-samples/devfile-sample-python-basic/87e269d5e018c904ba0a72b53292b3a9ed0b8b37/devfile.yaml",
		ConvertKubernetesContentInUri: &convert,
	})

@openshift-ci openshift-ci bot added the do-not-merge/work-in-progress Indicates that a PR should not merge because it is a work in progress. label Aug 29, 2022
@openshift-ci openshift-ci bot requested review from jhadvig and rhamilto August 29, 2022 20:01
@openshift-ci openshift-ci bot added the component/backend Related to backend label Aug 29, 2022
@openshift-merge-robot openshift-merge-robot added the needs-rebase Indicates a PR cannot be merged because it has merge conflicts with HEAD. label Sep 3, 2022

Choose a reason for hiding this comment

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

testingutil sounds like a unit test utility, is this really how it should work?

Copy link
Member Author

Choose a reason for hiding this comment

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

updated

Choose a reason for hiding this comment

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

I understand that this is WIP, but as a reminder that we don't want merge this URL unexpectedly.

Copy link
Member Author

Choose a reason for hiding this comment

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

removed

@maysunfaisal maysunfaisal force-pushed the devfile-outerloop-update-1 branch from c07f5b2 to 2fcc67e Compare September 15, 2022 20:29
@openshift-merge-robot openshift-merge-robot removed the needs-rebase Indicates a PR cannot be merged because it has merge conflicts with HEAD. label Sep 15, 2022
@maysunfaisal maysunfaisal force-pushed the devfile-outerloop-update-1 branch from 2fcc67e to f1d0fd8 Compare September 22, 2022 17:24
@maysunfaisal
Copy link
Member Author

@yangcao77 could you PTAL from Devfile perspective?

@maysunfaisal maysunfaisal changed the title [WIP] Update Devfile Import to use Kubernetes YAML definitions Update Devfile Import to use Kubernetes YAML definitions Sep 22, 2022
@openshift-ci openshift-ci bot removed the do-not-merge/work-in-progress Indicates that a PR should not merge because it is a work in progress. label Sep 22, 2022
Copy link
Contributor

@yangcao77 yangcao77 left a comment

Choose a reason for hiding this comment

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

generally looks good from devfile perspective. a couple suggestions added

Copy link
Contributor

Choose a reason for hiding this comment

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

can simply check if the imageBuildComponent has been set. so you don't need to introduce a count. and it does not need to iterate through the entire imageComponent list if it found an additional imagecomponent. (can save a little space & time :-D)

Suggested change
imageDeployComponentCount++
if reflect.DeepEqual(imageBuildComponent, devfilev1.Component{}) {
imageBuildComponent = component
} else {
// return error
}

and in the end, if the imageBuildComponent is unset, error out as well.

Copy link
Contributor

Choose a reason for hiding this comment

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

wrong error message?

Copy link
Member Author

@maysunfaisal maysunfaisal Sep 23, 2022

Choose a reason for hiding this comment

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

it was already in master branch, I didnt introduce this; I just merely moved the code. But let me see what i can do
meant to post it in another comment

Copy link
Contributor

Choose a reason for hiding this comment

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

why we want to pass in the imageComponentFilter as an arg? can this be defined within GetService?

Copy link
Member Author

Choose a reason for hiding this comment

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

it was already in master branch, I didnt introduce this; I just merely moved the code. But let me see what i can do

Copy link
Contributor

Choose a reason for hiding this comment

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

instead of a if-else statement. can check if component.Kubernetes.Inlined == "", and do the dev preview way. since it's going to break out if falls in that if statement. the src definition can be defined with all the stuffs starting at line 186

Copy link
Contributor

Choose a reason for hiding this comment

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

should not use an internal endpoint to create route neither

Copy link
Contributor

Choose a reason for hiding this comment

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

Copy link
Member Author

@maysunfaisal maysunfaisal Sep 23, 2022

Choose a reason for hiding this comment

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

I would still need to check if its nil because I am accessing it like *endpoint.Secure; I didnt check initially and it panicked in one of my tests with an empty secure

Copy link
Contributor

@yangcao77 yangcao77 Sep 23, 2022

Choose a reason for hiding this comment

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

in unit test, yes, you can assign a nil to endpoint.Secure. but in actual case, all boolean values will be set before returning devfileObj

But if you think it's safer to check & assign in ODC code, I'm good with that.

Copy link
Contributor

Choose a reason for hiding this comment

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

instead of doing the concatenating. can use github.com/hashicorp/go-multierror?
and

errMsg = multierror.Append(errMsg, fmt.Errorf("no service definition was found in the devfile sample"))

Copy link
Member Author

Choose a reason for hiding this comment

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

oh should have used this

@maysunfaisal maysunfaisal force-pushed the devfile-outerloop-update-1 branch from f1d0fd8 to 486b096 Compare September 23, 2022 21:01
Copy link
Member

Choose a reason for hiding this comment

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

@jhadvig What's you opinion on this move? We have also helm, knative, terminal on this level, so it might be ok?

Alternatively, we could move all these packages into a devconsole package (another time)? Wdyt? 🤷‍♂️

Copy link
Member

@christoph-jerolimov christoph-jerolimov left a comment

Choose a reason for hiding this comment

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

Just found some nits, this should not block us from pushing this forward.

Copy link
Member

Choose a reason for hiding this comment

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

Suggested change
// devfileData is the devfile-related information
// DevfileData is the devfile-related information

Copy link
Member

Choose a reason for hiding this comment

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

Suggested change
// gitData is the git-related information
// GitData is the git-related information

Comment on lines 174 to 178
Copy link
Member

Choose a reason for hiding this comment

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

The console backend (this bridge code) doesn't clone the repo. So it might not be possible to access any resource from the FS.

I see that you checking the src.URL, src.Path or src.Data attributes in ReadKubernetesYaml [1], it might be good to have three more explicit API methods in the library. That would also remove the direct dependency to https://github.com/spf13/afero from our code.

[1] https://github.com/devfile/library/blob/4c7c5dc73eee13b3db599a7e5fd2b266420cd390/pkg/devfile/parser/reader.go#L53-L91

Until then I would suggest:

Suggested change
src := parser.YamlSrc{
Data: []byte(component.Kubernetes.Inlined),
}
fs := afero.Afero{Fs: afero.NewOsFs()}
values, err := parser.ReadKubernetesYaml(src, fs)
src := parser.YamlSrc{
Data: []byte(component.Kubernetes.Inlined),
}
fs := afero.Afero{Fs: afero.NewMemMapFs()}
values, err := parser.ReadKubernetesYaml(src, fs)

Or just using YAML.Unmarshal

Copy link
Member Author

Choose a reason for hiding this comment

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

Good suggestion; I will put in a update to the library api method params.

but for now, I might go with NewMemMapFs(), dont really want to do YAML.Unmarshal because that would be just duplicating the devfile/library code in here to read the contents.

Copy link
Member

@christoph-jerolimov christoph-jerolimov left a comment

Choose a reason for hiding this comment

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

Tested the following cases:

  1. Imported all devfile samples on 4.12 (Kubernetes resources are ignored)
  2. Imported all devfile samples with this PR
  3. Added the following code to packages/dev-console/src/components/import/devfile/devfileHooks.ts [1] to insert some inlined kubernetes resources from https://github.com/devfile-samples/devfile-sample-dotnet60-basic
    • The /api/devfile/ response contains an updated Deployment and Service and these look fine to me 👍
    • ⚠️ Unfortunately, the import doesn't work because the Route resource is broken. You can see the full JSON response below. [3] ⚠️

In the console the dry-run fail already:

image

The Deployment diff looks good to me:

image

The Service diff looks also fine:

image

Here you see the broken Route:

image

[1] code snippet for devfileHooks.ts to test inlined yaml

tsx
import { safeLoad, safeDump } from 'js-yaml';
    /* eslint-disable no-console */
    console.log('xxx oldDevfileContent', devfileContent);

    const parsedDevfileContent = safeLoad(devfileContent);
    console.log('xxx parsed devfileContent', devfileContent);

    if (
      parsedDevfileContent.metadata.name === 'dotnet60' &&
      Array.isArray(parsedDevfileContent.components)
    ) {
      console.log('xxx update devfile with metadata.name', parsedDevfileContent.metadata.name);
      parsedDevfileContent.components.forEach((component) => {
        if (component.kubernetes && component.kubernetes.uri === 'kubernetes/deployment.yaml') {
          component.kubernetes = {
            inlined: `kind: Deployment
apiVersion: apps/v1
metadata:
  name: devfile-dotnet-deploy
spec:
  replicas: 1
  selector:
    matchLabels:
      app: devfile-dotnet-deploy
  template:
    metadata:
      labels:
        app: devfile-dotnet-deploy
    spec:
      containers:
        - name: main
          image: "{{CONTAINER_IMAGE}}"
          imagePullPolicy: Always
          resources: {}
`,
          };
        }
        if (component.kubernetes && component.kubernetes.uri === 'kubernetes/service.yaml') {
          component.kubernetes = {
            inlined: `apiVersion: v1
kind: Service
metadata:
  labels:
    app: dotnet-deploy
  name: devfile-dotnet-deploy
spec:
  ports:
    - name: http-8081
      port: 8081
      protocol: TCP
      targetPort: 8081
  selector:
    app: devfile-dotnet-deploy
  type: LoadBalancer
`,
          };
        }
      });
    } else {
      console.log('xxx skip devfile with metadata.name', parsedDevfileContent.metadata.name);
    }

    const newDevfileContent = safeDump(parsedDevfileContent);
    console.log('xxx newDevfileContent', newDevfileContent);

    return {
      name,
      git: { URL: url, ref, dir: prefixDotSlash(dir) },
      devfile: { devfileContent: newDevfileContent, devfilePath: `${smartSlashDir}${devfilePath}` },
    };
  }, [name, url, devfileContent, ref, dir, smartSlashDir, devfilePath]);

[2] old and new json response from /api/devfile/ (when no inlined kubernetes resource is used)

{
  "imageStream": {
    "kind": "ImageStream",
    "apiVersion": "image.openshift.io/v1",
    "metadata": {
      "creationTimestamp": null
    },
    "spec": {
      "lookupPolicy": {
        "local": false
      }
    },
    "status": {
      "dockerImageRepository": ""
    }
  },
  "buildResource": {
    "kind": "BuildConfig",
    "apiVersion": "build.openshift.io/v1",
    "metadata": {
      "creationTimestamp": null
    },
    "spec": {
      "source": {
        "type": "Git",
        "git": {
          "uri": "https://github.com/devfile-samples/devfile-sample-dotnet60-basic.git"
        },
        "contextDir": "."
      },
      "strategy": {
        "type": "Docker",
        "dockerStrategy": {
          "dockerfilePath": "docker/Dockerfile"
        }
      },
      "output": {
        "to": {
          "kind": "ImageStreamTag",
          "name": "dotnet60-basic:latest:latest"
        }
      },
      "resources": {},
      "postCommit": {},
      "nodeSelector": null
    },
    "status": {
      "lastVersion": 0
    }
  },
  "deployResource": {
    "kind": "Deployment",
    "apiVersion": "apps/v1",
    "metadata": {
      "creationTimestamp": null
    },
    "spec": {
      "selector": {
        "matchLabels": {
          "app": "dotnet60-basic"
        }
      },
      "template": {
        "metadata": {
          "creationTimestamp": null
        },
        "spec": {
          "containers": [
            {
              "name": "dotnet",
              "image": "registry.access.redhat.com/ubi8/dotnet-60:6.0",
              "command": [
                "tail",
                "-f",
                "/dev/null"
              ],
              "ports": [
                {
                  "name": "http-8080",
                  "containerPort": 8080,
                  "protocol": "TCP"
                }
              ],
              "env": [
                {
                  "name": "CONFIGURATION",
                  "value": "Debug"
                },
                {
                  "name": "STARTUP_PROJECT",
                  "value": "app.csproj"
                },
                {
                  "name": "ASPNETCORE_ENVIRONMENT",
                  "value": "Development"
                },
                {
                  "name": "PROJECTS_ROOT",
                  "value": "/projects"
                },
                {
                  "name": "PROJECT_SOURCE",
                  "value": "/projects"
                }
              ],
              "resources": {},
              "imagePullPolicy": "Always"
            }
          ]
        }
      },
      "strategy": {
        "type": "Recreate"
      }
    },
    "status": {}
  },
  "service": {
    "kind": "Service",
    "apiVersion": "v1",
    "metadata": {
      "creationTimestamp": null
    },
    "spec": {
      "ports": [
        {
          "name": "http-8080",
          "port": 8080,
          "targetPort": 8080
        },
        {
          "name": "http-8081",
          "port": 8081,
          "targetPort": "8081"
        }
      ]
    },
    "status": {
      "loadBalancer": {}
    }
  },
  "route": {
    "kind": "Route",
    "apiVersion": "route.openshift.io/v1",
    "metadata": {
      "creationTimestamp": null
    },
    "spec": {
      "path": "/",
      "to": {
        "kind": "Service",
        "name": "dotnet60-basic",
        "weight": null
      },
      "port": {
        "targetPort": "8081"
      }
    },
    "status": {}
  }
}

[3] updated /api/devfile/ json response with inlined YAML

{
  "imageStream": {
    "kind": "ImageStream",
    "apiVersion": "image.openshift.io/v1",
    "metadata": {
      "creationTimestamp": null
    },
    "spec": {
      "lookupPolicy": {
        "local": false
      }
    },
    "status": {
      "dockerImageRepository": ""
    }
  },
  "buildResource": {
    "kind": "BuildConfig",
    "apiVersion": "build.openshift.io/v1",
    "metadata": {
      "creationTimestamp": null
    },
    "spec": {
      "source": {
        "type": "Git",
        "git": {
          "uri": "https://github.com/devfile-samples/devfile-sample-dotnet60-basic.git"
        },
        "contextDir": "."
      },
      "strategy": {
        "type": "Docker",
        "dockerStrategy": {
          "dockerfilePath": "docker/Dockerfile"
        }
      },
      "output": {
        "to": {
          "kind": "ImageStreamTag",
          "name": "dotnet60-basic:latest:latest"
        }
      },
      "resources": {},
      "postCommit": {},
      "nodeSelector": null
    },
    "status": {
      "lastVersion": 0
    }
  },
  "deployResource": {
    "kind": "Deployment",
    "apiVersion": "apps/v1",
    "metadata": {
      "name": "devfile-dotnet-deploy",
      "creationTimestamp": null
    },
    "spec": {
      "replicas": 1,
      "selector": {
        "matchLabels": {
          "app": "devfile-dotnet-deploy"
        }
      },
      "template": {
        "metadata": {
          "creationTimestamp": null,
          "labels": {
            "app": "devfile-dotnet-deploy"
          }
        },
        "spec": {
          "containers": [
            {
              "name": "main",
              "image": "{{CONTAINER_IMAGE}}",
              "resources": {},
              "imagePullPolicy": "Always"
            }
          ]
        }
      },
      "strategy": {}
    },
    "status": {}
  },
  "service": {
    "kind": "Service",
    "apiVersion": "v1",
    "metadata": {
      "name": "devfile-dotnet-deploy",
      "creationTimestamp": null,
      "labels": {
        "app": "dotnet-deploy"
      }
    },
    "spec": {
      "ports": [
        {
          "name": "http-8081",
          "protocol": "TCP",
          "port": 8081,
          "targetPort": 8081
        }
      ],
      "selector": {
        "app": "devfile-dotnet-deploy"
      },
      "type": "LoadBalancer"
    },
    "status": {
      "loadBalancer": {}
    }
  },
  "route": {
    "metadata": {
      "creationTimestamp": null
    },
    "spec": {
      "to": {
        "kind": "",
        "name": "",
        "weight": null
      }
    },
    "status": {}
  }
}

@maysunfaisal
Copy link
Member Author

@jerolimov Thanks for the detailed testing and reports. The routes need to be defined in the devfile this way https://github.com/devfile-samples/devfile-sample-code-with-quarkus/pull/7/files#diff-23d39e3ae288b080d8aa0995928cd3c432f887a75f0ab3bba675089f51a4af8eR36-R39

One could also define routes in the YAML files but our official devfile samples will have the route definition in the component[x].kubernetes.endpoints

@christoph-jerolimov
Copy link
Member

@jerolimov Thanks for the detailed testing and reports. The routes need to be defined in the devfile this way https://github.com/devfile-samples/devfile-sample-code-with-quarkus/pull/7/files#diff-23d39e3ae288b080d8aa0995928cd3c432f887a75f0ab3bba675089f51a4af8eR36-R39

One could also define routes in the YAML files but our official devfile samples will have the route definition in the component[x].kubernetes.endpoints

Hi @maysunfaisal, I understand that it should be defined somewhere. But when its not defined the backend should not create broken resource definitions. I suggest that the Route is not exported in this case. Can you convert it to a pointer so that the JSON doesn't contain it anymore in this case?

@openshift-merge-robot openshift-merge-robot added the needs-rebase Indicates a PR cannot be merged because it has merge conflicts with HEAD. label Oct 11, 2022
@divyanshiGupta
Copy link
Contributor

divyanshiGupta commented Oct 11, 2022

@jerolimov Thanks for the detailed testing and reports. The routes need to be defined in the devfile this way https://github.com/devfile-samples/devfile-sample-code-with-quarkus/pull/7/files#diff-23d39e3ae288b080d8aa0995928cd3c432f887a75f0ab3bba675089f51a4af8eR36-R39
One could also define routes in the YAML files but our official devfile samples will have the route definition in the component[x].kubernetes.endpoints

Hi @maysunfaisal, I understand that it should be defined somewhere. But when its not defined the backend should not create broken resource definitions. I suggest that the Route is not exported in this case. Can you convert it to a pointer so that the JSON doesn't contain it anymore in this case?

@maysunfaisal I agree with @jerolimov here that backend should not return a broken resource definition since the add flows will break. In case the route is not defined let's not return it. Please update the PR accordingly.

@divyanshiGupta
Copy link
Contributor

@maysunfaisal I tested the UI PR with the current backend PR and it seems to work fine expect for the issue mentioned above. Resource URI is getting replaced with inline resource yaml and the api call is also successful with the new payload. All the desired resources are also returned but the route resource is broken as mentioned above.

Screen.Recording.2022-10-17.at.4.41.20.PM.mov

cc: @jerolimov @invincibleJai

@maysunfaisal maysunfaisal force-pushed the devfile-outerloop-update-1 branch from 486b096 to 7952114 Compare October 18, 2022 18:01
@openshift-merge-robot openshift-merge-robot removed the needs-rebase Indicates a PR cannot be merged because it has merge conflicts with HEAD. label Oct 18, 2022
@maysunfaisal
Copy link
Member Author

@divyanshiGupta @jerolimov I have rebased and addressed the PR concerns as well as our internal Slack thread conversation. PTAL.

I have tested 3 cases:

  1. Importing devfile sample without inline, it falls back to the current master branch approach. Successful.
  2. Importing devfile sample with inline including deployment, service and endpoint. Successful.
  3. Importing devfile sample with inline with only deployment, where service and endpoint are missing. Errors Out:

Screen Shot 2022-10-18 at 2 02 04 PM

Comment on lines +30 to +31
Service *corev1.Service `json:"service"`
Route *routev1.Route `json:"route"`

Choose a reason for hiding this comment

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

This pointers return this json if the Service or route is not defined:

{
  /* ... */
  "service": null,
  "route": null
}

You can omit this null values, this would fix the crash you mentioned here #12000 (comment). But it still need some frontend changes of PR #12168. So its up to you if you want apply this small change or not:

Suggested change
Service *corev1.Service `json:"service"`
Route *routev1.Route `json:"route"`
Service *corev1.Service `json:"service,omitempty"`
Route *routev1.Route `json:"route,omitempty"`

Copy link
Member Author

Choose a reason for hiding this comment

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

@jerolimov oops, I have committed this. if you can, please lgtm it again, thanks!

Copy link
Member

@christoph-jerolimov christoph-jerolimov left a comment

Choose a reason for hiding this comment

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

Overall this change looks good to me. 👍

I have retested this PR alone and together with #12168:

  • Imported all devfile samples without inlined frontend change
    • 5/6 samples could be imported successfully:+1:
    • The Quarkus example doesn't work. ⚠️ It works with this PR, please take a look into this PR: devfile-samples/devfile-sample-code-with-quarkus#7
    • Compared the /api/devfile/ response and it is 100% identical to the old version 👍
  • With the code snippet from #12000 (review) and also together with the PR #12168:
    • tested with an inlined Service and Deployment: both are created, Route is null and isn't created 👍
    • tested with just a Deployment, Service and Route are null and not created 👍

I observed one thing we should check on Slack. The Deployment contains a "variable" "{{CONTAINER_IMAGE}}" as image container. The frontend automatically overrides this with the new (ImageStream) name plus :latest. I expect this is fine for phase one, but that we should improve this behaviour later.

createOrUpdateDeployment is called here

const deploymentResponse = await createOrUpdateDeployment(
formData,
devfileResourceObjects.imageStream,
dryRun,
devfileResourceObjects.deployResource,
verb,
);

and then overrides the image in line 368 here:

const newDeployment = {
apiVersion: 'apps/v1',
kind: 'Deployment',
metadata: {
name,
namespace,
labels: { ...defaultLabels, ...userLabels },
annotations: defaultAnnotations,
},
spec: {
selector: {
matchLabels: {
app: name,
},
},
replicas,
template: {
metadata: {
labels: { ...templateLabels, ...userLabels, ...podLabels },
},
spec: {
containers: [
{
name,
image: `${name}:latest`,
ports,
env,
resources: getResourceLimitsData({ cpu, memory }),
...getProbesData(healthChecks),
},
],
},
},
},
};
const deployment = mergeData(originalDeployment, newDeployment);


The Deployment JSON as reference:

  "deployResource": {
    "kind": "Deployment",
    "apiVersion": "apps/v1",
    "metadata": { "name": "devfile-dotnet-deploy", "creationTimestamp": null },
    "spec": {
      "replicas": 1,
      "selector": { "matchLabels": { "app": "devfile-dotnet-deploy" } },
      "template": {
        "metadata": {
          "creationTimestamp": null,
          "labels": { "app": "devfile-dotnet-deploy" }
        },
        "spec": {
          "containers": [
            {
              "name": "main",
              "image": "{{CONTAINER_IMAGE}}",
              "resources": {},
              "imagePullPolicy": "Always"
            }
          ]
        }
      },
      "strategy": {}
    },
    "status": {}
  },

/lgtm
/approve

@openshift-ci openshift-ci bot added lgtm Indicates that a PR is ready to be merged. approved Indicates a PR has been approved by an approver from all required OWNERS files. labels Oct 19, 2022
@divyanshiGupta
Copy link
Contributor

divyanshiGupta commented Oct 19, 2022

I observed one thing we should check on Slack. The Deployment contains a "variable" "{{CONTAINER_IMAGE}}" as image container.

@maysunfaisal It seems that this should be replaced with the image-name in the devfile. As @jerolimov mentioned its fine for phase 1 but lets improve it later and make sure all variables are replaced with their respective values.

@divyanshiGupta
Copy link
Contributor

/label docs-approved
/label px-approved

@openshift-ci openshift-ci bot added docs-approved Signifies that Docs has signed off on this PR px-approved Signifies that Product Support has signed off on this PR labels Oct 19, 2022
Co-authored-by: Christoph Jerolimov <[email protected]>
@openshift-ci openshift-ci bot removed the lgtm Indicates that a PR is ready to be merged. label Oct 19, 2022
@christoph-jerolimov
Copy link
Member

/lgtm

@openshift-ci openshift-ci bot added the lgtm Indicates that a PR is ready to be merged. label Oct 20, 2022
@openshift-ci
Copy link
Contributor

openshift-ci bot commented Oct 20, 2022

[APPROVALNOTIFIER] This PR is APPROVED

This pull-request has been approved by: jerolimov, maysunfaisal

The full list of commands accepted by this bot can be found here.

The pull request process is described here

Details Needs approval from an approver in each of these files:

Approvers can indicate their approval by writing /approve in a comment
Approvers can cancel approval by writing /approve cancel in a comment

@sanketpathak
Copy link
Contributor

Verified on cluster created on pr
Screenshot from 2022-10-20 03-37-42
Screenshot from 2022-10-20 03-37-06
/label qe-approved

@openshift-ci openshift-ci bot added the qe-approved Signifies that QE has signed off on this PR label Oct 20, 2022
@divyanshiGupta
Copy link
Contributor

/retest

@openshift-ci
Copy link
Contributor

openshift-ci bot commented Oct 20, 2022

@maysunfaisal: all tests passed!

Full PR test history. Your PR dashboard.

Details

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. I understand the commands that are listed here.

@openshift-merge-robot openshift-merge-robot merged commit d51f3bb into openshift:master Oct 21, 2022
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

approved Indicates a PR has been approved by an approver from all required OWNERS files. component/backend Related to backend docs-approved Signifies that Docs has signed off on this PR lgtm Indicates that a PR is ready to be merged. px-approved Signifies that Product Support has signed off on this PR qe-approved Signifies that QE has signed off on this PR

Projects

None yet

Development

Successfully merging this pull request may close these issues.

ODC Adoption of Devfile v2.2.0

6 participants