0

I am writing code to update deployed image on marathon automatically. I use the REST patch method as listed in marathon API reference http://mesosphere.github.io/marathon/api-console/index.html

    url = 'https://<my-hostname>:<my-port>/v2/apps'
    h = {'Content-type': 'application/json', 'Accept': 'application/json'}
    data = {'app': { "id": app,
                'container': {
                    'docker': {
                        'image': image}}}}
    print ('requests.patch(%s, %s)' % (url + app, json.dumps(data)))
    r = requests.patch(url + app, headers = h, auth = auth, data = json.dumps(data))
    if r.status_code == 200:
        print('Deployed %s' % app)

The code ran successfully, I got back a Deployment ID, but nothing was changed from the UI. No new deployment is happening. If I change the patch request into get request without the data, I get back the image I previous updated in using code above.

According to this similar API reference https://docs.mesosphere.com/1.11/deploying-services/marathon-api/#/apps/V2AppsByAppId1

It says " This operation will create a deployment" but nothing happened. From the Marathon GUI, I don't see the configuration getting changed at all. If I restart, it is the same old deployment getting restarted. Am I interpreting the API reference incorrectly?

some user
  • 876
  • 1
  • 12
  • 26

2 Answers2

1

If I read the API reference guide correctly, the body should be:

{ "id": app,
  "container": {
       "docker": {
          "image": image
        }
   }
}

Tested this with marathon 1.4.11 and that worked. Not sure why you would get a deploymentid, if I do it the way you did (with the extra {"app":} layer), I get a 500 error. BTW, I am not sure how sensitive this is for single versus double quotes.

AntonioM
  • 166
  • 3
  • I felt so stupid! You are right. I have that extra "app" enclosure. I'm not sure where I get it from. Removing the app layer just works! – some user May 08 '19 at 21:15
  • I know why. When I made the GET request, the result is stored inside the "app" enclosure. I just assumed I should use the same format when patching. – some user May 09 '19 at 00:21
0

There is open bug in Marathon which cause that request body is not merged with current definition. Therefore, PUT/PATCH request with only .container.docker.image will remove settings like port mappings, volumes, parameters...

Solution is to get container object from current application and replace image key with new Docker image.

Example:

export MARATHON_IMAGE="registry.foo.bar/app:v10"

export BODY=$(curl -s -H "Content-type: application/json" leader.mesos:8080/v2/apps/foo/bar | jq -cr '.app.container | .docker.image = env.MARATHON_IMAGE | {"container": .}')

curl -s -H "Content-type: application/json" -X PATCH -d "${BODY}" leader.mesos:8080/v2/apps/foo/bar