Skip to content

Initial support for chronos 3.x for #33#35

Merged
Rob-Johnson merged 26 commits into
asher:masterfrom
krux:enhancement/chronos-3
Mar 28, 2017
Merged

Initial support for chronos 3.x for #33#35
Rob-Johnson merged 26 commits into
asher:masterfrom
krux:enhancement/chronos-3

Conversation

@thekad
Copy link
Copy Markdown
Contributor

@thekad thekad commented Mar 7, 2017

This is the initial draft I wrote for support of chronos >= 3.x
It tries to play nice with versions < 3.x as well and it doesn't keep you from
shooting yourself in the foot. I am undecided at which point you draw the line
in the sand and only allow valid values sent.
Tested vs chronos 2.4 and 3.0.x

This is the initial draft I wrote for support of chronos >= 3.x
It tries to play nice with versions < 3.x as well and it doesn't keep you from
shooting yourself in the foot. I am undecided at which point you draw the line
in the sand and only allow valid values sent.
Tested vs chronos 2.4 and 3.0.x
@thekad
Copy link
Copy Markdown
Contributor Author

thekad commented Mar 7, 2017

I had to skirt around the testing environment because it is not so easy to change, however I came up with the following docker-compose.yml:

version: "2"

services:
  zookeeper:
    image: zookeeper
    container_name: zookeeper
    environment:
      ZOO_MY_ID: 1
      ZK_INIT_LIMIT: 10
      ZK_SYNC_LIMIT: 5

  master:
    image: mesosphere/mesos-master:1.0.3
    container_name: mesos-master
    environment:
      MESOS_ZK: zk://zookeeper:2181/mesos
      MESOS_QUORUM: 1
      MESOS_CLUSTER: chronos-python
      MESOS_REGISTRY: in_memory
    ports:
      - 5050:5050
    depends_on:
      - zookeeper
    links:
      - zookeeper

  slave:
    image: mesosphere/mesos-slave:1.0.3
    container_name: mesos-slave
    pid: host
    environment:
      MESOS_MASTER: zk://zookeeper:2181/mesos
      MESOS_WORK_DIR: /tmp/mesos
      MESOS_PORT: 5051
      MESOS_RESOURCES: ports(*):[11000-11999]
      MESOS_CONTAINERIZERS: mesos
    ports:
      - 5051:5051
    volumes:
      - /sys/fs/cgroup:/sys/fs/cgroup
    depends_on:
      - zookeeper
    links:
      - zookeeper
      - master

  chronos2:
    image: mesosphere/chronos:chronos-2.4.0-0.1.20150828104228.ubuntu1404-mesos-0.27.0-0.2.190.ubuntu1404
    container_name: chronos2
    command: '/usr/bin/chronos run_jar --http_port 4400 --zk_hosts zookeeper:2181 --master zk://zookeeper:2181/mesos'
    ports:
      - 4402:4400
    depends_on:
      - zookeeper
      - master
    links:
      - zookeeper
      - master
      - slave

  chronos3:
    image: mesosphere/chronos:v3.0.2
    container_name: chronos3
    command: '--zk_hosts zookeeper:2181 --master zk://zookeeper:2181/mesos'
    environment:
      PORT0: 4400
      PORT1: 8080
    ports:
      - 4403:4400
    depends_on:
      - zookeeper
      - master
    links:
      - zookeeper
      - master
      - slave

Which allows you to spin up a chronos 2.4 on port 4402 and a chronos 3.0.2 on port 4403, then I could modify itests/steps/chronos_steps.py to point individually to either one. One of the test cases fails in 3.x (obviously) because new chronos doesn't accept spaces in the job name

@thekad
Copy link
Copy Markdown
Contributor Author

thekad commented Mar 7, 2017

And of course travis build failed because the test env is not updated. I didn't want to mess with it but my idea would be to default to test everything in docker under travis via docker-compose https://docs.travis-ci.com/user/docker/ and run the same tests vs either port, depending which version of chronos you want to test (the docker-compose port bits would need updating as well) what do you think @Rob-Johnson ?

@solarkennedy
Copy link
Copy Markdown
Collaborator

How about just append the env to include a new CHRONOSVERSION and travis will matrix it out? Why not mess with it? This to me seems like the most direct way to test this, and only requires one line added to the .travis.yaml file.

You could do docker compose, we use it in https://github.com/thefactory/marathon-python. I recommend avoiding the complexity if you can.

@thekad
Copy link
Copy Markdown
Contributor Author

thekad commented Mar 8, 2017 via email

@solarkennedy
Copy link
Copy Markdown
Collaborator

Oh right, no debs from upstream. We'll docker it is I guess. Again the marathon-python does have some "ok" prior art.

Jorge Gallegos added 10 commits March 14, 2017 18:32
Which is pretty fantastic
Now it is a matter of passing the appropriate docker node defined in the
docker-compose.yml file. All chronos nodes will expose chronos on port 4400 so
all client calls will be done to localhost port 4400. No need to figure out
magically which port docker-compose is exposing or anything (at least in theory)
Comment thread chronos/__init__.py Outdated
else:
if scheduler_version not in SCHEDULER_VERSIONS:
raise ChronosAPIError('Wrong scheduler_version provided')
self._prefix = "/%s" % (scheduler_version,)
Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

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

I think you need to add empty-string '' to list list of acceptable SCHEDULER_VERSIONS, or allow None so people can keep using < 3

Comment thread chronos/__init__.py Outdated
raise MissingFieldError("missing required field %s" % k)

# Chronos v3.x rejects job names with spaces in them
regex = re.compile(r'^[\w.-]+$')
Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

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

what about < 3 though? this isn't really allowing for backwards compatibility - if I were you I'd let this happen and have clients deal with the failure (hopefully chronos spits out a reasonably informative error message?)

Comment thread chronos/__init__.py

class ChronosJob(object):
fields = [
"async",
Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

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

same comment re < 3. You're not really allowing for backwards compat here.

Jorge Gallegos added 7 commits March 22, 2017 09:59
@thekad
Copy link
Copy Markdown
Contributor Author

thekad commented Mar 22, 2017

@Rob-Johnson So I worked out most of the compatibility issues, but I seem to have tripped the py.test tests with da54db4, I am raising an ChronosAPIError when the chronos api, well, returns an error. However:

tests/test_chronos_init.py::test_check_returns_raw_response_when_not_json FAILED
tests/test_chronos_init.py::test_check_does_not_log_error_when_content_type_is_not_json FAILED
tests/test_chronos_init.py::test_check_logs_error_when_invalid_json FAILED

These 3 tests make me think not raising an error on chronos api errors was actually intentional, do you still think that's a valid route and I should revert the exception raising? or should the tests be reworked?

@Rob-Johnson
Copy link
Copy Markdown
Collaborator

those tests are more for handling Chronos not consistently returning JSON in failure modes. Happy for you to rework them as you see fit, so long as we keep similar behaviour: that is, the client handles non-json responses appropriately.

Jorge Gallegos added 4 commits March 23, 2017 13:40
Also the payload message might be too long as is
And also since we're throwing exceptions, make sure to catch them properly
@thekad
Copy link
Copy Markdown
Contributor Author

thekad commented Mar 23, 2017

@Rob-Johnson let me know what you think re: 1ba92a9 also I fixed the build and it now passes with 2.4.0 and 3.0.2 with both python 2.7 and 3.5.

Copy link
Copy Markdown
Collaborator

@Rob-Johnson Rob-Johnson left a comment

Choose a reason for hiding this comment

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

one last thing, but otherwise this looks good to me. want to take a glance over it @solarkennedy? one action point for us at Yelp is going to be adding api_version=None to our calls to create a Chronos client until we get our fork inline with upstream.

Comment thread chronos/__init__.py Outdated
except ImportError:
from urllib.parse import quote

SCHEDULER_VERSIONS = ('v1',)
Copy link
Copy Markdown
Collaborator

@Rob-Johnson Rob-Johnson Mar 24, 2017

Choose a reason for hiding this comment

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

can we rename this (and all mentions of scheduler_version) to be API_VERSION instead? it just makes it a little clearer what this actually does.

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

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

@Rob-Johnson I thought about this, but since chronos appears to have multiple APIs and they are only versioning /scheduler/* (they don't prefix /metrics, for example) that's why I decided to use this variable. Happy to change it to whatever name makes the most sense, naming is hard 😊

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

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

how about.... scheduler_api_version?

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

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

😲 see this is exactly why you get paid the big bucks @ yelp, gonna do that.

@Rob-Johnson Rob-Johnson merged commit e531f47 into asher:master Mar 28, 2017
@Rob-Johnson
Copy link
Copy Markdown
Collaborator

thanks @thekad !

@paddycarey paddycarey mentioned this pull request Apr 20, 2017
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants