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

control over how rsync and start/stop happens #3132

Closed
maxandersen opened this issue May 9, 2020 · 14 comments · Fixed by #4588
Closed

control over how rsync and start/stop happens #3132

maxandersen opened this issue May 9, 2020 · 14 comments · Fixed by #4588
Assignees
Labels
kind/feature Categorizes issue as a feature request. For PRs, that means that the PR is the implementation

Comments

@maxandersen
Copy link
Contributor

/kind feature

Which functionality do you think we should add?

Being able to customize in devfile what folders are rsynced to not only support in-cluster source builds but be able to take locally built artifacts and put in a specific location on the deployment.

Why is this needed?

to support wildfly, tomcat, or any other runtime that supports true incremental hotdeploy of resources (wether source or binaries) (quarkus will support this in upcoming releases)

Advantages:

  • speed - allows us to fully skip the incluster build.
  • experimentation - one can do local changes and experiments not necessarily encoded in pom.xml etc. yet
  • local vs remote are in sync; less surprises during development
  • can be used to focus source based builds too to save time

disadvantages:

  • makes non-reproducible builds (but that is the same today where you don't need to commit to see changes)
@openshift-ci-robot openshift-ci-robot added the kind/feature Categorizes issue as a feature request. For PRs, that means that the PR is the implementation label May 9, 2020
@kadel
Copy link
Member

kadel commented Jun 8, 2020

I can see two options for how this be done in odo.
I prefer the second one as it makes it possible switch between "do everything in cluster" and "local build, in-cluster run"

Special Devfile that supports local build.

This would be devfile that doesn't define any build commands.

example of a devfile.yaml without build
schemaVersion: 2.0.0
metadata:
  name: maven
  version: 1.0.0
components:
  - container:
      name: tools
      image: quay.io/eclipse/che-java11-maven:nightly
      mountSources: true
commands:
  - exec:
      id: run
      component: tools
      commandLine: "java -jar target/*.jar"
      group:
        kind: run
        isDefault: true 

The only problem that we need to solve here is that odo needs to know what are the build artifacts that need to be pushed to the container.
For this, we could introduce new config option for odo push command --artifacts. This flag would be the opposite of --ignore.
odo push --artifacts target would push only the target directory and nothing else.

Option to skip build step, with regular devfile.yaml

normal devfile.yaml with build and run commands
schemaVersion: 2.0.0
metadata:
  name: maven
  version: 1.0.0
components:
  - container:
      name: tools
      image: quay.io/eclipse/che-java11-maven:nightly
      mountSources: true
commands:
  - exec:
      id: devBuild
      component: tools
      commandLine: "mvn package"
      group:
        kind: build
        isDefault: true
  - exec:
      id: run
      component: tools
      commandLine: "java -jar target/*.jar"
      group:
        kind: run
        isDefault: true 

For odo push we would have to introduce two new flags. In addition to --artifacts flag as described above this would need a flag that would tell odo that no build is required - --skip-build (or --run-only).

@maxandersen
Copy link
Contributor Author

why is it you would want the artifacts as part of the command line of odo and not as something defined in the devfile ?

@gorkem
Copy link
Contributor

gorkem commented Jun 15, 2020

@kadel Is .odoignore still used with devfiles?

@kadel kadel added this to the 2.2 (Planning) milestone Aug 12, 2020
@mik-dass
Copy link
Contributor

mik-dass commented Mar 3, 2021

@kadel Is .odoignore still used with devfiles?

Yes devfile components do use .odoignore.

@mik-dass
Copy link
Contributor

mik-dass commented Mar 4, 2021

For odo push we would have to introduce two new flags. In addition to --artifacts flag as described above this would need a flag that would tell odo that no build is required - --skip-build (or --run-only).

We should also find a way to save the info in the env.yaml instead of using the artifacts flag during every push.

@dharmit
Copy link
Member

dharmit commented Mar 22, 2021

Please update the issue as discussed on the triage call. @kadel

@kadel
Copy link
Member

kadel commented Mar 23, 2021

Background - how to do remote dev with quarkus

Quarkus has a remote development mode. In this mode Quarkus handles syncing and reloading on its own. Odo should let Quarkus handle it and don't interfere.

To use Quarkus remote dev mode, you first need to add following lines to src/main/resources/application.properties

quarkus.package.type=mutable-jar 
quarkus.live-reload.password=changeit 

Than you build the jar file (mvn package). This will produce Quarkus application jar in target/quarkus-app/quarkus-run.jar.

After transferring the jar file into the remote side, you set export QUARKUS_LAUNCH_DEVMODE=true and run the application java -jar quarkus-run.jar.

On the local side (your laptop) you just need to execute ./mvnw quarkus:remote-dev -Dquarkus.live-reload.url=<url where your app is runnign>. (NOTE: For example, if your application is running on OpenShift cluster quarkus.live-reload.url will point to Route url.

How remote devmode works

The local and remote are communicating bi-bidirectionally. My understanding of how this works:

  • When you access the remote application, it asks the local side if there were changes.
  • If something changed, the local side builds new jar and class files and sends them to the remote.
  • Remote side does hot-reload and starts running new code.

All this is fast enough that it happens within the request time.

How to do Quarkus dev mode in current odo (hacky and slow)

It is already possible to write a devfile that will use Quarkus remote devmode. Problem is that with how odo currently works, this will be even slower than doing regular source push, rebuild, reload.

To test this you:

  • Download Quarkus app from code.quarkus.io.

  • Add following lines to src/main/resources/application.properties.

    quarkus.package.type=mutable-jar 
    quarkus.live-reload.password=changeit 
    
  • mvn package

  • In the directory with Quarkus app create devfile.yaml with the content shown below.

  • Edit .gitignore and remove target/ line from it. **Without this odo ignores target directory and it won't sync its content to cluster.

  • odo project create quarkus-test

  • odo push This will take a long time, because odo syncs full source code including full target directory to the cluster. But all that is required is one file target/quarkus-app/quarkus-run.jar

  • When push is done application should be accessible on the url

  • Now you can run ./mvnw quarkus:remote-dev -Dquarkus.live-reload.url=<url> on your local machine.

  • When you edit the code, and then try to access the application on the url, you should see that the local side is building the app and sending it to the remote.

schemaVersion: 2.0.0
metadata:
  name: java-quarkus-remotedev
  version: 1.1.0
  website: https://quarkus.io
starterProjects:
  - name: community
    zip:
      location: https://code.quarkus.io/d?e=io.quarkus%3Aquarkus-resteasy&e=io.quarkus%3Aquarkus-micrometer&e=io.quarkus%3Aquarkus-smallrye-health&e=io.quarkus%3Aquarkus-openshift&cn=devfile
  - name: redhat-product
    zip:
      location: https://code.quarkus.redhat.com/d?e=io.quarkus%3Aquarkus-resteasy&e=io.quarkus%3Aquarkus-smallrye-health&e=io.quarkus%3Aquarkus-openshift
components:
  - name: tools
    container:
      image: quay.io/eclipse/che-quarkus:nightly
      memoryLimit: 1512Mi
      mountSources: true
      env:
        - name: QUARKUS_LAUNCH_DEVMODE
          value: "true"
      volumeMounts:
        - name: m2
          path: /home/user/.m2
      endpoints:
        - name: '8080-http'
          targetPort: 8080
  - name: m2
    volume:
      size: 3Gi
commands:
  - id: dev-run
    attributes:
       "dev.odo.push.path:target/quarkus-app/": "target/quarkus-app/"
    exec:
      component: tools
      commandLine: "java -jar target/quarkus-app/quarkus-run.jar -Dquarkus.http.host=0.0.0.0"
      hotReloadCapable: true
      group:
        kind: run
        isDefault: true
      workingDir: $PROJECTS_ROOT
  - id: dev-debug
    exec:
      component: tools
      commandLine: "java -Xdebug -Xrunjdwp:server=y,transport=dt_socket,address=${DEBUG_PORT},suspend=n -jar target/quarkus-app/quarkus-run.jar -Dquarkus.http.host=0.0.0.0"
      hotReloadCapable: true
      group:
        kind: debug
        isDefault: true
      workingDir: $PROJECTS_ROOT

How to better support remote dev flow in odo

There are two differences between Quarkus remote dev and regular odo flow.

  1. Build happens locally outside of odo control
  2. odo push should not sync the whole source code, but only one file.

The first item is already supported in odo. If there is no kind:build commands odo the build process is skipped.

For the second item we need to be able to tell odo that only certain files should be pushed the container.
We could leverage devfile attribute field. This field was intended to add a program specific information in devfile.

You can see attribute being set in the devfile sample above ("dev.odo.push.file:target/quarkus-app/quarkus-run.jar": "target/quarkus-app/quarkus-run.jar"). This will instruct odo that only a local file target/quarkus-app/quarkus-run.jar should be pushed to container at target/quarkus-app/quarkus-run.jar location.

The format of this attribute is dev.odo.push.file:<local file path>:<remote file path>. Devfile could have multiple dev.odo.push.file attributes for multiple files, each of them should be synced by odo push command. If dev.odo.push.file attribute is used, odo push should ignore .odoginore and .gitignore files.

@mik-dass
Copy link
Contributor

mik-dass commented Mar 25, 2021

  • Use the annotation "dev.odo.push.file:target/quarkus-app/quarkus-run.jar": "target/quarkus-app/quarkus-run.jar" to push only the required files to the given location. A devfile can also contain multiple such annotations.
  • If the build command exists, we execute it.

@dharmit
Copy link
Member

dharmit commented Mar 25, 2021

Can we also document the annotation and an example of how to do this entire thing on odo.dev?

@maxandersen
Copy link
Contributor Author

I think you would need more than just single file copying.
something like, "dev.odo.push.file:target/quarkus-app/*": "target/quarkus-app/"

also, are deletes handled ? like if a file is no longer there is the remote one removed ?

@mik-dass
Copy link
Contributor

mik-dass commented Apr 19, 2021

I think you would need more than just single file copying.
something like, "dev.odo.push.file:target/quarkus-app/*": "target/quarkus-app/"

Multiple remote attributes and folder based attributes will be supported but the syntax would be dev.odo.push.file:target/quarkus-app.

also, are deletes handled ? like if a file is no longer there is the remote one removed ?

Yes, deletion of files and removal of files upon removal of corresponding remote attributes will be supported. Here's the WIP PR #4588. All the scenarios can be tested against the current state of the PR and it only requires cleanup ad integration tests currently.

@maxandersen
Copy link
Contributor Author

But how do you specify the target dir? They won't necessarily match inside the container?

@mik-dass
Copy link
Contributor

But how do you specify the target dir? They won't necessarily match inside the container?

The format of this attribute is dev.odo.push.file:: where remote file path is the target directory inside the source code folder in the container.

They won't necessarily match inside the container?

Yes the local path and the remote path might not match.

@mik-dass
Copy link
Contributor

mik-dass commented May 3, 2021

Since we want to support both files and folder, the name of the attribute has been changed to dev.odo.push.path.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
kind/feature Categorizes issue as a feature request. For PRs, that means that the PR is the implementation
Projects
None yet
Development

Successfully merging a pull request may close this issue.

7 participants