From 9d94c008015c8f76fd3991c30b1d48da00626955 Mon Sep 17 00:00:00 2001 From: Luke Weston Date: Tue, 23 Jun 2020 16:59:42 +0100 Subject: [PATCH 01/10] Initial proposal --- docs/proposals/lifecycle_events.md | 75 ++++++++++++++++++++++++++++++ 1 file changed, 75 insertions(+) create mode 100644 docs/proposals/lifecycle_events.md diff --git a/docs/proposals/lifecycle_events.md b/docs/proposals/lifecycle_events.md new file mode 100644 index 00000000000..fdeb4d49211 --- /dev/null +++ b/docs/proposals/lifecycle_events.md @@ -0,0 +1,75 @@ +# Support execution of the commands based on lifecycle events. + +## Abstract +Add support for the lifecycle events which can be defined in 2.0.0 devfiles. + +To be achieved by performing the PreStart and PostStart events as a part of **odo push**, and the PreStop and Poststop events as a part of **odo delete** + +## Motivation +Devfile support commands that can be triggered based on dev lifecycle events. Odo will need to support/execute these commands at appropriate times within the flow. + +With the implementation of livecycle events, stack creators will be able to leverage all the capabilities of devfiles when building the correct experience/features for their stacks. + +## User Stories +Container initiliazation support - https://github.com/openshift/odo/issues/2936 + +Lifecycle bindings for specific events - https://github.com/devfile/kubernetes-api/issues/32 + + +## Design overview + +The lifecycle events that have been implemented in Devfile 2.0.0 are generic. So their effect/meaning might be slightly different when applying them to a workspace (Che) or a single project (odo). + +Our proposal is that the PreStart and PostStart events are designed to run as a part of **odo push**, and that the PreStop and PostStop events run as a part of **odo delete**. + + + +### The flow for **odo push** including the *PreStart* and *PostStart* lifecycle events will be as follows: + - PreStart - Devfile command gets translated to entrypoint for specified init container - one time only + - Container initialisation (as done today) + - PostStart - Exec the specified command(s) in the container - one time only + - Rest of the command execution (as we do today - exec commands for build/run/test/debug) + +**PreStart**: + - The PreStart command(s) that are specified in the Devfile will be translated into entry points for their specified containers, and added to the pod spec as init containers. + - These will only run on the first odo push, or when doing a force push (odo push -f). + - These are commands that you’d want to run before the main containers are created. + + **Note: We need some good use cases to understand when the user would run commands as PreStart opposed to PostStart.** + +**Component Initialization** + - After the PreStart event has completed, the containers specified in the Devfile are initialised and created if the component doesn’t already exist. + +**PostStart** + - If the component is newly created, the PostStart events are executed sequentially within the containers given in the Devfile. + - These commands could all be in the same container, or all in different ones. + +**Command Execution** + - After PostStart, we’d run the usual build/run/test/debug commands (depending on what sort of odo push parameters the user has provided) as usual. + +The reason we have chosen to use init containers for PreStart rather than to be consistent, is because we don’t think there would be any difference in the PreStart and PostStart stages if they both ran in the same containers. If we were instead initialising the containers, running PreStart in those containers, and then PostStart in those containers, what would be different to running them all in PreStart, or all in PostStart? At least with init containers for PreStart, there is a definitive difference between the two, and therefore reason to include them both as separate events. + + + +### The flow for **odo delete** including the *PreStop* and *PostStop* lifecycle events will be as follows: +**PreStop** + - Exec the specified command(s) in their respective containers before deleting the deployment and any clean up begins. + +**Clean up resources** + - Clean up the pod and deployment etc. (as done today) + +**PostStop** + - Execute the command specified by postStop + - Would we be spinning up a new container exclusively for the PostStop commands? + - Would the command need to run on the host instead for local clean up? + + + +### Conclusions: + - We think that the most important event is the PostStart because it has a clear, reasonable use case within odo’s flow. + - PreStart and PreStop could potentially be useful, but in a much more niche range. It would be important to clearly document the execution order/process for these events, because it would likely cause confusion. + - We aren’t fully conclusive on the necessity of PostStop, and what it would be useful for. + + ## Future Evolution + + From 408cfce55c08d3ada45ca942b7ede3951a9b57f6 Mon Sep 17 00:00:00 2001 From: Luke Weston Date: Tue, 23 Jun 2020 17:05:30 +0100 Subject: [PATCH 02/10] Updated abstract --- docs/proposals/lifecycle_events.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/docs/proposals/lifecycle_events.md b/docs/proposals/lifecycle_events.md index fdeb4d49211..13084f4ae0e 100644 --- a/docs/proposals/lifecycle_events.md +++ b/docs/proposals/lifecycle_events.md @@ -3,7 +3,7 @@ ## Abstract Add support for the lifecycle events which can be defined in 2.0.0 devfiles. -To be achieved by performing the PreStart and PostStart events as a part of **odo push**, and the PreStop and Poststop events as a part of **odo delete** +Our proposed solution is to perform the PreStart and PostStart events as a part of the **odo push** command, and the PreStop and Poststop events as a part of the **odo delete** command. ## Motivation Devfile support commands that can be triggered based on dev lifecycle events. Odo will need to support/execute these commands at appropriate times within the flow. From 6337c2665a124ebabe30440aa3b4e161cd10e15b Mon Sep 17 00:00:00 2001 From: Luke Weston Date: Wed, 24 Jun 2020 11:45:20 +0100 Subject: [PATCH 03/10] Added Neeraj's suggestions --- docs/proposals/lifecycle_events.md | 50 ++++++++++++++++-------------- 1 file changed, 26 insertions(+), 24 deletions(-) diff --git a/docs/proposals/lifecycle_events.md b/docs/proposals/lifecycle_events.md index 13084f4ae0e..fcc18f94281 100644 --- a/docs/proposals/lifecycle_events.md +++ b/docs/proposals/lifecycle_events.md @@ -3,7 +3,10 @@ ## Abstract Add support for the lifecycle events which can be defined in 2.0.0 devfiles. -Our proposed solution is to perform the PreStart and PostStart events as a part of the **odo push** command, and the PreStop and Poststop events as a part of the **odo delete** command. +Our proposed solution is to perform the preStart and postStart events as a part of the **odo push** command, and the preStop and Poststop events as a part of the **odo delete** command. + +Lifecycle bindings for specific events - https://github.com/devfile/kubernetes-api/issues/32 + ## Motivation Devfile support commands that can be triggered based on dev lifecycle events. Odo will need to support/execute these commands at appropriate times within the flow. @@ -11,64 +14,63 @@ Devfile support commands that can be triggered based on dev lifecycle events. Od With the implementation of livecycle events, stack creators will be able to leverage all the capabilities of devfiles when building the correct experience/features for their stacks. ## User Stories -Container initiliazation support - https://github.com/openshift/odo/issues/2936 - -Lifecycle bindings for specific events - https://github.com/devfile/kubernetes-api/issues/32 +Each lifecycle event would be suited to individual user stories. We propose that at least one issue is made for each of them for tracking and implementation purposes. +An issue has already been created for postStart: [container initiliazation support](https://github.com/openshift/odo/issues/2936) ## Design overview -The lifecycle events that have been implemented in Devfile 2.0.0 are generic. So their effect/meaning might be slightly different when applying them to a workspace (Che) or a single project (odo). +The lifecycle events that have been implemented in Devfile 2.0.0 are generic. So their effect/meaning might be slightly different when applying them to a workspace (Che) or a single project (odo). However, this proposal will aim to provide a similar user experience within the scope of a single project. -Our proposal is that the PreStart and PostStart events are designed to run as a part of **odo push**, and that the PreStop and PostStop events run as a part of **odo delete**. +Our proposal is that the preStart and postStart events are designed to run as a part of **odo push**, and that the preStop and postStop events run as a part of **odo delete**. -### The flow for **odo push** including the *PreStart* and *PostStart* lifecycle events will be as follows: - - PreStart - Devfile command gets translated to entrypoint for specified init container - one time only +### The flow for **odo push** including the *preStart* and *postStart* lifecycle events will be as follows: + - preStart - Devfile command gets translated to entrypoint for specified init container - one time only - Container initialisation (as done today) - - PostStart - Exec the specified command(s) in the container - one time only + - postStart - Exec the specified command(s) in the container - one time only - Rest of the command execution (as we do today - exec commands for build/run/test/debug) -**PreStart**: - - The PreStart command(s) that are specified in the Devfile will be translated into entry points for their specified containers, and added to the pod spec as init containers. +**preStart**: + - The preStart command(s) that are specified in the Devfile will be translated into entry points for their specified containers, and added to the pod spec as init containers. - These will only run on the first odo push, or when doing a force push (odo push -f). - These are commands that you’d want to run before the main containers are created. - **Note: We need some good use cases to understand when the user would run commands as PreStart opposed to PostStart.** + **Note: We need some good use cases to understand when the user would run commands as preStart opposed to postStart.** **Component Initialization** - - After the PreStart event has completed, the containers specified in the Devfile are initialised and created if the component doesn’t already exist. + - After the preStart event has completed, the containers specified in the Devfile are initialised and created if the component doesn’t already exist. -**PostStart** - - If the component is newly created, the PostStart events are executed sequentially within the containers given in the Devfile. +**postStart** + - If the component is newly created, the postStart events are executed sequentially within the containers given in the Devfile. - These commands could all be in the same container, or all in different ones. **Command Execution** - - After PostStart, we’d run the usual build/run/test/debug commands (depending on what sort of odo push parameters the user has provided) as usual. + - After postStart, we’d run the usual build/run/test/debug commands (depending on what sort of odo push parameters the user has provided) as usual. -The reason we have chosen to use init containers for PreStart rather than to be consistent, is because we don’t think there would be any difference in the PreStart and PostStart stages if they both ran in the same containers. If we were instead initialising the containers, running PreStart in those containers, and then PostStart in those containers, what would be different to running them all in PreStart, or all in PostStart? At least with init containers for PreStart, there is a definitive difference between the two, and therefore reason to include them both as separate events. +The reason we have chosen to use init containers for preStart rather than to be consistent, is because we don’t think there would be any difference in the preStart and postStart stages if they both ran in the same containers. If we were instead initialising the containers, running preStart in those containers, and then postStart in those containers, what would be different to running them all in preStart, or all in postStart? At least with init containers for preStart, there is a definitive difference between the two, and therefore reason to include them both as separate events. -### The flow for **odo delete** including the *PreStop* and *PostStop* lifecycle events will be as follows: -**PreStop** +### The flow for **odo delete** including the *preStop* and *postStop* lifecycle events will be as follows: +**preStop** - Exec the specified command(s) in their respective containers before deleting the deployment and any clean up begins. **Clean up resources** - Clean up the pod and deployment etc. (as done today) -**PostStop** +**postStop** - Execute the command specified by postStop - - Would we be spinning up a new container exclusively for the PostStop commands? + - Would we be spinning up a new container exclusively for the postStop commands? - Would the command need to run on the host instead for local clean up? ### Conclusions: - - We think that the most important event is the PostStart because it has a clear, reasonable use case within odo’s flow. - - PreStart and PreStop could potentially be useful, but in a much more niche range. It would be important to clearly document the execution order/process for these events, because it would likely cause confusion. - - We aren’t fully conclusive on the necessity of PostStop, and what it would be useful for. + - We think that the most important event is the postStart because it has a clear, reasonable use case within odo’s flow. + - preStart and preStop could potentially be useful, but in a much more niche range. It would be important to clearly document the execution order/process for these events, because it would likely cause confusion. + - We aren’t fully conclusive on the necessity of postStop, and what it would be useful for. ## Future Evolution From e34c98f08d36e32ddf46b4958fc52c20454cc5fc Mon Sep 17 00:00:00 2001 From: Luke Weston Date: Fri, 26 Jun 2020 15:32:33 +0100 Subject: [PATCH 04/10] Revisions from Elson and Aditi --- docs/proposals/lifecycle_events.md | 123 +++++++++++++++++++++-------- 1 file changed, 89 insertions(+), 34 deletions(-) diff --git a/docs/proposals/lifecycle_events.md b/docs/proposals/lifecycle_events.md index fcc18f94281..c3af3768428 100644 --- a/docs/proposals/lifecycle_events.md +++ b/docs/proposals/lifecycle_events.md @@ -1,17 +1,17 @@ # Support execution of the commands based on lifecycle events. ## Abstract -Add support for the lifecycle events which can be defined in 2.0.0 devfiles. +Add support for the lifecycle events which can be defined in 2.0 devfiles. -Our proposed solution is to perform the preStart and postStart events as a part of the **odo push** command, and the preStop and Poststop events as a part of the **odo delete** command. +Our proposed solution is to perform the postStart event as a part of the **odo push** command, and the preStop event as a part of the **odo delete** command. Lifecycle bindings for specific events - https://github.com/devfile/kubernetes-api/issues/32 ## Motivation -Devfile support commands that can be triggered based on dev lifecycle events. Odo will need to support/execute these commands at appropriate times within the flow. +Devfiles support commands that can be triggered based on dev lifecycle events. Odo will need to support/execute these commands at appropriate times within the flow. -With the implementation of livecycle events, stack creators will be able to leverage all the capabilities of devfiles when building the correct experience/features for their stacks. +With the implementation of lifecycle events, stack creators will be able to leverage all the capabilities of devfiles when building the correct experience/features for their stacks. ## User Stories Each lifecycle event would be suited to individual user stories. We propose that at least one issue is made for each of them for tracking and implementation purposes. @@ -20,58 +20,113 @@ An issue has already been created for postStart: [container initiliazation suppo ## Design overview -The lifecycle events that have been implemented in Devfile 2.0.0 are generic. So their effect/meaning might be slightly different when applying them to a workspace (Che) or a single project (odo). However, this proposal will aim to provide a similar user experience within the scope of a single project. +The lifecycle events that have been implemented in Devfile 2.0 are generic. So their effect/meaning might be slightly different when applying them to a workspace (Che) or a single project (odo). However, this proposal will aim to provide a similar user experience within the scope of a single project. -Our proposal is that the preStart and postStart events are designed to run as a part of **odo push**, and that the preStop and postStop events run as a part of **odo delete**. +Our proposal is that the postStart event will run as a part of **odo push**, and that the preStop event will run as a part of **odo delete**. - -### The flow for **odo push** including the *preStart* and *postStart* lifecycle events will be as follows: - - preStart - Devfile command gets translated to entrypoint for specified init container - one time only - - Container initialisation (as done today) +### The flow for **odo push** including the *postStart* lifecycle event will be as follows: + - Start the container(s) (as done today) - postStart - Exec the specified command(s) in the container - one time only - Rest of the command execution (as we do today - exec commands for build/run/test/debug) -**preStart**: - - The preStart command(s) that are specified in the Devfile will be translated into entry points for their specified containers, and added to the pod spec as init containers. - - These will only run on the first odo push, or when doing a force push (odo push -f). - - These are commands that you’d want to run before the main containers are created. - - **Note: We need some good use cases to understand when the user would run commands as preStart opposed to postStart.** -**Component Initialization** - - After the preStart event has completed, the containers specified in the Devfile are initialised and created if the component doesn’t already exist. +**Starting the container(s)** + - The containers specified in the Devfile are initialised and created if the component doesn’t already exist. **postStart** - If the component is newly created, the postStart events are executed sequentially within the containers given in the Devfile. - - These commands could all be in the same container, or all in different ones. + - If any of the *postStart* commands do fail, then we would exit the **odo push** and report the error that had occurred. If it had failed to execute one of the postStart commands, the **odo push** might behave differently to what the stack creator had intended, so we would bail out early. + - This functionality would also act as a replacement for `devInit` in devfile v1.0. **Command Execution** - After postStart, we’d run the usual build/run/test/debug commands (depending on what sort of odo push parameters the user has provided) as usual. -The reason we have chosen to use init containers for preStart rather than to be consistent, is because we don’t think there would be any difference in the preStart and postStart stages if they both ran in the same containers. If we were instead initialising the containers, running preStart in those containers, and then postStart in those containers, what would be different to running them all in preStart, or all in postStart? At least with init containers for preStart, there is a definitive difference between the two, and therefore reason to include them both as separate events. - +### The flow for **odo delete** including the *preStop* lifecycle event will be as follows: + - preStop - Exec the specified command(s) in the container + - Clean up the pod and deployment etc. (as done today) -### The flow for **odo delete** including the *preStop* and *postStop* lifecycle events will be as follows: **preStop** - Exec the specified command(s) in their respective containers before deleting the deployment and any clean up begins. - -**Clean up resources** - - Clean up the pod and deployment etc. (as done today) - -**postStop** - - Execute the command specified by postStop - - Would we be spinning up a new container exclusively for the postStop commands? - - Would the command need to run on the host instead for local clean up? - + - If any of the *preStop* commands do fail, then we would exit the **odo delete** and report the error that had occurred. If it had failed to execute one of the preStop commands, the **odo delete** might behave differently to what the stack creator had intended, so we would bail out early. + + +### Flow with example devfile: +``` +schemaVersion: "2.0.0" +metadata: + name: test-devfile +projects: + - name: nodejs-web-app + git: + location: "https://github.com/che-samples/web-nodejs-sample.git" +components: + - container: + id: tools + image: quay.io/eclipse/che-nodejs10-ubi:nightly + name: "tools" + - container: + id: runtime + image: quay.io/eclipse/che-nodejs10-ubi:nightly + name: "runtime" +commands: + - exec: + id: download dependencies + commandLine: "npm install" + component: tools + workingDir: ${CHE_PROJECTS_ROOT}/nodejs-web-app/app + group: + kind: build + - exec: + id: run the app + commandLine: "nodemon app.js" + component: runtime + workingDir: ${CHE_PROJECTS_ROOT}/nodejs-web-app/app + group: + kind: run + - exec: + id: firstPostStartCmd + commandLine: echo I am the first PostStart + component: tools + workingDir: ${CHE_PROJECTS_ROOT}/ + - exec: + id: secondPostStartCmd + commandLine: echo I am the second PostStart + component: tools + workingDir: ${CHE_PROJECTS_ROOT}/ + - exec: + id: disconnectDatabase + commandLine: echo disconnecting from the database + component: tools + workingDir: ${CHE_PROJECTS_ROOT}/ +events: + postStart: + - "firstPostStartCmd" + - "secondPostStartCmd" + preStop: + - "disconnectDatabase" + +``` + +The example flow for **odo push** in this case would be: + - create the containers + - execute firstPostStartCmd within the tools container + - execute secondPostStartCmd within the tools container + - execute build command + - execute run command + + The example flow for **odo delete** in this case would be: + - execute disconnectDatabase + - clean up the pod and deployment etc. (as done today) ### Conclusions: - - We think that the most important event is the postStart because it has a clear, reasonable use case within odo’s flow. - - preStart and preStop could potentially be useful, but in a much more niche range. It would be important to clearly document the execution order/process for these events, because it would likely cause confusion. - - We aren’t fully conclusive on the necessity of postStop, and what it would be useful for. + - We think that the most important events are the postStart, and the preStop because they have clear, reasonable use case within odo’s flow. + - We aren’t fully conclusive on the necessity of preStart and postStop. They do not currently have a useful case within odo. ## Future Evolution + + - *preStop* and *postStop* events are supported in Devfile 2.0, but aren't currently applicable to odo. In the future, a reason could arise where would benefit from these events. From cd1ac35186fa7512356a655a87ba293092608196 Mon Sep 17 00:00:00 2001 From: Luke Weston Date: Tue, 30 Jun 2020 16:56:10 +0100 Subject: [PATCH 05/10] Added further evolution with postStart implementation --- docs/proposals/lifecycle_events.md | 15 +++++++++++++-- 1 file changed, 13 insertions(+), 2 deletions(-) diff --git a/docs/proposals/lifecycle_events.md b/docs/proposals/lifecycle_events.md index c3af3768428..dbf45e87794 100644 --- a/docs/proposals/lifecycle_events.md +++ b/docs/proposals/lifecycle_events.md @@ -32,7 +32,7 @@ Our proposal is that the postStart event will run as a part of **odo push**, and **Starting the container(s)** - - The containers specified in the Devfile are initialised and created if the component doesn’t already exist. + - The containers specified in the Devfile are initialized and created if the component doesn’t already exist. **postStart** - If the component is newly created, the postStart events are executed sequentially within the containers given in the Devfile. @@ -42,6 +42,8 @@ Our proposal is that the postStart event will run as a part of **odo push**, and **Command Execution** - After postStart, we’d run the usual build/run/test/debug commands (depending on what sort of odo push parameters the user has provided) as usual. + This flow relies on the assumption that all of the postCommands will only be required to run on the first `odo push` of the given odo project. A more in-depth description of a potential further developed approach is documented in the Future Evolution section of the proposal. + ### The flow for **odo delete** including the *preStop* lifecycle event will be as follows: - preStop - Exec the specified command(s) in the container @@ -127,6 +129,15 @@ The example flow for **odo push** in this case would be: ## Future Evolution - - *preStop* and *postStop* events are supported in Devfile 2.0, but aren't currently applicable to odo. In the future, a reason could arise where would benefit from these events. +The above proposed implementation of postStart events could be further improved upon in future developments. There is potential to be more granular by identifying which specific container we are initializing, and whether or not there is a postStart command associated with it. With this, we could better utilize the postStart commands and use them in cases where only some of the containers are being initialized. + + +A potential flow could be to check for postStart commands associated with a specific container when inititializing it, storing those commands in an Object(?) and then executing only those postStart commands when the containers have all finished initializing (in the order that they have been defined within the devfile). This would benefit cases where an individual container has been re-initialized, but not the whole component. For example, if a build container has been restarted as a part of **odo push --force** and there is a postStart command associated with the build container in the devfile that is required to re-run, that single postStart command would be executed before continuing to the build/run phase of the push command. + + +There could be room for such a feature, and a case could be presented to argue the validity of changing the flow of **odo push** in order to accommodate such cases in a future implementation. + + +Additionally, *preStop* and *postStop* events are supported in Devfile 2.0, but aren't currently applicable to odo. In the future, a reason could arise where would benefit from these events. From 9e7e39454ccc0ff2f864c41adf7b8c2812d683cf Mon Sep 17 00:00:00 2001 From: Neeraj Laad Date: Wed, 8 Jul 2020 16:26:12 +0100 Subject: [PATCH 06/10] Updated design proposal Signed-off-by: Neeraj Laad --- docs/proposals/lifecycle_events.md | 188 +++++++++++++---------------- 1 file changed, 87 insertions(+), 101 deletions(-) diff --git a/docs/proposals/lifecycle_events.md b/docs/proposals/lifecycle_events.md index dbf45e87794..6ece1a5a62b 100644 --- a/docs/proposals/lifecycle_events.md +++ b/docs/proposals/lifecycle_events.md @@ -1,114 +1,112 @@ -# Support execution of the commands based on lifecycle events. +# Support execution of the commands based on lifecycle events ## Abstract -Add support for the lifecycle events which can be defined in 2.0 devfiles. - -Our proposed solution is to perform the postStart event as a part of the **odo push** command, and the preStop event as a part of the **odo delete** command. - -Lifecycle bindings for specific events - https://github.com/devfile/kubernetes-api/issues/32 +Devfile 2.0.0 allows binding of commands to specific lifecycle events: https://github.com/devfile/kubernetes-api/issues/32. These commands are meant to be executed when those specific lifecycle events are triggered. +The lifecycle events that have been implemented in Devfile 2.0.0 are generic. Their effect/meaning might be slightly different in the context a workspace (Che) or a single project (odo). However, odo should aim to provide a similar user experience within the scope of a single project. ## Motivation -Devfiles support commands that can be triggered based on dev lifecycle events. Odo will need to support/execute these commands at appropriate times within the flow. - -With the implementation of lifecycle events, stack creators will be able to leverage all the capabilities of devfiles when building the correct experience/features for their stacks. +Devfiles support commands that can be triggered based on development lifecycle events. With the implementation of lifecycle events, stack creators will be able to leverage all the capabilities of devfiles when building the correct experience/features for their stacks. `odo` should support/execute these commands at appropriate times within `odo` development flow. ## User Stories Each lifecycle event would be suited to individual user stories. We propose that at least one issue is made for each of them for tracking and implementation purposes. -An issue has already been created for postStart: [container initiliazation support](https://github.com/openshift/odo/issues/2936) +- Add support for `postStart` commands: [container initialization support](https://github.com/openshift/odo/issues/2936) +- Add support for `preStop` commands: ## Design overview +Some of the events might not be useful for `odo` to adopt. We should only support the ones that have a clear use-case, and then add more as other use-cases emerge. -The lifecycle events that have been implemented in Devfile 2.0 are generic. So their effect/meaning might be slightly different when applying them to a workspace (Che) or a single project (odo). However, this proposal will aim to provide a similar user experience within the scope of a single project. - -Our proposal is that the postStart event will run as a part of **odo push**, and that the preStop event will run as a part of **odo delete**. - +For odo, the most important events are the `postStart`, and the `preStop` because they have clear, reasonable use case within odo’s flow. There is no clear use case within odo for `preStart` and `postStop` today. -### The flow for **odo push** including the *postStart* lifecycle event will be as follows: - - Start the container(s) (as done today) - - postStart - Exec the specified command(s) in the container - one time only - - Rest of the command execution (as we do today - exec commands for build/run/test/debug) +- `preStart` - Do not support in odo +- `postStart` - support executing these commands as part of component initialization +- `preStop` - support executing these commands as part of the component delete +- `postStop` - Do not support in odo +As per the Devfile 2.0.0 design specification: +- Commands associated with a lifecycle binding should provide a mechanism to figure out when they have completed. That means that the command should be terminating or having a readiness probe. -**Starting the container(s)** - - The containers specified in the Devfile are initialized and created if the component doesn’t already exist. +- Commands associated with the same lifecycle binding do not guarantee to be executed sequentially or in any order. To run commands in a given order a user should use a composite. -**postStart** - - If the component is newly created, the postStart events are executed sequentially within the containers given in the Devfile. - - If any of the *postStart* commands do fail, then we would exit the **odo push** and report the error that had occurred. If it had failed to execute one of the postStart commands, the **odo push** might behave differently to what the stack creator had intended, so we would bail out early. - - This functionality would also act as a replacement for `devInit` in devfile v1.0. +The flow for initializing and deleting components should be updated to add execution of commands bound to relevant lifecycle event while initializing and destroying any containers. -**Command Execution** - - After postStart, we’d run the usual build/run/test/debug commands (depending on what sort of odo push parameters the user has provided) as usual. +### Initialize containers +- Identify which containers have been created as part of creating/updating the component deployment + - Initial implementation can assume containers are only initialised during the component creation (first push). We can improve this in future to allow execution of postStart commands at a more granular level. +- Iterate over the list of `postStart` commands and identify the ones that are associated with newly started containers +- execute the identified commands one by one + - execute the command in the container + - on failure, display a meaningful error message and stop + - on success, execute next command in the list (if any) +- consider the component has been successfully initialised and continue as usual - This flow relies on the assumption that all of the postCommands will only be required to run on the first `odo push` of the given odo project. A more in-depth description of a potential further developed approach is documented in the Future Evolution section of the proposal. + Note: This functionality would act as a replacement for `devInit` in devfile v1.0. +### Destroy containers +- Identify which containers will be deleted as of a result of deleting the component deployment +- prepare a list of `preStop` commands that are associated with the containers being destroyed +- execute the preStop commands one by one + - execute the command in the container + - on failure, display a meaningful error message and stop + - on success, execute next command in the list (if any) +- destroy/delete the component and continue as usual -### The flow for **odo delete** including the *preStop* lifecycle event will be as follows: - - preStop - Exec the specified command(s) in the container - - Clean up the pod and deployment etc. (as done today) - -**preStop** - - Exec the specified command(s) in their respective containers before deleting the deployment and any clean up begins. - - If any of the *preStop* commands do fail, then we would exit the **odo delete** and report the error that had occurred. If it had failed to execute one of the preStop commands, the **odo delete** might behave differently to what the stack creator had intended, so we would bail out early. - - -### Flow with example devfile: +## Example devfile with lifecycle binding: ``` schemaVersion: "2.0.0" metadata: - name: test-devfile + name: test-devfile projects: - - name: nodejs-web-app - git: - location: "https://github.com/che-samples/web-nodejs-sample.git" + - name: nodejs-web-app + git: + location: "https://github.com/che-samples/web-nodejs-sample.git" components: - - container: - id: tools - image: quay.io/eclipse/che-nodejs10-ubi:nightly - name: "tools" - - container: - id: runtime - image: quay.io/eclipse/che-nodejs10-ubi:nightly - name: "runtime" + - container: + id: tools + image: quay.io/eclipse/che-nodejs10-ubi:nightly + name: "tools" + - container: + id: runtime + image: quay.io/eclipse/che-nodejs10-ubi:nightly + name: "runtime" commands: - - exec: - id: download dependencies - commandLine: "npm install" - component: tools - workingDir: ${CHE_PROJECTS_ROOT}/nodejs-web-app/app - group: - kind: build - - exec: - id: run the app - commandLine: "nodemon app.js" - component: runtime - workingDir: ${CHE_PROJECTS_ROOT}/nodejs-web-app/app - group: - kind: run - - exec: - id: firstPostStartCmd - commandLine: echo I am the first PostStart - component: tools - workingDir: ${CHE_PROJECTS_ROOT}/ - - exec: - id: secondPostStartCmd - commandLine: echo I am the second PostStart - component: tools - workingDir: ${CHE_PROJECTS_ROOT}/ - - exec: - id: disconnectDatabase - commandLine: echo disconnecting from the database - component: tools - workingDir: ${CHE_PROJECTS_ROOT}/ + - exec: + id: download dependencies + commandLine: "npm install" + component: tools + workingDir: ${CHE_PROJECTS_ROOT}/nodejs-web-app/app + group: + kind: build + - exec: + id: run the app + commandLine: "nodemon app.js" + component: runtime + workingDir: ${CHE_PROJECTS_ROOT}/nodejs-web-app/app + group: + kind: run + - exec: + id: firstPostStartCmd + commandLine: echo I am the first PostStart + component: tools + workingDir: ${CHE_PROJECTS_ROOT}/ + - exec: + id: secondPostStartCmd + commandLine: echo I am the second PostStart + component: tools + workingDir: ${CHE_PROJECTS_ROOT}/ + - exec: + id: disconnectDatabase + commandLine: echo disconnecting from the database + component: tools + workingDir: ${CHE_PROJECTS_ROOT}/ events: - postStart: - - "firstPostStartCmd" - - "secondPostStartCmd" - preStop: - - "disconnectDatabase" - + postStart: + - "firstPostStartCmd" + - "secondPostStartCmd" + preStop: + - "disconnectDatabase" + ``` The example flow for **odo push** in this case would be: @@ -118,26 +116,14 @@ The example flow for **odo push** in this case would be: - execute build command - execute run command - The example flow for **odo delete** in this case would be: + The example flow for **odo delete**, in this case, would be: - execute disconnectDatabase - clean up the pod and deployment etc. (as done today) - - -### Conclusions: - - We think that the most important events are the postStart, and the preStop because they have clear, reasonable use case within odo’s flow. - - We aren’t fully conclusive on the necessity of preStart and postStop. They do not currently have a useful case within odo. - ## Future Evolution - -The above proposed implementation of postStart events could be further improved upon in future developments. There is potential to be more granular by identifying which specific container we are initializing, and whether or not there is a postStart command associated with it. With this, we could better utilize the postStart commands and use them in cases where only some of the containers are being initialized. - +## Future Evolution -A potential flow could be to check for postStart commands associated with a specific container when inititializing it, storing those commands in an Object(?) and then executing only those postStart commands when the containers have all finished initializing (in the order that they have been defined within the devfile). This would benefit cases where an individual container has been re-initialized, but not the whole component. For example, if a build container has been restarted as a part of **odo push --force** and there is a postStart command associated with the build container in the devfile that is required to re-run, that single postStart command would be executed before continuing to the build/run phase of the push command. +The initial implementation of postStart events assumes all containers are initilised during component startup (first push). In future we could make this granular and allow executing these postStart commands if containers are restarted by other commands/events too. +Example: A potential flow could be to check for postStart commands associated with a specific container when initializing it, storing those commands in an Object(?) and then executing only those postStart commands when the containers have all finished initializing (in the order that they have been defined within the devfile). This would benefit cases where an individual container has been re-initialized, but not the whole component. For example, if a build container has been restarted as a part of **odo push --force** and there is a postStart command associated with the build container in the devfile that is required to re-run, that single postStart command would be executed before continuing to the build/run phase of the push command. -There could be room for such a feature, and a case could be presented to argue the validity of changing the flow of **odo push** in order to accommodate such cases in a future implementation. - - -Additionally, *preStop* and *postStop* events are supported in Devfile 2.0, but aren't currently applicable to odo. In the future, a reason could arise where would benefit from these events. - - +Today, *preStop* and *postStop* events are supported in Devfile 2.0.0, but there is no clear use case for them in odo. As and when we have a clear use case, we should consider implementing those for odo too. \ No newline at end of file From c746a9e064a8f82230e63b2bf370b6bce0c59332 Mon Sep 17 00:00:00 2001 From: Neeraj Laad Date: Wed, 8 Jul 2020 16:37:36 +0100 Subject: [PATCH 07/10] Update lifecycle_events.md --- docs/proposals/lifecycle_events.md | 93 +++++++++++++++--------------- 1 file changed, 46 insertions(+), 47 deletions(-) diff --git a/docs/proposals/lifecycle_events.md b/docs/proposals/lifecycle_events.md index 6ece1a5a62b..370e17d5e9b 100644 --- a/docs/proposals/lifecycle_events.md +++ b/docs/proposals/lifecycle_events.md @@ -56,57 +56,56 @@ The flow for initializing and deleting components should be updated to add execu ``` schemaVersion: "2.0.0" metadata: - name: test-devfile + name: test-devfile projects: - - name: nodejs-web-app - git: - location: "https://github.com/che-samples/web-nodejs-sample.git" + - name: nodejs-web-app + git: + location: "https://github.com/che-samples/web-nodejs-sample.git" components: - - container: - id: tools - image: quay.io/eclipse/che-nodejs10-ubi:nightly - name: "tools" - - container: - id: runtime - image: quay.io/eclipse/che-nodejs10-ubi:nightly - name: "runtime" + - container: + id: tools + image: quay.io/eclipse/che-nodejs10-ubi:nightly + name: "tools" + - container: + id: runtime + image: quay.io/eclipse/che-nodejs10-ubi:nightly + name: "runtime" commands: - - exec: - id: download dependencies - commandLine: "npm install" - component: tools - workingDir: ${CHE_PROJECTS_ROOT}/nodejs-web-app/app - group: - kind: build - - exec: - id: run the app - commandLine: "nodemon app.js" - component: runtime - workingDir: ${CHE_PROJECTS_ROOT}/nodejs-web-app/app - group: - kind: run - - exec: - id: firstPostStartCmd - commandLine: echo I am the first PostStart - component: tools - workingDir: ${CHE_PROJECTS_ROOT}/ - - exec: - id: secondPostStartCmd - commandLine: echo I am the second PostStart - component: tools - workingDir: ${CHE_PROJECTS_ROOT}/ - - exec: - id: disconnectDatabase - commandLine: echo disconnecting from the database - component: tools - workingDir: ${CHE_PROJECTS_ROOT}/ + - exec: + id: download dependencies + commandLine: "npm install" + component: tools + workingDir: ${CHE_PROJECTS_ROOT}/nodejs-web-app/app + group: + kind: build + - exec: + id: run the app + commandLine: "nodemon app.js" + component: runtime + workingDir: ${CHE_PROJECTS_ROOT}/nodejs-web-app/app + group: + kind: run + - exec: + id: firstPostStartCmd + commandLine: echo I am the first PostStart + component: tools + workingDir: ${CHE_PROJECTS_ROOT}/ + - exec: + id: secondPostStartCmd + commandLine: echo I am the second PostStart + component: tools + workingDir: ${CHE_PROJECTS_ROOT}/ + - exec: + id: disconnectDatabase + commandLine: echo disconnecting from the database + component: tools + workingDir: ${CHE_PROJECTS_ROOT}/ events: - postStart: - - "firstPostStartCmd" - - "secondPostStartCmd" - preStop: - - "disconnectDatabase" - + postStart: + - "firstPostStartCmd" + - "secondPostStartCmd" + preStop: + - "disconnectDatabase" ``` The example flow for **odo push** in this case would be: From ba9591460173fe4abd69775a4c4d5accdccd365d Mon Sep 17 00:00:00 2001 From: Luke Weston Date: Thu, 9 Jul 2020 13:37:01 +0100 Subject: [PATCH 08/10] More clarity for when the postStart events would execute --- docs/proposals/lifecycle_events.md | 11 ++++++----- 1 file changed, 6 insertions(+), 5 deletions(-) diff --git a/docs/proposals/lifecycle_events.md b/docs/proposals/lifecycle_events.md index 370e17d5e9b..30082244eec 100644 --- a/docs/proposals/lifecycle_events.md +++ b/docs/proposals/lifecycle_events.md @@ -34,23 +34,24 @@ The flow for initializing and deleting components should be updated to add execu ### Initialize containers - Identify which containers have been created as part of creating/updating the component deployment - Initial implementation can assume containers are only initialised during the component creation (first push). We can improve this in future to allow execution of postStart commands at a more granular level. +- Sync the source code to the containers - Iterate over the list of `postStart` commands and identify the ones that are associated with newly started containers -- execute the identified commands one by one +- Execute the identified commands one by one - execute the command in the container - on failure, display a meaningful error message and stop - on success, execute next command in the list (if any) -- consider the component has been successfully initialised and continue as usual +- Consider the component has been successfully initialised and continue as usual (e.g. execute build command) Note: This functionality would act as a replacement for `devInit` in devfile v1.0. ### Destroy containers - Identify which containers will be deleted as of a result of deleting the component deployment -- prepare a list of `preStop` commands that are associated with the containers being destroyed -- execute the preStop commands one by one +- Prepare a list of `preStop` commands that are associated with the containers being destroyed +- Execute the preStop commands one by one - execute the command in the container - on failure, display a meaningful error message and stop - on success, execute next command in the list (if any) -- destroy/delete the component and continue as usual +- Destroy/delete the component and continue as usual ## Example devfile with lifecycle binding: ``` From f44bba02092f28bb2b610bbf3d0dfb3259a70a4e Mon Sep 17 00:00:00 2001 From: Luke Weston Date: Tue, 14 Jul 2020 12:01:46 +0100 Subject: [PATCH 09/10] Added brief mention of support for preStart and postStop --- docs/proposals/lifecycle_events.md | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/docs/proposals/lifecycle_events.md b/docs/proposals/lifecycle_events.md index 30082244eec..c3e5afb08fe 100644 --- a/docs/proposals/lifecycle_events.md +++ b/docs/proposals/lifecycle_events.md @@ -19,10 +19,10 @@ Some of the events might not be useful for `odo` to adopt. We should only suppor For odo, the most important events are the `postStart`, and the `preStop` because they have clear, reasonable use case within odo’s flow. There is no clear use case within odo for `preStart` and `postStop` today. -- `preStart` - Do not support in odo +- `preStart` - support executing these commands via init containers - `postStart` - support executing these commands as part of component initialization - `preStop` - support executing these commands as part of the component delete -- `postStop` - Do not support in odo +- `postStop` - support executing these commands via standalone pod or job and delete it once complete As per the Devfile 2.0.0 design specification: - Commands associated with a lifecycle binding should provide a mechanism to figure out when they have completed. That means that the command should be terminating or having a readiness probe. From 94a539a08df354657e7b51580a925d6381edf099 Mon Sep 17 00:00:00 2001 From: Luke Weston Date: Wed, 15 Jul 2020 10:27:02 +0100 Subject: [PATCH 10/10] Added links for new event issues --- docs/proposals/lifecycle_events.md | 18 ++++++++++++------ 1 file changed, 12 insertions(+), 6 deletions(-) diff --git a/docs/proposals/lifecycle_events.md b/docs/proposals/lifecycle_events.md index c3e5afb08fe..cfae6f568dc 100644 --- a/docs/proposals/lifecycle_events.md +++ b/docs/proposals/lifecycle_events.md @@ -11,14 +11,14 @@ Devfiles support commands that can be triggered based on development lifecycle e ## User Stories Each lifecycle event would be suited to individual user stories. We propose that at least one issue is made for each of them for tracking and implementation purposes. +- Add support for `preStart` commands: [preStart lifecycle event support](https://github.com/openshift/odo/issues/3565) - Add support for `postStart` commands: [container initialization support](https://github.com/openshift/odo/issues/2936) -- Add support for `preStop` commands: +- Add support for `preStop` commands: [preStop lifecycle event support](https://github.com/openshift/odo/issues/3566) +- Add support for `postStop` commands: [postStop lifecycle event support](https://github.com/openshift/odo/issues/3577) ## Design overview Some of the events might not be useful for `odo` to adopt. We should only support the ones that have a clear use-case, and then add more as other use-cases emerge. -For odo, the most important events are the `postStart`, and the `preStop` because they have clear, reasonable use case within odo’s flow. There is no clear use case within odo for `preStart` and `postStop` today. - - `preStart` - support executing these commands via init containers - `postStart` - support executing these commands as part of component initialization - `preStop` - support executing these commands as part of the component delete @@ -31,6 +31,10 @@ As per the Devfile 2.0.0 design specification: The flow for initializing and deleting components should be updated to add execution of commands bound to relevant lifecycle event while initializing and destroying any containers. +### preStart + - `preStart` command(s) that are specified in the devfile will be translated into entry points for their specified containers, and added to the pod spec as init containers. + - These are commands that the stack creator intends to run before the main containers are created/initialized. + ### Initialize containers - Identify which containers have been created as part of creating/updating the component deployment - Initial implementation can assume containers are only initialised during the component creation (first push). We can improve this in future to allow execution of postStart commands at a more granular level. @@ -53,6 +57,10 @@ The flow for initializing and deleting components should be updated to add execu - on success, execute next command in the list (if any) - Destroy/delete the component and continue as usual +### postStop +- Execute the `postStop` commands one by one + - via standalone pod or job and delete it once complete + ## Example devfile with lifecycle binding: ``` schemaVersion: "2.0.0" @@ -124,6 +132,4 @@ The example flow for **odo push** in this case would be: The initial implementation of postStart events assumes all containers are initilised during component startup (first push). In future we could make this granular and allow executing these postStart commands if containers are restarted by other commands/events too. -Example: A potential flow could be to check for postStart commands associated with a specific container when initializing it, storing those commands in an Object(?) and then executing only those postStart commands when the containers have all finished initializing (in the order that they have been defined within the devfile). This would benefit cases where an individual container has been re-initialized, but not the whole component. For example, if a build container has been restarted as a part of **odo push --force** and there is a postStart command associated with the build container in the devfile that is required to re-run, that single postStart command would be executed before continuing to the build/run phase of the push command. - -Today, *preStop* and *postStop* events are supported in Devfile 2.0.0, but there is no clear use case for them in odo. As and when we have a clear use case, we should consider implementing those for odo too. \ No newline at end of file +Example: A potential flow could be to check for postStart commands associated with a specific container when initializing it, storing those commands in an Object(?) and then executing only those postStart commands when the containers have all finished initializing (in the order that they have been defined within the devfile). This would benefit cases where an individual container has been re-initialized, but not the whole component. For example, if a build container has been restarted as a part of **odo push --force** and there is a postStart command associated with the build container in the devfile that is required to re-run, that single postStart command would be executed before continuing to the build/run phase of the push command. \ No newline at end of file