dcos / dcos-cli

The command line for DC/OS.
https://docs.d2iq.com/mesosphere/dcos/latest/cli/
Apache License 2.0
224 stars 118 forks source link

How can I change one file in a marathon app? #1107

Closed andrei-bv closed 6 years ago

andrei-bv commented 6 years ago

Is there a way to trigger a redeploy for a Marathon application already running in a DC/OS cluster, without changing the definition file (.json) as the configuration for that app would remain the same.

For example I need to make a change in the index.php file and redeploy the app by means of Docker image using Jenkins.

Thank you

meichstedt commented 6 years ago

@andrei-bv the Marathon API has a /v2/apps/{app_id}/restart endpoint via which you can trigger a restart for all associated tasks. The related dcos-cli command is dcos marathon app restart [--force] <app-id>

bamarni commented 6 years ago

Restarting the app assumes that you are overwriting the tag in use for your docker image and that forcePullImage is set to true. Another way which is imo preferable is to update the app :

echo '{"container": {"docker": {"image": "my-app:X.Y.Z" } } }' | dcos marathon app update /my-app

This would deploy the same app with the specified image tag and kill the previous one.

@meichstedt : let us know if you rather suggest another approach for this.

andrei-bv commented 6 years ago

@bamarni - forcePullImage is set to TRUE in my configuration file and also the image tag is unique with every try, set as the git commit id (${GIT_COMMIT}) - but unless I change the marathon definition file, trying to redeploy thru Jenkins UI will not work. I get "Build successful" in Jenkins - but no restart in DC/OS.

bamarni commented 6 years ago

@andrei-bv : forcePullImage only pulls the image for the given tag in use in your marathon definition. The other way that I recommended to you is to update the app with the new tag you want.

jordi-t commented 6 years ago

@bamarni i'm trying it through the method you described above, echo'ing the JSON, but this completely removes existing config for the docker part. Here are the steps:

Before: "container": { "docker": { "image": "abc/myimage:v1", "forcePullImage": true, "privileged": false, "portMappings": [ { "containerPort": 8000, "protocol": "tcp", "servicePort": 10122, "labels": { "VIP_0": "/a/b:8000" } } ], "network": "BRIDGE" } }

Execute: echo '{"container": {"docker": {"image": "abc/myimage:v2" } } }' | dcos marathon app update a/b

Results in:

"container": { "docker": { "image": "abc/myimage:v2", "forcePullImage": false, "privileged": false, "network": "HOST" } }

I would expect that only the {image} part is changed. Of course we can extend the json we echo with the necessary values, but that feels like a bit too much.

Btw, we are running a pretty old version:

dcoscli.version=0.4.15 dcos.version=1.8.8

Has this behaviour been changed in newer versions perhaps?

meichstedt commented 6 years ago

@jseris Ok that explains the problem :)

Updating an app definition will patch the fields you provide. However, Marathon doesn't allow to patch fields in a property object of the app definition. Meaning: you can e.g. patch the amount of cpus, but you cannot only patch the image of the container property. In this case, unfortunately, you need to fetch the app definition, update the image on the configured container object, and then patch the whole container object on the app (or the whole app definition).

bamarni commented 6 years ago

Thank for the explanation @meichstedt, I missed that as I was testing with a minimal container definition.

jordi-t commented 6 years ago

@meichstedt thanks for explaining 👍 Got it working now :)