)]}'
{"doc/specs/in-progress/os_services.rst":[{"author":{"_account_id":9545,"name":"Andriy Kurilin","email":"andr.kurilin@gmail.com","username":"akurilin"},"change_message_id":"fcdc4b8e5a0a0a164f897c41b24bec8aa3bb48bb","unresolved":false,"context_lines":[{"line_number":7,"context_line":".."},{"line_number":8,"context_line":" This template should be in ReSTructured text. The filename in the git"},{"line_number":9,"context_line":" repository should match the launchpad URL, for example a URL of"},{"line_number":10,"context_line":" https://blueprints.launchpad.net/heat/+spec/awesome-thing should be named"},{"line_number":11,"context_line":" awesome-thing.rst .  Please do not delete any of the sections in this"},{"line_number":12,"context_line":" template.  If you have nothing to say for a whole section, just write: None"},{"line_number":13,"context_line":" For help with syntax, see http://sphinx-doc.org/rest.html"}],"source_content_type":"text/x-rst","patch_set":1,"id":"7aaa499b_45032074","line":10,"updated":"2015-04-13 08:43:52.000000000","message":"heat template detected:)","commit_id":"86f43117ef07d1f7c9a41f53305022d4559d46cd"},{"author":{"_account_id":9545,"name":"Andriy Kurilin","email":"andr.kurilin@gmail.com","username":"akurilin"},"change_message_id":"80f69e06a58cb60d89e5d8695a1b2244fabfb4ab","unresolved":false,"context_lines":[{"line_number":42,"context_line":" |-os_services"},{"line_number":43,"context_line":"    |-common.py"},{"line_number":44,"context_line":"    |-\u003cservice\u003e"},{"line_number":45,"context_line":"    |   |-\u003cservice\u003e.py"},{"line_number":46,"context_line":"    |-network.py"},{"line_number":47,"context_line":"    |-keystone"},{"line_number":48,"context_line":"        |-keystone.py"}],"source_content_type":"text/x-rst","patch_set":2,"id":"7aaa499b_08388fd2","line":45,"updated":"2015-04-13 08:59:53.000000000","message":"imo, it would be better to rename \u003cservice\u003e.py to \u003cservice\u003e_utils.py, since all imports across Rally code look like:\n\n    from rally.benchmark.scenarios.\u003cservice\u003e import utils as \u003cservice\u003e_utils","commit_id":"588eabef9c021369e2b36d130a9b52aafea6fcd1"},{"author":{"_account_id":8576,"name":"Yair Fried","email":"yfried@redhat.com","username":"yfried"},"change_message_id":"6a8d04b660cffeb77aae42da4909f5bb4c7f45fa","unresolved":false,"context_lines":[{"line_number":42,"context_line":" |-os_services"},{"line_number":43,"context_line":"    |-common.py"},{"line_number":44,"context_line":"    |-\u003cservice\u003e"},{"line_number":45,"context_line":"    |   |-\u003cservice\u003e.py"},{"line_number":46,"context_line":"    |-network.py"},{"line_number":47,"context_line":"    |-keystone"},{"line_number":48,"context_line":"        |-keystone.py"}],"source_content_type":"text/x-rst","patch_set":2,"id":"7aaa499b_6841530b","line":45,"in_reply_to":"7aaa499b_08388fd2","updated":"2015-04-13 09:06:37.000000000","message":"IMO this is implementation detail. I\u0027m good either way","commit_id":"588eabef9c021369e2b36d130a9b52aafea6fcd1"},{"author":{"_account_id":6172,"name":"Boris Pavlovic","email":"boris@pavlovic.me","username":"boris-42"},"change_message_id":"3a9c64d8ec80f8672cec6bed85a51d16bbeb5939","unresolved":false,"context_lines":[{"line_number":18,"context_line":"Code that wraps openstack services from different scenario utils is difficult"},{"line_number":19,"context_line":"to reuse outside the scenario directory (ie, different scenarios and areas"},{"line_number":20,"context_line":"like context), which calls for code duplications and strange solutions like"},{"line_number":21,"context_line":"wrappers."},{"line_number":22,"context_line":""},{"line_number":23,"context_line":"Proposed change"},{"line_number":24,"context_line":"\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d"}],"source_content_type":"text/x-rst","patch_set":5,"id":"5aa745d1_209024ec","line":21,"updated":"2015-04-15 20:11:52.000000000","message":"As well it is hard to do versioning of such stuff.","commit_id":"9b8db0c7c3f619adcda2e501f944757d44ea560e"},{"author":{"_account_id":8576,"name":"Yair Fried","email":"yfried@redhat.com","username":"yfried"},"change_message_id":"20942667617df33ad2b83c743c2c42eb5b53b77e","unresolved":false,"context_lines":[{"line_number":18,"context_line":"Code that wraps openstack services from different scenario utils is difficult"},{"line_number":19,"context_line":"to reuse outside the scenario directory (ie, different scenarios and areas"},{"line_number":20,"context_line":"like context), which calls for code duplications and strange solutions like"},{"line_number":21,"context_line":"wrappers."},{"line_number":22,"context_line":""},{"line_number":23,"context_line":"Proposed change"},{"line_number":24,"context_line":"\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d"}],"source_content_type":"text/x-rst","patch_set":5,"id":"bab921fb_1024a65d","line":21,"in_reply_to":"5aa745d1_209024ec","updated":"2015-04-26 08:40:27.000000000","message":"Done","commit_id":"9b8db0c7c3f619adcda2e501f944757d44ea560e"},{"author":{"_account_id":10475,"name":"Alexander Maretskiy","email":"amaretskiy@mirantis.com","username":"maretskiy"},"change_message_id":"93ffb53b7920bc480f65c1bf9e5901aabbdfe1bc","unresolved":false,"context_lines":[{"line_number":35,"context_line":""},{"line_number":36,"context_line":"Implementation"},{"line_number":37,"context_line":"\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d"},{"line_number":38,"context_line":"current tree:"},{"line_number":39,"context_line":""},{"line_number":40,"context_line":".. code-block:: shell"},{"line_number":41,"context_line":""}],"source_content_type":"text/x-rst","patch_set":5,"id":"bab921fb_57e93fe5","line":38,"updated":"2015-04-24 17:26:34.000000000","message":"Add blank line immediately after header (between L37-38)","commit_id":"9b8db0c7c3f619adcda2e501f944757d44ea560e"},{"author":{"_account_id":8576,"name":"Yair Fried","email":"yfried@redhat.com","username":"yfried"},"change_message_id":"20942667617df33ad2b83c743c2c42eb5b53b77e","unresolved":false,"context_lines":[{"line_number":35,"context_line":""},{"line_number":36,"context_line":"Implementation"},{"line_number":37,"context_line":"\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d"},{"line_number":38,"context_line":"current tree:"},{"line_number":39,"context_line":""},{"line_number":40,"context_line":".. code-block:: shell"},{"line_number":41,"context_line":""}],"source_content_type":"text/x-rst","patch_set":5,"id":"bab921fb_f0281235","line":38,"in_reply_to":"bab921fb_57e93fe5","updated":"2015-04-26 08:40:27.000000000","message":"Done","commit_id":"9b8db0c7c3f619adcda2e501f944757d44ea560e"},{"author":{"_account_id":10475,"name":"Alexander Maretskiy","email":"amaretskiy@mirantis.com","username":"maretskiy"},"change_message_id":"93ffb53b7920bc480f65c1bf9e5901aabbdfe1bc","unresolved":false,"context_lines":[{"line_number":52,"context_line":""},{"line_number":53,"context_line":"    Example1(utils.ExampleScenario)"},{"line_number":54,"context_line":""},{"line_number":55,"context_line":"Suggested change:"},{"line_number":56,"context_line":""},{"line_number":57,"context_line":".. code-block:: shell"},{"line_number":58,"context_line":""}],"source_content_type":"text/x-rst","patch_set":5,"id":"bab921fb_b54ac9aa","line":55,"updated":"2015-04-24 17:26:34.000000000","message":"Please consider about the following:\n\n * scenarios are actually plugins\n\n * I think that term `service\u0027 is perfect.\n   Identity/keystone, compute/nova and others are OpenStack services,\n   and scenarios utils in most cases just make a facade to them\n\n * In my opinion, we need the following:\n\n    - move atomic actions to scenarios\n\n    - move generic code from scenarios utils to more generic place and put into\n      modules, each related to specific environment service,\n      for example `compute\u0027 (or, maybe, `nova\u0027 - if using another convention)\n\n    - each service module should have class inherited from some base class,\n      with some unified interface\n\n    - this class should have `Service\u0027 in its name\n\n    - this services must support versioning\n\n    - wrappers from rally/benchmark/wrapper/* should be transformed into services\n\n    - there should be unified factory how to get service instance\n\n\nBased on the points above, here is how I see changes on filesystem:\n\n\n CURRENT\n \u003d\u003d\u003d\u003d\u003d\u003d\u003d\n\n rally/\n   |\n   +-- benchmark/\n           |\n           +-- scenarios/\n           |      |\n           |      +-- nova/\n           |      |     |\n           |      |     +-- servers.py\n           |      |     |\n           |      |     `-- utils.py\n           |      |\n           |      `-- ...\n           |\n           `-- wrappers/\n                  |\n                  +-- keystone.py\n                  |\n                  `-- network.py\n\n PROPOSAL\n \u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\n\n rally/\n   |\n   +-- benchmark/\n   |       |\n   |       `-- scenarios/\n   |              | \n   |              `-- nova/\n   |                    |\n   |                    `-- servers.py\n   |\n   +-- plugins/\n          |\n          +-- services/\n                 |\n                 +-- base.py # base class, services factory\n                 |\n                 +-- identity.py (or `keystone.py\u0027) # merged with `keystone\u0027 wrapper\n                 |\n                 +-- network.py (or `neutron.py\u0027) # merged with `network\u0027 wrapper\n                 |\n                 +-- compute.py (or `nova.py\u0027)\n                 |\n                 `-- ...\n\n\n How this can be implemented:\n \u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\n\n rally.plugins.services.base\n ---------------------------\n\n class Service(object):\n    \"\"\"Some generic code here.\"\"\"\n    NAME \u003d None # Must be overrided\n    VERSION \u003d None # Must be overrided\n\n class ServiceFactory(object):\n    \"\"\"Initialize, setup and cache services instances.\"\"\"\n\n    def __init__(self,\n                clients\u003dNone, # Maybe use endpoint instead?\n                config\u003dNone):\n        \"\"\"Setup factory.\"\"\"\n\n    def get_service(self, name, version):\n        \"\"\"Service factory.\"\"\"\n\n\n rally.plugins.services.identity\n -------------------------------\n\n class KeystoneV2Service(base.Service):\n     \"\"\"Facade for keystone v2 client + specific logic.\"\"\"\n     NAME \u003d \"keystone\"\n     VERSION \u003d 2\n     ...\n\n\n class KeystoneV3Service(base.Service):\n     \"\"\"Facade for keystone v3 client + specific logic.\"\"\"\n     NAME \u003d \"keystone\"\n     VERSION \u003d 3\n     ...\n\n\n How this can be used:\n \u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\n\n rally.benchmark.scenarios.nova.servers\n --------------------------------------\n\n class NovaServers(object):\n     svc_factory \u003d services_base.ServiceFactory.get_service(self.clients)\n     nova_svc \u003d svc_factory.get_service(\"compute\", 2)\n     def boot_server(self, ...):\n        with base.AtomicAction(self, \"nova.boot_server\"):\n            nova_svc._boot_server(...)\n\n     # Imagine that we need keystone here:\n     keystone_svc \u003d svc_factory.get_service(\"identity\", 3)","commit_id":"9b8db0c7c3f619adcda2e501f944757d44ea560e"},{"author":{"_account_id":6172,"name":"Boris Pavlovic","email":"boris@pavlovic.me","username":"boris-42"},"change_message_id":"48b464e88e7aed6606e9bcf1957bcab2b96fa4e6","unresolved":false,"context_lines":[{"line_number":52,"context_line":""},{"line_number":53,"context_line":"    Example1(utils.ExampleScenario)"},{"line_number":54,"context_line":""},{"line_number":55,"context_line":"Suggested change:"},{"line_number":56,"context_line":""},{"line_number":57,"context_line":".. code-block:: shell"},{"line_number":58,"context_line":""}],"source_content_type":"text/x-rst","patch_set":5,"id":"9abe1de1_d4b80de8","line":55,"in_reply_to":"9abe1de1_f109e8de","updated":"2015-04-27 13:13:26.000000000","message":"Alex, \n\nYour solution is terrible ugly. I don\u0027t know any of patterns in development that will produce so many copy paste. In EACH benchmark scenario/context we will need to use atomic actions explicit which will double the size of our benchmark code and make it totally unreadable. \n\n\nYair, \n\nI agree with you atomic actions should be a part of service code. But what I think is that we can use AtomicActionMixin as a base of context/self and pass them to __init__ method of service. E.g: \n\n  ServiceManager(...., atomic_action_mgr\u003dself)\n\n\n\nAlex, \n\nPlease read my proposal. It\u0027s much simple to implement/user and don\u0027t require all this OOP with factories. \n\nWe are not in Java world and I don\u0027t want to see Java code in Rally.","commit_id":"9b8db0c7c3f619adcda2e501f944757d44ea560e"},{"author":{"_account_id":10475,"name":"Alexander Maretskiy","email":"amaretskiy@mirantis.com","username":"maretskiy"},"change_message_id":"25fe167f7e617438ca47a021e6f3fe6de8f50278","unresolved":false,"context_lines":[{"line_number":52,"context_line":""},{"line_number":53,"context_line":"    Example1(utils.ExampleScenario)"},{"line_number":54,"context_line":""},{"line_number":55,"context_line":"Suggested change:"},{"line_number":56,"context_line":""},{"line_number":57,"context_line":".. code-block:: shell"},{"line_number":58,"context_line":""}],"source_content_type":"text/x-rst","patch_set":5,"id":"9abe1de1_f109e8de","line":55,"in_reply_to":"bab921fb_50d57e19","updated":"2015-04-27 10:45:38.000000000","message":"IMO scenario is better place for atomic actions, since in different cases some action should be run:\n\n * with timing\n * without timing\n * with different timer name\n\nand these cases should be under scenario control, so there are 2 ways:\n\n 1) run atomic timers in scenarios (looks better for me)\n 2) run atomic timers somewhere else (in services),\n    but in this case actions signature should be extended\n    to give control on timers (enable/disable timer, change its name)","commit_id":"9b8db0c7c3f619adcda2e501f944757d44ea560e"},{"author":{"_account_id":8576,"name":"Yair Fried","email":"yfried@redhat.com","username":"yfried"},"change_message_id":"20942667617df33ad2b83c743c2c42eb5b53b77e","unresolved":false,"context_lines":[{"line_number":52,"context_line":""},{"line_number":53,"context_line":"    Example1(utils.ExampleScenario)"},{"line_number":54,"context_line":""},{"line_number":55,"context_line":"Suggested change:"},{"line_number":56,"context_line":""},{"line_number":57,"context_line":".. code-block:: shell"},{"line_number":58,"context_line":""}],"source_content_type":"text/x-rst","patch_set":5,"id":"bab921fb_50d57e19","line":55,"in_reply_to":"bab921fb_b54ac9aa","updated":"2015-04-26 08:40:27.000000000","message":"Atomic actions are already in scenario. Maybe you meant \"out of\" scenario?\n\nMy idea is that most atomic actions would be implemented inside Services (as the are now inside Utils) and not as part of scenario. That way, if you call nova_svc.boot_server from scenario or context, you\u0027d get the atomic action with it.","commit_id":"9b8db0c7c3f619adcda2e501f944757d44ea560e"},{"author":{"_account_id":6172,"name":"Boris Pavlovic","email":"boris@pavlovic.me","username":"boris-42"},"change_message_id":"3a9c64d8ec80f8672cec6bed85a51d16bbeb5939","unresolved":false,"context_lines":[{"line_number":60,"context_line":"    |-common.py"},{"line_number":61,"context_line":"    |-\u003cservice\u003e"},{"line_number":62,"context_line":"    |   |-\u003cservice\u003e.py"},{"line_number":63,"context_line":"    |-network.py"},{"line_number":64,"context_line":"    |-keystone"},{"line_number":65,"context_line":"        |-keystone.py"},{"line_number":66,"context_line":"        |-v2.py"}],"source_content_type":"text/x-rst","patch_set":5,"id":"5aa745d1_463468dd","line":63,"updated":"2015-04-15 20:11:52.000000000","message":"So something is strange with this diagram. \n\n\n  |-  os_services\n\n     # here we will store base stuff for os_services\n     |-  base.py    \n\n    # \u003cservice\u003e should be like compute, identity, network \n     |-  \u003cservice\u003e\n\n        # here is common service when we care to do things and now what API/service is used for that. Like keystone v2/v3, nova network/neutron. So we will implement here parts that can be done in both. \n        |-  common.py          \n\n        # here is api for working with specific API version / service Like keystone_v2/keystone_v3 or nova_network/neutron. This will be used in common.py \n        |- service_a.py\n\n        |- service_b.py","commit_id":"9b8db0c7c3f619adcda2e501f944757d44ea560e"},{"author":{"_account_id":8840,"name":"Carlos L. Torres","email":"carlos.torres@rackspace.com","username":"carl6796"},"change_message_id":"9e92e007cbbaec417f4be1eff40652660c36fc5e","unresolved":false,"context_lines":[{"line_number":66,"context_line":"        |-v2.py"},{"line_number":67,"context_line":"        |-v3.py"},{"line_number":68,"context_line":""},{"line_number":69,"context_line":"scenarios/example/utils.py"},{"line_number":70,"context_line":".. code-block:: python"},{"line_number":71,"context_line":""},{"line_number":72,"context_line":"    ExampleUtils(common.ServiceUtils)"}],"source_content_type":"text/x-rst","patch_set":5,"id":"5aa745d1_d1595490","line":69,"updated":"2015-04-15 20:36:17.000000000","message":"I think we should take the opportunity, to change the name \u0027utils\u0027 to something else.\n\nIn my mind, utils is file/directory/class/namespace that holds unrelated functions/files etc, that don\u0027t really belong somewhere else.\n\nBut in this case, it seems to me,  utils.py for each scenario, actually holds the basic actions (often just the atomic_actions) of a scenario.\n\nWhy not just call it \u0027actions.py\u0027, and have for example, ComputeActions, ImagesActions, etc\n\nWhat do you think @boris?","commit_id":"9b8db0c7c3f619adcda2e501f944757d44ea560e"},{"author":{"_account_id":8840,"name":"Carlos L. Torres","email":"carlos.torres@rackspace.com","username":"carl6796"},"change_message_id":"34cc3777700a28e45d66d2c0b3a88016123bf6d9","unresolved":false,"context_lines":[{"line_number":66,"context_line":"        |-v2.py"},{"line_number":67,"context_line":"        |-v3.py"},{"line_number":68,"context_line":""},{"line_number":69,"context_line":"scenarios/example/utils.py"},{"line_number":70,"context_line":".. code-block:: python"},{"line_number":71,"context_line":""},{"line_number":72,"context_line":"    ExampleUtils(common.ServiceUtils)"}],"source_content_type":"text/x-rst","patch_set":5,"id":"5aa745d1_976dfc34","line":69,"in_reply_to":"5aa745d1_d1595490","updated":"2015-04-15 21:53:26.000000000","message":"Another name could be operations.py, and \u003cService\u003eOperations","commit_id":"9b8db0c7c3f619adcda2e501f944757d44ea560e"},{"author":{"_account_id":6172,"name":"Boris Pavlovic","email":"boris@pavlovic.me","username":"boris-42"},"change_message_id":"3a9c64d8ec80f8672cec6bed85a51d16bbeb5939","unresolved":false,"context_lines":[{"line_number":67,"context_line":"        |-v3.py"},{"line_number":68,"context_line":""},{"line_number":69,"context_line":"scenarios/example/utils.py"},{"line_number":70,"context_line":".. code-block:: python"},{"line_number":71,"context_line":""},{"line_number":72,"context_line":"    ExampleUtils(common.ServiceUtils)"},{"line_number":73,"context_line":""}],"source_content_type":"text/x-rst","patch_set":5,"id":"5aa745d1_c6fd1870","line":70,"updated":"2015-04-15 20:11:52.000000000","message":"I don\u0027t understand these samples. Please write more real life samples. At least interfaces + implementation where it is important. \n\nFor example, \n\n\n  ### in rally/os_services/keystone/common.py\n\n  How it will look like\n\n\n  ### in rally/benchmark/context/users.py \n\n  from rally.benchmark.context import base \n\n  context SingleUser(base.Context):\n   \n     def create(): \n\n        #how we are going to implement this using os_service \n\n     def cleanup()\n\n\n\n   ### in rally/benchamrk/scenario/keystone/keystone.py: \n  \n   from rally.benchmark.scenarios import base \n\n   class KeystoneScenario(base.Scenario):\n\n      def users_create_and_delete(self):\n          # How we are going to implement this using os_services","commit_id":"9b8db0c7c3f619adcda2e501f944757d44ea560e"},{"author":{"_account_id":6172,"name":"Boris Pavlovic","email":"boris@pavlovic.me","username":"boris-42"},"change_message_id":"3a9c64d8ec80f8672cec6bed85a51d16bbeb5939","unresolved":false,"context_lines":[{"line_number":75,"context_line":"scenarios/base.py"},{"line_number":76,"context_line":".. code-block:: python"},{"line_number":77,"context_line":""},{"line_number":78,"context_line":"    class ServiceUtils():"},{"line_number":79,"context_line":"        \"\"\"A Class to group all scenario\u0027s utils. \"\"\""},{"line_number":80,"context_line":""},{"line_number":81,"context_line":""}],"source_content_type":"text/x-rst","patch_set":5,"id":"5aa745d1_46aa281b","line":78,"updated":"2015-04-15 20:11:52.000000000","message":"Not sure what this is...","commit_id":"9b8db0c7c3f619adcda2e501f944757d44ea560e"},{"author":{"_account_id":6172,"name":"Boris Pavlovic","email":"boris@pavlovic.me","username":"boris-42"},"change_message_id":"3a9c64d8ec80f8672cec6bed85a51d16bbeb5939","unresolved":false,"context_lines":[{"line_number":85,"context_line":""},{"line_number":86,"context_line":"    Example1(base.Scenario)"},{"line_number":87,"context_line":""},{"line_number":88,"context_line":"      def __init__(self):"},{"line_number":89,"context_line":"          utils \u003d base.ServiceUtils(ExampleUtils, NeutronUtils, NovaUtils)"},{"line_number":90,"context_line":""},{"line_number":91,"context_line":"    ..."}],"source_content_type":"text/x-rst","patch_set":5,"id":"5aa745d1_d1c954ae","line":88,"updated":"2015-04-15 20:11:52.000000000","message":"So I don\u0027t see any benefit of simplicity here. What if we make explicit way simple and clean. \n\nSomething like, \n\n   from rally import os_services\n\n    services \u003d os_services(self, clients)  \n    # self is passed to support atomic actions\n    # clients is instance of osclients.Clients \n\n    server \u003d services.nova(\"common/v1/v2\").boot_server()\n    services.network(\"common\").attach_floating_ip(server)\n    services.nova(\"common\").delete_server(server)","commit_id":"9b8db0c7c3f619adcda2e501f944757d44ea560e"},{"author":{"_account_id":8840,"name":"Carlos L. Torres","email":"carlos.torres@rackspace.com","username":"carl6796"},"change_message_id":"9e92e007cbbaec417f4be1eff40652660c36fc5e","unresolved":false,"context_lines":[{"line_number":93,"context_line":""},{"line_number":94,"context_line":"          self.utils.nova.boot_server()"},{"line_number":95,"context_line":""},{"line_number":96,"context_line":"          self.utils.example.do_whatever()"},{"line_number":97,"context_line":""},{"line_number":98,"context_line":"Assignee(s)"},{"line_number":99,"context_line":"-----------"}],"source_content_type":"text/x-rst","patch_set":5,"id":"5aa745d1_b116c853","line":96,"updated":"2015-04-15 20:36:17.000000000","message":"I don\u0027t see how API versioning is handled, will it be a configuration for the scenario?","commit_id":"9b8db0c7c3f619adcda2e501f944757d44ea560e"},{"author":{"_account_id":6172,"name":"Boris Pavlovic","email":"boris@pavlovic.me","username":"boris-42"},"change_message_id":"98c8e3fd5e38477cdb14f1924b36cd7d06bb8281","unresolved":false,"context_lines":[{"line_number":93,"context_line":""},{"line_number":94,"context_line":"          self.utils.nova.boot_server()"},{"line_number":95,"context_line":""},{"line_number":96,"context_line":"          self.utils.example.do_whatever()"},{"line_number":97,"context_line":""},{"line_number":98,"context_line":"Assignee(s)"},{"line_number":99,"context_line":"-----------"}],"source_content_type":"text/x-rst","patch_set":5,"id":"5aa745d1_6c6f4393","line":96,"in_reply_to":"5aa745d1_b116c853","updated":"2015-04-15 20:41:09.000000000","message":"Take a look at my comments as well\u003d)","commit_id":"9b8db0c7c3f619adcda2e501f944757d44ea560e"},{"author":{"_account_id":8576,"name":"Yair Fried","email":"yfried@redhat.com","username":"yfried"},"change_message_id":"20942667617df33ad2b83c743c2c42eb5b53b77e","unresolved":false,"context_lines":[{"line_number":93,"context_line":""},{"line_number":94,"context_line":"          self.utils.nova.boot_server()"},{"line_number":95,"context_line":""},{"line_number":96,"context_line":"          self.utils.example.do_whatever()"},{"line_number":97,"context_line":""},{"line_number":98,"context_line":"Assignee(s)"},{"line_number":99,"context_line":"-----------"}],"source_content_type":"text/x-rst","patch_set":5,"id":"bab921fb_3019ead7","line":96,"in_reply_to":"5aa745d1_b116c853","updated":"2015-04-26 08:40:27.000000000","message":"This shouldn\u0027t introduce any API change.","commit_id":"9b8db0c7c3f619adcda2e501f944757d44ea560e"},{"author":{"_account_id":10475,"name":"Alexander Maretskiy","email":"amaretskiy@mirantis.com","username":"maretskiy"},"change_message_id":"3cc50494d14a83d3dd6cfc0734a7ff1a0fa6e6df","unresolved":false,"context_lines":[{"line_number":7,"context_line":""},{"line_number":8,"context_line":"\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d"},{"line_number":9,"context_line":" Refactor scenarios\u0027 utils into central os-services tree"},{"line_number":10,"context_line":"\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d"},{"line_number":11,"context_line":""},{"line_number":12,"context_line":"It\u0027s hard to reuse code from different scenario utils in areas like context."},{"line_number":13,"context_line":""}],"source_content_type":"text/x-rst","patch_set":9,"id":"5ad0253b_0ead3be9","line":10,"updated":"2015-04-29 12:34:07.000000000","message":"RestructuredText requires lines `\u003d\u003d\u003d...\u003d\u003d\u003d\u0027 lenght equal or larger than the length of wrapped string\n\n \u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\n  Refactor scenarios\u0027 utils into central os-services tree\n \u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\n                                                        ^","commit_id":"6754822735f417dcd8da1e8699d8176ef466ef7e"},{"author":{"_account_id":10475,"name":"Alexander Maretskiy","email":"amaretskiy@mirantis.com","username":"maretskiy"},"change_message_id":"3cc50494d14a83d3dd6cfc0734a7ff1a0fa6e6df","unresolved":false,"context_lines":[{"line_number":61,"context_line":"                  |"},{"line_number":62,"context_line":"                  `-- network.py"},{"line_number":63,"context_line":""},{"line_number":64,"context_line":"scenarios/neutron/utils.pyscenarios/neutron/utils.py"},{"line_number":65,"context_line":""},{"line_number":66,"context_line":".. code-block:: python"},{"line_number":67,"context_line":""}],"source_content_type":"text/x-rst","patch_set":9,"id":"5ad0253b_8e870b61","line":64,"updated":"2015-04-29 12:34:07.000000000","message":"I guess this line (and others below) is a result of double-paste","commit_id":"6754822735f417dcd8da1e8699d8176ef466ef7e"},{"author":{"_account_id":8576,"name":"Yair Fried","email":"yfried@redhat.com","username":"yfried"},"change_message_id":"7aece2a09da4fec11e3e6fd5dcc3c754b3d0f2d5","unresolved":false,"context_lines":[{"line_number":61,"context_line":"                  |"},{"line_number":62,"context_line":"                  `-- network.py"},{"line_number":63,"context_line":""},{"line_number":64,"context_line":"scenarios/neutron/utils.pyscenarios/neutron/utils.py"},{"line_number":65,"context_line":""},{"line_number":66,"context_line":".. code-block:: python"},{"line_number":67,"context_line":""}],"source_content_type":"text/x-rst","patch_set":9,"id":"3acd31a7_0973bd4e","line":64,"in_reply_to":"5ad0253b_8e870b61","updated":"2015-05-03 12:27:44.000000000","message":"Done","commit_id":"6754822735f417dcd8da1e8699d8176ef466ef7e"},{"author":{"_account_id":10475,"name":"Alexander Maretskiy","email":"amaretskiy@mirantis.com","username":"maretskiy"},"change_message_id":"3cc50494d14a83d3dd6cfc0734a7ff1a0fa6e6df","unresolved":false,"context_lines":[{"line_number":138,"context_line":"    ServiceManager(Plugin):"},{"line_number":139,"context_line":"        def __init__(self,...., atomic_action_mgr\u003dNone):"},{"line_number":140,"context_line":"            atomic_action_mgr \u003d atomic_action_mgr or self"},{"line_number":141,"context_line":""},{"line_number":142,"context_line":"os_service/network/common.pyscenarios/neutron/utils.py"},{"line_number":143,"context_line":""},{"line_number":144,"context_line":".. code-block:: python"}],"source_content_type":"text/x-rst","patch_set":9,"id":"5ad0253b_4e81f349","line":141,"updated":"2015-04-29 12:34:07.000000000","message":"ServiceManager looks good, but, I think, we have to describe here how this manager will:\n\n * spawn services\n * manage versions\n\nProbably some factory method should be added here, with examples","commit_id":"6754822735f417dcd8da1e8699d8176ef466ef7e"},{"author":{"_account_id":8576,"name":"Yair Fried","email":"yfried@redhat.com","username":"yfried"},"change_message_id":"7aece2a09da4fec11e3e6fd5dcc3c754b3d0f2d5","unresolved":false,"context_lines":[{"line_number":138,"context_line":"    ServiceManager(Plugin):"},{"line_number":139,"context_line":"        def __init__(self,...., atomic_action_mgr\u003dNone):"},{"line_number":140,"context_line":"            atomic_action_mgr \u003d atomic_action_mgr or self"},{"line_number":141,"context_line":""},{"line_number":142,"context_line":"os_service/network/common.pyscenarios/neutron/utils.py"},{"line_number":143,"context_line":""},{"line_number":144,"context_line":".. code-block:: python"}],"source_content_type":"text/x-rst","patch_set":9,"id":"3acd31a7_69d35105","line":141,"in_reply_to":"5ad0253b_4e81f349","updated":"2015-05-03 12:27:44.000000000","message":"not sure","commit_id":"6754822735f417dcd8da1e8699d8176ef466ef7e"},{"author":{"_account_id":6172,"name":"Boris Pavlovic","email":"boris@pavlovic.me","username":"boris-42"},"change_message_id":"296eefcd0e996c9a9e75432a155456ea889e5423","unresolved":false,"context_lines":[{"line_number":19,"context_line":"to reuse outside the scenario directory (ie, different scenarios and areas"},{"line_number":20,"context_line":"like context), which calls for code duplications and strange solutions like"},{"line_number":21,"context_line":"wrappers."},{"line_number":22,"context_line":"As well it is hard to do versions of such stuff."},{"line_number":23,"context_line":""},{"line_number":24,"context_line":"Proposed change"},{"line_number":25,"context_line":"\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d"}],"source_content_type":"text/x-rst","patch_set":10,"id":"3acd31a7_a9104902","line":22,"updated":"2015-05-03 11:57:29.000000000","message":"As well it is impossible to do versioning of  current utils which makes them absolutely non-reusable as a base for out of tree plugins.","commit_id":"6e49c0051c6b8756fe54fe9c61ad65a78723edf6"},{"author":{"_account_id":8576,"name":"Yair Fried","email":"yfried@redhat.com","username":"yfried"},"change_message_id":"3f45b4fa06a431923e09439c177a5ff3f55a244a","unresolved":false,"context_lines":[{"line_number":19,"context_line":"to reuse outside the scenario directory (ie, different scenarios and areas"},{"line_number":20,"context_line":"like context), which calls for code duplications and strange solutions like"},{"line_number":21,"context_line":"wrappers."},{"line_number":22,"context_line":"As well it is hard to do versions of such stuff."},{"line_number":23,"context_line":""},{"line_number":24,"context_line":"Proposed change"},{"line_number":25,"context_line":"\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d"}],"source_content_type":"text/x-rst","patch_set":10,"id":"3acd31a7_c993854e","line":22,"in_reply_to":"3acd31a7_a9104902","updated":"2015-05-03 12:27:49.000000000","message":"Done","commit_id":"6e49c0051c6b8756fe54fe9c61ad65a78723edf6"},{"author":{"_account_id":6172,"name":"Boris Pavlovic","email":"boris@pavlovic.me","username":"boris-42"},"change_message_id":"296eefcd0e996c9a9e75432a155456ea889e5423","unresolved":false,"context_lines":[{"line_number":61,"context_line":"                  |"},{"line_number":62,"context_line":"                  `-- network.py"},{"line_number":63,"context_line":""},{"line_number":64,"context_line":"scenarios/neutron/utils.pyscenarios/neutron/utils.py"},{"line_number":65,"context_line":""},{"line_number":66,"context_line":".. code-block:: python"},{"line_number":67,"context_line":""}],"source_content_type":"text/x-rst","patch_set":10,"id":"3acd31a7_49f655d8","line":64,"updated":"2015-05-03 11:57:29.000000000","message":"seems like copy paste bug it should be \n\nscenarios/neutron/utils.py\n\n...\n\nscenarios/neutron/utils.py","commit_id":"6e49c0051c6b8756fe54fe9c61ad65a78723edf6"},{"author":{"_account_id":8576,"name":"Yair Fried","email":"yfried@redhat.com","username":"yfried"},"change_message_id":"3f45b4fa06a431923e09439c177a5ff3f55a244a","unresolved":false,"context_lines":[{"line_number":61,"context_line":"                  |"},{"line_number":62,"context_line":"                  `-- network.py"},{"line_number":63,"context_line":""},{"line_number":64,"context_line":"scenarios/neutron/utils.pyscenarios/neutron/utils.py"},{"line_number":65,"context_line":""},{"line_number":66,"context_line":".. code-block:: python"},{"line_number":67,"context_line":""}],"source_content_type":"text/x-rst","patch_set":10,"id":"3acd31a7_e9908145","line":64,"in_reply_to":"3acd31a7_49f655d8","updated":"2015-05-03 12:27:49.000000000","message":"Done","commit_id":"6e49c0051c6b8756fe54fe9c61ad65a78723edf6"},{"author":{"_account_id":6172,"name":"Boris Pavlovic","email":"boris@pavlovic.me","username":"boris-42"},"change_message_id":"296eefcd0e996c9a9e75432a155456ea889e5423","unresolved":false,"context_lines":[{"line_number":63,"context_line":""},{"line_number":64,"context_line":"scenarios/neutron/utils.pyscenarios/neutron/utils.py"},{"line_number":65,"context_line":""},{"line_number":66,"context_line":".. code-block:: python"},{"line_number":67,"context_line":""},{"line_number":68,"context_line":""},{"line_number":69,"context_line":"    NeutronScenario(base.Scenario):"}],"source_content_type":"text/x-rst","patch_set":10,"id":"3acd31a7_290559bb","line":66,"updated":"2015-05-03 11:57:29.000000000","message":"put some code or remove this at all","commit_id":"6e49c0051c6b8756fe54fe9c61ad65a78723edf6"},{"author":{"_account_id":8576,"name":"Yair Fried","email":"yfried@redhat.com","username":"yfried"},"change_message_id":"3f45b4fa06a431923e09439c177a5ff3f55a244a","unresolved":false,"context_lines":[{"line_number":63,"context_line":""},{"line_number":64,"context_line":"scenarios/neutron/utils.pyscenarios/neutron/utils.py"},{"line_number":65,"context_line":""},{"line_number":66,"context_line":".. code-block:: python"},{"line_number":67,"context_line":""},{"line_number":68,"context_line":""},{"line_number":69,"context_line":"    NeutronScenario(base.Scenario):"}],"source_content_type":"text/x-rst","patch_set":10,"id":"3acd31a7_a99a8961","line":66,"in_reply_to":"3acd31a7_290559bb","updated":"2015-05-03 12:27:49.000000000","message":"this makes inheritance clear","commit_id":"6e49c0051c6b8756fe54fe9c61ad65a78723edf6"},{"author":{"_account_id":6172,"name":"Boris Pavlovic","email":"boris@pavlovic.me","username":"boris-42"},"change_message_id":"296eefcd0e996c9a9e75432a155456ea889e5423","unresolved":false,"context_lines":[{"line_number":84,"context_line":"   |"},{"line_number":85,"context_line":"   +-- plugins/"},{"line_number":86,"context_line":"           |"},{"line_number":87,"context_line":"           +-- context/"},{"line_number":88,"context_line":"           +-- runners/"},{"line_number":89,"context_line":"           +-- sla/"},{"line_number":90,"context_line":"           |"}],"source_content_type":"text/x-rst","patch_set":10,"id":"3acd31a7_e92d2147","line":87,"updated":"2015-05-03 11:57:29.000000000","message":"we can remove context/runners/sla/scenarios becuase they doesn\u0027t matter here.\n\nand put human readable note why we are putting os_services in such strange place","commit_id":"6e49c0051c6b8756fe54fe9c61ad65a78723edf6"},{"author":{"_account_id":6172,"name":"Boris Pavlovic","email":"boris@pavlovic.me","username":"boris-42"},"change_message_id":"296eefcd0e996c9a9e75432a155456ea889e5423","unresolved":false,"context_lines":[{"line_number":100,"context_line":"           |      +-- authenticate/"},{"line_number":101,"context_line":"           |"},{"line_number":102,"context_line":"           `-- os_services/"},{"line_number":103,"context_line":"                  |  # Here we will store base stuff for os_services."},{"line_number":104,"context_line":"                  +-- base.py"},{"line_number":105,"context_line":"                  |"},{"line_number":106,"context_line":"                  +-- compute/"}],"source_content_type":"text/x-rst","patch_set":10,"id":"3acd31a7_e9d40121","line":103,"updated":"2015-05-03 11:57:29.000000000","message":"base code for os_service. \n\nI believe we should put here some samples e.g.:  \n\nwait_for, wait_for_delete and so on should go here.","commit_id":"6e49c0051c6b8756fe54fe9c61ad65a78723edf6"},{"author":{"_account_id":8576,"name":"Yair Fried","email":"yfried@redhat.com","username":"yfried"},"change_message_id":"3f45b4fa06a431923e09439c177a5ff3f55a244a","unresolved":false,"context_lines":[{"line_number":100,"context_line":"           |      +-- authenticate/"},{"line_number":101,"context_line":"           |"},{"line_number":102,"context_line":"           `-- os_services/"},{"line_number":103,"context_line":"                  |  # Here we will store base stuff for os_services."},{"line_number":104,"context_line":"                  +-- base.py"},{"line_number":105,"context_line":"                  |"},{"line_number":106,"context_line":"                  +-- compute/"}],"source_content_type":"text/x-rst","patch_set":10,"id":"3acd31a7_49c77545","line":103,"in_reply_to":"3acd31a7_e9d40121","updated":"2015-05-03 12:27:49.000000000","message":"Done","commit_id":"6e49c0051c6b8756fe54fe9c61ad65a78723edf6"},{"author":{"_account_id":6172,"name":"Boris Pavlovic","email":"boris@pavlovic.me","username":"boris-42"},"change_message_id":"296eefcd0e996c9a9e75432a155456ea889e5423","unresolved":false,"context_lines":[{"line_number":116,"context_line":"                  |     +-- neutron.py"},{"line_number":117,"context_line":"                  +-- identity/"},{"line_number":118,"context_line":"                  |     | # Here is common service when we care to do things"},{"line_number":119,"context_line":"                  |     | # and regardless of which API/service is used for"},{"line_number":120,"context_line":"                  |     | # that. So we will implement here parts that can be"},{"line_number":121,"context_line":"                  |     | # done in both."},{"line_number":122,"context_line":"                  |     +-- common.py"}],"source_content_type":"text/x-rst","patch_set":10,"id":"3acd31a7_89e10d01","line":119,"updated":"2015-05-03 11:57:29.000000000","message":"Could you change the order of identity and network and probably repeat this comment for netowrk part","commit_id":"6e49c0051c6b8756fe54fe9c61ad65a78723edf6"},{"author":{"_account_id":8576,"name":"Yair Fried","email":"yfried@redhat.com","username":"yfried"},"change_message_id":"3f45b4fa06a431923e09439c177a5ff3f55a244a","unresolved":false,"context_lines":[{"line_number":116,"context_line":"                  |     +-- neutron.py"},{"line_number":117,"context_line":"                  +-- identity/"},{"line_number":118,"context_line":"                  |     | # Here is common service when we care to do things"},{"line_number":119,"context_line":"                  |     | # and regardless of which API/service is used for"},{"line_number":120,"context_line":"                  |     | # that. So we will implement here parts that can be"},{"line_number":121,"context_line":"                  |     | # done in both."},{"line_number":122,"context_line":"                  |     +-- common.py"}],"source_content_type":"text/x-rst","patch_set":10,"id":"3acd31a7_29c67948","line":119,"in_reply_to":"3acd31a7_89e10d01","updated":"2015-05-03 12:27:49.000000000","message":"Done","commit_id":"6e49c0051c6b8756fe54fe9c61ad65a78723edf6"},{"author":{"_account_id":6172,"name":"Boris Pavlovic","email":"boris@pavlovic.me","username":"boris-42"},"change_message_id":"296eefcd0e996c9a9e75432a155456ea889e5423","unresolved":false,"context_lines":[{"line_number":137,"context_line":""},{"line_number":138,"context_line":"    ServiceManager(Plugin):"},{"line_number":139,"context_line":"        def __init__(self,...., atomic_action_mgr\u003dNone):"},{"line_number":140,"context_line":"            atomic_action_mgr \u003d atomic_action_mgr or self"},{"line_number":141,"context_line":""},{"line_number":142,"context_line":"os_service/network/common.pyscenarios/neutron/utils.py"},{"line_number":143,"context_line":""}],"source_content_type":"text/x-rst","patch_set":10,"id":"3acd31a7_09ee1dec","line":140,"updated":"2015-05-03 11:57:29.000000000","message":"So basically we are expecting that ServiceManager will inherit code that implmenets atomic action stuff?","commit_id":"6e49c0051c6b8756fe54fe9c61ad65a78723edf6"},{"author":{"_account_id":8576,"name":"Yair Fried","email":"yfried@redhat.com","username":"yfried"},"change_message_id":"3f45b4fa06a431923e09439c177a5ff3f55a244a","unresolved":false,"context_lines":[{"line_number":137,"context_line":""},{"line_number":138,"context_line":"    ServiceManager(Plugin):"},{"line_number":139,"context_line":"        def __init__(self,...., atomic_action_mgr\u003dNone):"},{"line_number":140,"context_line":"            atomic_action_mgr \u003d atomic_action_mgr or self"},{"line_number":141,"context_line":""},{"line_number":142,"context_line":"os_service/network/common.pyscenarios/neutron/utils.py"},{"line_number":143,"context_line":""}],"source_content_type":"text/x-rst","patch_set":10,"id":"3acd31a7_a9e849b5","line":140,"in_reply_to":"3acd31a7_09ee1dec","updated":"2015-05-03 12:27:49.000000000","message":"I think so.","commit_id":"6e49c0051c6b8756fe54fe9c61ad65a78723edf6"},{"author":{"_account_id":6172,"name":"Boris Pavlovic","email":"boris@pavlovic.me","username":"boris-42"},"change_message_id":"296eefcd0e996c9a9e75432a155456ea889e5423","unresolved":false,"context_lines":[{"line_number":139,"context_line":"        def __init__(self,...., atomic_action_mgr\u003dNone):"},{"line_number":140,"context_line":"            atomic_action_mgr \u003d atomic_action_mgr or self"},{"line_number":141,"context_line":""},{"line_number":142,"context_line":"os_service/network/common.pyscenarios/neutron/utils.py"},{"line_number":143,"context_line":""},{"line_number":144,"context_line":".. code-block:: python"},{"line_number":145,"context_line":""}],"source_content_type":"text/x-rst","patch_set":10,"id":"3acd31a7_e9bbe1e3","line":142,"updated":"2015-05-03 11:57:29.000000000","message":"some strange path seems like 2 joined","commit_id":"6e49c0051c6b8756fe54fe9c61ad65a78723edf6"},{"author":{"_account_id":8576,"name":"Yair Fried","email":"yfried@redhat.com","username":"yfried"},"change_message_id":"3f45b4fa06a431923e09439c177a5ff3f55a244a","unresolved":false,"context_lines":[{"line_number":139,"context_line":"        def __init__(self,...., atomic_action_mgr\u003dNone):"},{"line_number":140,"context_line":"            atomic_action_mgr \u003d atomic_action_mgr or self"},{"line_number":141,"context_line":""},{"line_number":142,"context_line":"os_service/network/common.pyscenarios/neutron/utils.py"},{"line_number":143,"context_line":""},{"line_number":144,"context_line":".. code-block:: python"},{"line_number":145,"context_line":""}],"source_content_type":"text/x-rst","patch_set":10,"id":"3acd31a7_89eb4db0","line":142,"in_reply_to":"3acd31a7_e9bbe1e3","updated":"2015-05-03 12:27:49.000000000","message":"Done","commit_id":"6e49c0051c6b8756fe54fe9c61ad65a78723edf6"},{"author":{"_account_id":6172,"name":"Boris Pavlovic","email":"boris@pavlovic.me","username":"boris-42"},"change_message_id":"296eefcd0e996c9a9e75432a155456ea889e5423","unresolved":false,"context_lines":[{"line_number":145,"context_line":""},{"line_number":146,"context_line":""},{"line_number":147,"context_line":"    NetworkService(ServiceManager):"},{"line_number":148,"context_line":"    # code from NetworkWrapper."},{"line_number":149,"context_line":""},{"line_number":150,"context_line":"os_service/network/neutron.pyscenarios/neutron/utils.py"},{"line_number":151,"context_line":""}],"source_content_type":"text/x-rst","patch_set":10,"id":"3acd31a7_c9bee5d3","line":148,"updated":"2015-05-03 11:57:29.000000000","message":"please add real piece of code otherwise it is abosolutelly unclear what you are going to put here..","commit_id":"6e49c0051c6b8756fe54fe9c61ad65a78723edf6"},{"author":{"_account_id":12395,"name":"Roman Vasylets","email":"pomeo92@gmail.com","username":"rvasilets"},"change_message_id":"3cc02da1b03ff1a73b78fbc8b530f25e0875cab6","unresolved":false,"context_lines":[{"line_number":1,"context_line":".."},{"line_number":2,"context_line":" This work is licensed under a Creative Commons Attribution 3.0 Unported"},{"line_number":3,"context_line":" License."},{"line_number":4,"context_line":""}],"source_content_type":"text/x-rst","patch_set":16,"id":"7a016987_f432445d","line":1,"updated":"2015-05-20 14:23:59.000000000","message":"https://github.com/openstack/rally/blob/master/rally/benchmark/scenarios/vm/vmtasks.py How we would handle situation for scenario as above where we use 3 types of utils and thinking about future structure... Do I need to import plugins for cinder, nova, vm utils just to use scenario vmtask? If so its not comfortable and it would be not plugin scenario.","commit_id":"c9f87a312be7ea018a83a9577cd9e208cf2fb382"},{"author":{"_account_id":8576,"name":"Yair Fried","email":"yfried@redhat.com","username":"yfried"},"change_message_id":"4759a45e943371609c6a530e29ade42fdb105768","unresolved":false,"context_lines":[{"line_number":1,"context_line":".."},{"line_number":2,"context_line":" This work is licensed under a Creative Commons Attribution 3.0 Unported"},{"line_number":3,"context_line":" License."},{"line_number":4,"context_line":""}],"source_content_type":"text/x-rst","patch_set":16,"id":"7a2fa921_1676bf05","line":1,"in_reply_to":"7a016987_f432445d","updated":"2015-10-11 07:28:14.000000000","message":"Done","commit_id":"c9f87a312be7ea018a83a9577cd9e208cf2fb382"},{"author":{"_account_id":10475,"name":"Alexander Maretskiy","email":"amaretskiy@mirantis.com","username":"maretskiy"},"change_message_id":"59639c1f0b53eef058e9d41905475571163da3fb","unresolved":false,"context_lines":[{"line_number":17,"context_line":""},{"line_number":18,"context_line":"Code that wraps openstack services from different scenario utils is difficult"},{"line_number":19,"context_line":"to reuse outside the scenario directory (ie, different scenarios and areas"},{"line_number":20,"context_line":"like context), which calls for code duplications and strange solutions like"},{"line_number":21,"context_line":"wrappers."},{"line_number":22,"context_line":"As well it is impossible to do versioning of current utils which makes them"},{"line_number":23,"context_line":"absolutely non-reusable as a base for out of tree plugins."}],"source_content_type":"text/x-rst","patch_set":16,"id":"7a016987_2d003c01","line":20,"updated":"2015-05-25 10:44:11.000000000","message":"s/calls for/cause/","commit_id":"c9f87a312be7ea018a83a9577cd9e208cf2fb382"},{"author":{"_account_id":10475,"name":"Alexander Maretskiy","email":"amaretskiy@mirantis.com","username":"maretskiy"},"change_message_id":"59639c1f0b53eef058e9d41905475571163da3fb","unresolved":false,"context_lines":[{"line_number":40,"context_line":""},{"line_number":41,"context_line":"current tree:"},{"line_number":42,"context_line":""},{"line_number":43,"context_line":".. code-block:: shell"},{"line_number":44,"context_line":""},{"line_number":45,"context_line":"  rally/"},{"line_number":46,"context_line":"   |"}],"source_content_type":"text/x-rst","patch_set":16,"id":"7a016987_906bc7b6","line":43,"updated":"2015-05-25 10:44:11.000000000","message":"This is not shell code. Just use empty value: `.. code-block::\u0027","commit_id":"c9f87a312be7ea018a83a9577cd9e208cf2fb382"},{"author":{"_account_id":8576,"name":"Yair Fried","email":"yfried@redhat.com","username":"yfried"},"change_message_id":"4759a45e943371609c6a530e29ade42fdb105768","unresolved":false,"context_lines":[{"line_number":40,"context_line":""},{"line_number":41,"context_line":"current tree:"},{"line_number":42,"context_line":""},{"line_number":43,"context_line":".. code-block:: shell"},{"line_number":44,"context_line":""},{"line_number":45,"context_line":"  rally/"},{"line_number":46,"context_line":"   |"}],"source_content_type":"text/x-rst","patch_set":16,"id":"7a2fa921_d6be0764","line":43,"in_reply_to":"7a016987_906bc7b6","updated":"2015-10-11 07:28:14.000000000","message":"Done","commit_id":"c9f87a312be7ea018a83a9577cd9e208cf2fb382"},{"author":{"_account_id":10475,"name":"Alexander Maretskiy","email":"amaretskiy@mirantis.com","username":"maretskiy"},"change_message_id":"59639c1f0b53eef058e9d41905475571163da3fb","unresolved":false,"context_lines":[{"line_number":78,"context_line":""},{"line_number":79,"context_line":"Suggested change:"},{"line_number":80,"context_line":""},{"line_number":81,"context_line":".. code-block:: shell"},{"line_number":82,"context_line":""},{"line_number":83,"context_line":""},{"line_number":84,"context_line":"  rally/"}],"source_content_type":"text/x-rst","patch_set":16,"id":"7a016987_305c1318","line":81,"updated":"2015-05-25 10:44:11.000000000","message":"Remove `shell\u0027","commit_id":"c9f87a312be7ea018a83a9577cd9e208cf2fb382"},{"author":{"_account_id":8576,"name":"Yair Fried","email":"yfried@redhat.com","username":"yfried"},"change_message_id":"4759a45e943371609c6a530e29ade42fdb105768","unresolved":false,"context_lines":[{"line_number":78,"context_line":""},{"line_number":79,"context_line":"Suggested change:"},{"line_number":80,"context_line":""},{"line_number":81,"context_line":".. code-block:: shell"},{"line_number":82,"context_line":""},{"line_number":83,"context_line":""},{"line_number":84,"context_line":"  rally/"}],"source_content_type":"text/x-rst","patch_set":16,"id":"7a2fa921_f6c1c3e4","line":81,"in_reply_to":"7a016987_305c1318","updated":"2015-10-11 07:28:14.000000000","message":"Done","commit_id":"c9f87a312be7ea018a83a9577cd9e208cf2fb382"},{"author":{"_account_id":10475,"name":"Alexander Maretskiy","email":"amaretskiy@mirantis.com","username":"maretskiy"},"change_message_id":"59639c1f0b53eef058e9d41905475571163da3fb","unresolved":false,"context_lines":[{"line_number":86,"context_line":"   +-- plugins/"},{"line_number":87,"context_line":"           |"},{"line_number":88,"context_line":"           |"},{"line_number":89,"context_line":"           +-- scenarios/"},{"line_number":90,"context_line":"           |      |"},{"line_number":91,"context_line":"           |      +-- nova/"},{"line_number":92,"context_line":"           |      |     |"}],"source_content_type":"text/x-rst","patch_set":16,"id":"7a016987_103a3799","line":89,"updated":"2015-05-25 10:44:11.000000000","message":"`openstack/scenarios\u0027 - we already have this module","commit_id":"c9f87a312be7ea018a83a9577cd9e208cf2fb382"},{"author":{"_account_id":10475,"name":"Alexander Maretskiy","email":"amaretskiy@mirantis.com","username":"maretskiy"},"change_message_id":"59639c1f0b53eef058e9d41905475571163da3fb","unresolved":false,"context_lines":[{"line_number":97,"context_line":"           |      +-- neutron/"},{"line_number":98,"context_line":"           |      +-- authenticate/"},{"line_number":99,"context_line":"           |"},{"line_number":100,"context_line":"           `-- os_services/"},{"line_number":101,"context_line":"                  |  # Here we will store base code for os_services."},{"line_number":102,"context_line":"                  |  # like waif_for, and wait_for_delete"},{"line_number":103,"context_line":"                  +-- base.py"}],"source_content_type":"text/x-rst","patch_set":16,"id":"7a016987_f0d55b42","line":100,"updated":"2015-05-25 10:44:11.000000000","message":"Maybe `openstack/services/\u0027, since we already have module rally/plugins/openstack","commit_id":"c9f87a312be7ea018a83a9577cd9e208cf2fb382"},{"author":{"_account_id":8576,"name":"Yair Fried","email":"yfried@redhat.com","username":"yfried"},"change_message_id":"4759a45e943371609c6a530e29ade42fdb105768","unresolved":false,"context_lines":[{"line_number":97,"context_line":"           |      +-- neutron/"},{"line_number":98,"context_line":"           |      +-- authenticate/"},{"line_number":99,"context_line":"           |"},{"line_number":100,"context_line":"           `-- os_services/"},{"line_number":101,"context_line":"                  |  # Here we will store base code for os_services."},{"line_number":102,"context_line":"                  |  # like waif_for, and wait_for_delete"},{"line_number":103,"context_line":"                  +-- base.py"}],"source_content_type":"text/x-rst","patch_set":16,"id":"7a2fa921_96108f5a","line":100,"in_reply_to":"7a016987_f0d55b42","updated":"2015-10-11 07:28:14.000000000","message":"Done","commit_id":"c9f87a312be7ea018a83a9577cd9e208cf2fb382"},{"author":{"_account_id":10475,"name":"Alexander Maretskiy","email":"amaretskiy@mirantis.com","username":"maretskiy"},"change_message_id":"59639c1f0b53eef058e9d41905475571163da3fb","unresolved":false,"context_lines":[{"line_number":116,"context_line":"                  |     | # version/service Like keystone_v2/keystone_v3 or"},{"line_number":117,"context_line":"                  |     | # nova_network/neutron. This will be used in"},{"line_number":118,"context_line":"                  |     | # common.py for implementation."},{"line_number":119,"context_line":"                  |     +-- kestoneV2.py"},{"line_number":120,"context_line":"                  |     |"},{"line_number":121,"context_line":"                  |     +-- kestoneV3.py"},{"line_number":122,"context_line":"                  |"}],"source_content_type":"text/x-rst","patch_set":16,"id":"7a016987_506b0f85","line":119,"updated":"2015-05-25 10:44:11.000000000","message":"keystone_v2.py (mixedCase is not working convention)","commit_id":"c9f87a312be7ea018a83a9577cd9e208cf2fb382"},{"author":{"_account_id":10475,"name":"Alexander Maretskiy","email":"amaretskiy@mirantis.com","username":"maretskiy"},"change_message_id":"59639c1f0b53eef058e9d41905475571163da3fb","unresolved":false,"context_lines":[{"line_number":118,"context_line":"                  |     | # common.py for implementation."},{"line_number":119,"context_line":"                  |     +-- kestoneV2.py"},{"line_number":120,"context_line":"                  |     |"},{"line_number":121,"context_line":"                  |     +-- kestoneV3.py"},{"line_number":122,"context_line":"                  |"},{"line_number":123,"context_line":"                  +-- network/"},{"line_number":124,"context_line":"                  |     | # Here is common service when we care to do things"}],"source_content_type":"text/x-rst","patch_set":16,"id":"7a016987_5002efb4","line":121,"updated":"2015-05-25 10:44:11.000000000","message":"keystone_v3.py (mixedCase is not working convention)","commit_id":"c9f87a312be7ea018a83a9577cd9e208cf2fb382"},{"author":{"_account_id":8576,"name":"Yair Fried","email":"yfried@redhat.com","username":"yfried"},"change_message_id":"4759a45e943371609c6a530e29ade42fdb105768","unresolved":false,"context_lines":[{"line_number":118,"context_line":"                  |     | # common.py for implementation."},{"line_number":119,"context_line":"                  |     +-- kestoneV2.py"},{"line_number":120,"context_line":"                  |     |"},{"line_number":121,"context_line":"                  |     +-- kestoneV3.py"},{"line_number":122,"context_line":"                  |"},{"line_number":123,"context_line":"                  +-- network/"},{"line_number":124,"context_line":"                  |     | # Here is common service when we care to do things"}],"source_content_type":"text/x-rst","patch_set":16,"id":"7a2fa921_560f5736","line":121,"in_reply_to":"7a016987_5002efb4","updated":"2015-10-11 07:28:14.000000000","message":"Done","commit_id":"c9f87a312be7ea018a83a9577cd9e208cf2fb382"},{"author":{"_account_id":10475,"name":"Alexander Maretskiy","email":"amaretskiy@mirantis.com","username":"maretskiy"},"change_message_id":"59639c1f0b53eef058e9d41905475571163da3fb","unresolved":false,"context_lines":[{"line_number":129,"context_line":"                  |     | # Here is api for working with specific API"},{"line_number":130,"context_line":"                  |     | # version/service Like nova_network/neutron."},{"line_number":131,"context_line":"                  |     | # This will be used in common.py for implementation."},{"line_number":132,"context_line":"                  |     +-- nova-network.py"},{"line_number":133,"context_line":"                  |     |"},{"line_number":134,"context_line":"                  |     +-- neutron.py"},{"line_number":135,"context_line":"                  +-- ..."}],"source_content_type":"text/x-rst","patch_set":16,"id":"7a016987_f0631baf","line":132,"updated":"2015-05-25 10:44:11.000000000","message":"s/nova-network.py/nova_network.py/","commit_id":"c9f87a312be7ea018a83a9577cd9e208cf2fb382"},{"author":{"_account_id":10475,"name":"Alexander Maretskiy","email":"amaretskiy@mirantis.com","username":"maretskiy"},"change_message_id":"59639c1f0b53eef058e9d41905475571163da3fb","unresolved":false,"context_lines":[{"line_number":139,"context_line":".. code-block:: python"},{"line_number":140,"context_line":""},{"line_number":141,"context_line":""},{"line_number":142,"context_line":"    ServiceManager(Plugin):"},{"line_number":143,"context_line":"        def __init__(self,...., atomic_action_mgr\u003dNone):"},{"line_number":144,"context_line":"            atomic_action_mgr \u003d atomic_action_mgr or self"},{"line_number":145,"context_line":""}],"source_content_type":"text/x-rst","patch_set":16,"id":"7a016987_30c2d353","line":142,"updated":"2015-05-25 10:44:11.000000000","message":"This is not clear for me how atomic actions will be used in plugins. Can you give some examples?","commit_id":"c9f87a312be7ea018a83a9577cd9e208cf2fb382"},{"author":{"_account_id":10475,"name":"Alexander Maretskiy","email":"amaretskiy@mirantis.com","username":"maretskiy"},"change_message_id":"59639c1f0b53eef058e9d41905475571163da3fb","unresolved":false,"context_lines":[{"line_number":187,"context_line":"----------"},{"line_number":188,"context_line":""},{"line_number":189,"context_line":"#. Create ServiceManager in os_service/base.py"},{"line_number":190,"context_line":"#. create new interface (AtomicAction Mixing)"},{"line_number":191,"context_line":"#. depracate old interface (in base.Scenario) \u003d\u003e it must work"},{"line_number":192,"context_line":"#. start working on services"},{"line_number":193,"context_line":"#. port portions by portions of scenario utils to services"}],"source_content_type":"text/x-rst","patch_set":16,"id":"7a016987_50f0afc8","line":190,"updated":"2015-05-25 10:44:11.000000000","message":"s/Mixing/Mixin/","commit_id":"c9f87a312be7ea018a83a9577cd9e208cf2fb382"},{"author":{"_account_id":6172,"name":"Boris Pavlovic","email":"boris@pavlovic.me","username":"boris-42"},"change_message_id":"61cae4830359a3a99697fef8d915be59f86d1eb7","unresolved":false,"context_lines":[{"line_number":16,"context_line":"\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d"},{"line_number":17,"context_line":""},{"line_number":18,"context_line":"Code that wraps openstack services from different scenario utils is difficult"},{"line_number":19,"context_line":"to reuse outside the scenario directory (ie, different scenarios and areas"},{"line_number":20,"context_line":"like context), which causes code duplications and strange solutions like"},{"line_number":21,"context_line":"wrappers."},{"line_number":22,"context_line":"As well it is impossible to do versioning of current utils which makes them"}],"source_content_type":"text/x-rst","patch_set":19,"id":"7a2fa921_b1135564","line":19,"updated":"2015-10-11 10:48:25.000000000","message":"s/outside the scenario directory/in context plugins/","commit_id":"fd351e0b0373d3e8efccd1e0fa378583c4f3bc98"},{"author":{"_account_id":8576,"name":"Yair Fried","email":"yfried@redhat.com","username":"yfried"},"change_message_id":"29350433d478219a4c07a9597aa056d056365354","unresolved":false,"context_lines":[{"line_number":16,"context_line":"\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d"},{"line_number":17,"context_line":""},{"line_number":18,"context_line":"Code that wraps openstack services from different scenario utils is difficult"},{"line_number":19,"context_line":"to reuse outside the scenario directory (ie, different scenarios and areas"},{"line_number":20,"context_line":"like context), which causes code duplications and strange solutions like"},{"line_number":21,"context_line":"wrappers."},{"line_number":22,"context_line":"As well it is impossible to do versioning of current utils which makes them"}],"source_content_type":"text/x-rst","patch_set":19,"id":"7a2fa921_acde9a3b","line":19,"in_reply_to":"7a2fa921_b1135564","updated":"2015-10-11 12:29:08.000000000","message":"Done","commit_id":"fd351e0b0373d3e8efccd1e0fa378583c4f3bc98"},{"author":{"_account_id":6172,"name":"Boris Pavlovic","email":"boris@pavlovic.me","username":"boris-42"},"change_message_id":"61cae4830359a3a99697fef8d915be59f86d1eb7","unresolved":false,"context_lines":[{"line_number":18,"context_line":"Code that wraps openstack services from different scenario utils is difficult"},{"line_number":19,"context_line":"to reuse outside the scenario directory (ie, different scenarios and areas"},{"line_number":20,"context_line":"like context), which causes code duplications and strange solutions like"},{"line_number":21,"context_line":"wrappers."},{"line_number":22,"context_line":"As well it is impossible to do versioning of current utils which makes them"},{"line_number":23,"context_line":"absolutely non-reusable as a base for out of tree plugins."},{"line_number":24,"context_line":""}],"source_content_type":"text/x-rst","patch_set":19,"id":"7a2fa921_510f6136","line":21,"updated":"2015-10-11 10:48:25.000000000","message":"First of all it is not strange solution. The second thing it was not introduce to resolve absolutely different task, we were trying to unify different services (versions of API) in case when we don\u0027t care about details about implementation and would just to get something done.","commit_id":"fd351e0b0373d3e8efccd1e0fa378583c4f3bc98"},{"author":{"_account_id":8576,"name":"Yair Fried","email":"yfried@redhat.com","username":"yfried"},"change_message_id":"29350433d478219a4c07a9597aa056d056365354","unresolved":false,"context_lines":[{"line_number":18,"context_line":"Code that wraps openstack services from different scenario utils is difficult"},{"line_number":19,"context_line":"to reuse outside the scenario directory (ie, different scenarios and areas"},{"line_number":20,"context_line":"like context), which causes code duplications and strange solutions like"},{"line_number":21,"context_line":"wrappers."},{"line_number":22,"context_line":"As well it is impossible to do versioning of current utils which makes them"},{"line_number":23,"context_line":"absolutely non-reusable as a base for out of tree plugins."},{"line_number":24,"context_line":""}],"source_content_type":"text/x-rst","patch_set":19,"id":"7a2fa921_4cea66dc","line":21,"in_reply_to":"7a2fa921_510f6136","updated":"2015-10-11 12:29:08.000000000","message":"Done","commit_id":"fd351e0b0373d3e8efccd1e0fa378583c4f3bc98"},{"author":{"_account_id":6172,"name":"Boris Pavlovic","email":"boris@pavlovic.me","username":"boris-42"},"change_message_id":"61cae4830359a3a99697fef8d915be59f86d1eb7","unresolved":false,"context_lines":[{"line_number":20,"context_line":"like context), which causes code duplications and strange solutions like"},{"line_number":21,"context_line":"wrappers."},{"line_number":22,"context_line":"As well it is impossible to do versioning of current utils which makes them"},{"line_number":23,"context_line":"absolutely non-reusable as a base for out of tree plugins."},{"line_number":24,"context_line":""},{"line_number":25,"context_line":"Proposed change"},{"line_number":26,"context_line":"\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d"}],"source_content_type":"text/x-rst","patch_set":19,"id":"7a2fa921_cc019606","line":23,"updated":"2015-10-11 10:48:25.000000000","message":"IMHO they are not absolutely non-reusable and we are doing deprecation method before deleting them. But yep agree we can do it better","commit_id":"fd351e0b0373d3e8efccd1e0fa378583c4f3bc98"},{"author":{"_account_id":8576,"name":"Yair Fried","email":"yfried@redhat.com","username":"yfried"},"change_message_id":"29350433d478219a4c07a9597aa056d056365354","unresolved":false,"context_lines":[{"line_number":20,"context_line":"like context), which causes code duplications and strange solutions like"},{"line_number":21,"context_line":"wrappers."},{"line_number":22,"context_line":"As well it is impossible to do versioning of current utils which makes them"},{"line_number":23,"context_line":"absolutely non-reusable as a base for out of tree plugins."},{"line_number":24,"context_line":""},{"line_number":25,"context_line":"Proposed change"},{"line_number":26,"context_line":"\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d"}],"source_content_type":"text/x-rst","patch_set":19,"id":"7a2fa921_6ce5e206","line":23,"in_reply_to":"7a2fa921_cc019606","updated":"2015-10-11 12:29:08.000000000","message":"Done","commit_id":"fd351e0b0373d3e8efccd1e0fa378583c4f3bc98"},{"author":{"_account_id":6172,"name":"Boris Pavlovic","email":"boris@pavlovic.me","username":"boris-42"},"change_message_id":"61cae4830359a3a99697fef8d915be59f86d1eb7","unresolved":false,"context_lines":[{"line_number":119,"context_line":"                  │     ├── neutron.py"},{"line_number":120,"context_line":"                  ├── ..."},{"line_number":121,"context_line":""},{"line_number":122,"context_line":""},{"line_number":123,"context_line":"Assignee(s)"},{"line_number":124,"context_line":"-----------"},{"line_number":125,"context_line":""}],"source_content_type":"text/x-rst","patch_set":19,"id":"7a2fa921_ec049215","line":122,"updated":"2015-10-11 10:48:25.000000000","message":"so we need here description of: \n\n* How common service will interact with services for specific version\n* How specific version services would look like \n* The stuff related to atomic_actions and how we are going to implement same functionallity that we have now it scenarios and utils.","commit_id":"fd351e0b0373d3e8efccd1e0fa378583c4f3bc98"},{"author":{"_account_id":10475,"name":"Alexander Maretskiy","email":"amaretskiy@mirantis.com","username":"maretskiy"},"change_message_id":"fed930be6b215e60531887847586a1ab84ee0e5a","unresolved":false,"context_lines":[{"line_number":64,"context_line":"      |       +-- network.py"},{"line_number":65,"context_line":""},{"line_number":66,"context_line":"keystone scenarios use plugins/openstack/scenarios/keystone/utils.py"},{"line_number":67,"context_line":".. code-block:: python"},{"line_number":68,"context_line":""},{"line_number":69,"context_line":"    @atomic.action_timer(\"keystone.create_tenant\")"},{"line_number":70,"context_line":"    def _tenant_create(self, name_length\u003d10, **kwargs):"}],"source_content_type":"text/x-rst","patch_set":22,"id":"7a2fa921_a4ee95b2","line":67,"updated":"2015-10-12 16:32:14.000000000","message":"RST format requires blank line before `.. code-block\u0027\n\nSame for another occurrences below","commit_id":"fd44a0edc78d53153134dd2b4c6b6cb9388c659a"},{"author":{"_account_id":10475,"name":"Alexander Maretskiy","email":"amaretskiy@mirantis.com","username":"maretskiy"},"change_message_id":"fed930be6b215e60531887847586a1ab84ee0e5a","unresolved":false,"context_lines":[{"line_number":230,"context_line":"                                argument must be None or \u0027Default\u0027."},{"line_number":231,"context_line":"            \"\"\""},{"line_number":232,"context_line":""},{"line_number":233,"context_line":"    class KeystoneV2Wrapper(KeystoneWrapper):"},{"line_number":234,"context_line":"        def create_project(self, project_name, domain_name\u003d\"Default\","},{"line_number":235,"context_line":"                           **kwargs):"},{"line_number":236,"context_line":"            self._check_domain(domain_name)"}],"source_content_type":"text/x-rst","patch_set":22,"id":"7a2fa921_b567a1e9","line":233,"updated":"2015-10-12 16:32:14.000000000","message":"class IdentityV2Service(IdentityService):","commit_id":"fd44a0edc78d53153134dd2b4c6b6cb9388c659a"},{"author":{"_account_id":10475,"name":"Alexander Maretskiy","email":"amaretskiy@mirantis.com","username":"maretskiy"},"change_message_id":"fed930be6b215e60531887847586a1ab84ee0e5a","unresolved":false,"context_lines":[{"line_number":244,"context_line":"            project \u003d self.client.projects.create("},{"line_number":245,"context_line":"                name\u003dproject_name, domain\u003ddomain_id)"},{"line_number":246,"context_line":"            return KeystoneV3Wrapper._wrap_v3_project(project)"},{"line_number":247,"context_line":""},{"line_number":248,"context_line":"both context.keystone and scenario.keystone will now use services/identity.py"},{"line_number":249,"context_line":""},{"line_number":250,"context_line":"scenario:"}],"source_content_type":"text/x-rst","patch_set":22,"id":"7a2fa921_7554a9c9","line":247,"updated":"2015-10-12 16:32:14.000000000","message":"I think it worth to put here a sketch of implementation for Scenario.services() method","commit_id":"fd44a0edc78d53153134dd2b4c6b6cb9388c659a"},{"author":{"_account_id":12395,"name":"Roman Vasylets","email":"pomeo92@gmail.com","username":"rvasilets"},"change_message_id":"87df9d9992f4263a2521f436a1c82892f31cee55","unresolved":false,"context_lines":[{"line_number":20,"context_line":"which causes code duplications."},{"line_number":21,"context_line":"* Wrappers don\u0027t fully integrate with the current structure (example: network"},{"line_number":22,"context_line":"operations need to alternate between calls to utils and calls to network"},{"line_number":23,"context_line":"wrappers)."},{"line_number":24,"context_line":"* It is impossible to do versioning of current utils which makes them"},{"line_number":25,"context_line":"hard to reuse as a base for out of tree plugins."},{"line_number":26,"context_line":""}],"source_content_type":"text/x-rst","patch_set":23,"id":"7a5de9d1_90f34e0a","line":23,"updated":"2016-01-28 16:33:23.000000000","message":"We could agree that utils should be used in wrappers and wrappers in scenario. Or something similar.","commit_id":"cbfa361fe815460c863437f6e6c9ff918e8763a5"},{"author":{"_account_id":12395,"name":"Roman Vasylets","email":"pomeo92@gmail.com","username":"rvasilets"},"change_message_id":"87df9d9992f4263a2521f436a1c82892f31cee55","unresolved":false,"context_lines":[{"line_number":22,"context_line":"operations need to alternate between calls to utils and calls to network"},{"line_number":23,"context_line":"wrappers)."},{"line_number":24,"context_line":"* It is impossible to do versioning of current utils which makes them"},{"line_number":25,"context_line":"hard to reuse as a base for out of tree plugins."},{"line_number":26,"context_line":""},{"line_number":27,"context_line":"Proposed change"},{"line_number":28,"context_line":"\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d"}],"source_content_type":"text/x-rst","patch_set":23,"id":"7a5de9d1_b05a0a29","line":25,"updated":"2016-01-28 16:33:23.000000000","message":"How creating of services will help with versioning?","commit_id":"cbfa361fe815460c863437f6e6c9ff918e8763a5"},{"author":{"_account_id":12395,"name":"Roman Vasylets","email":"pomeo92@gmail.com","username":"rvasilets"},"change_message_id":"87df9d9992f4263a2521f436a1c82892f31cee55","unresolved":false,"context_lines":[{"line_number":27,"context_line":"Proposed change"},{"line_number":28,"context_line":"\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d"},{"line_number":29,"context_line":""},{"line_number":30,"context_line":"Group all service related utils under a single tree accessible from all areas"},{"line_number":31,"context_line":"of the project."},{"line_number":32,"context_line":"Also, inheritance structure in scenarios is problematic. This would be a great"},{"line_number":33,"context_line":"opportunity to move to composition."}],"source_content_type":"text/x-rst","patch_set":23,"id":"7a5de9d1_25ab3a1f","line":30,"updated":"2016-01-28 16:33:23.000000000","message":"I think that the most uncomfortable thin is that usage of wrappers and utils in scenarios inconsistent. Also a lot of code in wrapper is copy-paste. Maybe you will specify what difficults you\u0027ve faced with?","commit_id":"cbfa361fe815460c863437f6e6c9ff918e8763a5"},{"author":{"_account_id":12395,"name":"Roman Vasylets","email":"pomeo92@gmail.com","username":"rvasilets"},"change_message_id":"87df9d9992f4263a2521f436a1c82892f31cee55","unresolved":false,"context_lines":[{"line_number":30,"context_line":"Group all service related utils under a single tree accessible from all areas"},{"line_number":31,"context_line":"of the project."},{"line_number":32,"context_line":"Also, inheritance structure in scenarios is problematic. This would be a great"},{"line_number":33,"context_line":"opportunity to move to composition."},{"line_number":34,"context_line":""},{"line_number":35,"context_line":"Alternatives"},{"line_number":36,"context_line":"------------"}],"source_content_type":"text/x-rst","patch_set":23,"id":"7a5de9d1_c5858607","line":33,"updated":"2016-01-28 16:33:23.000000000","message":"As I understand you suggest to move utils and wrapper under services layer. But I can\u0027t understand how this simplify the life.","commit_id":"cbfa361fe815460c863437f6e6c9ff918e8763a5"},{"author":{"_account_id":12395,"name":"Roman Vasylets","email":"pomeo92@gmail.com","username":"rvasilets"},"change_message_id":"87df9d9992f4263a2521f436a1c82892f31cee55","unresolved":false,"context_lines":[{"line_number":169,"context_line":"       +-- scenarios/"},{"line_number":170,"context_line":"       |   |"},{"line_number":171,"context_line":"       |   |"},{"line_number":172,"context_line":"       |   +-- neutron/"},{"line_number":173,"context_line":"       |   +-- authenticate/"},{"line_number":174,"context_line":"       |"},{"line_number":175,"context_line":"       +-- services/"}],"source_content_type":"text/x-rst","patch_set":23,"id":"7a5de9d1_7fab05d7","line":172,"updated":"2016-01-28 16:33:23.000000000","message":"What would be here?","commit_id":"cbfa361fe815460c863437f6e6c9ff918e8763a5"},{"author":{"_account_id":12395,"name":"Roman Vasylets","email":"pomeo92@gmail.com","username":"rvasilets"},"change_message_id":"87df9d9992f4263a2521f436a1c82892f31cee55","unresolved":false,"context_lines":[{"line_number":174,"context_line":"       |"},{"line_number":175,"context_line":"       +-- services/"},{"line_number":176,"context_line":"           |  # Here we will store base code for openstack services."},{"line_number":177,"context_line":"           |  # like wait_for, and wait_for_delete"},{"line_number":178,"context_line":"           +-- base.py"},{"line_number":179,"context_line":"           |"},{"line_number":180,"context_line":"           +-- compute/"}],"source_content_type":"text/x-rst","patch_set":23,"id":"7a5de9d1_2306e0ce","line":177,"updated":"2016-01-28 16:33:23.000000000","message":"But functions like wait_for and wait_for_delete not openstack specific. They might be needed for non-openstack resources If we are talking about https://github.com/openstack/rally/blob/master/rally/task/utils.py#L104 So I don\u0027t understand what\u0027s mean \"base code\".","commit_id":"cbfa361fe815460c863437f6e6c9ff918e8763a5"},{"author":{"_account_id":8491,"name":"Illia Khudoshyn","email":"ikhudoshyn@mirantis.com","username":"ikhudoshyn"},"change_message_id":"94df3a90086a2372fbb3c3a16ad0727472ea64d8","unresolved":false,"context_lines":[{"line_number":175,"context_line":"       +-- services/"},{"line_number":176,"context_line":"           |  # Here we will store base code for openstack services."},{"line_number":177,"context_line":"           |  # like wait_for, and wait_for_delete"},{"line_number":178,"context_line":"           +-- base.py"},{"line_number":179,"context_line":"           |"},{"line_number":180,"context_line":"           +-- compute/"},{"line_number":181,"context_line":"           |   |"}],"source_content_type":"text/x-rst","patch_set":23,"id":"9a68dd71_e1b80aeb","line":178,"range":{"start_line":178,"start_character":0,"end_line":178,"end_character":22},"updated":"2016-01-26 09:32:30.000000000","message":"base.py could be a great place for base classes, but for plain functions I\u0027d consider __init__.py","commit_id":"cbfa361fe815460c863437f6e6c9ff918e8763a5"},{"author":{"_account_id":8491,"name":"Illia Khudoshyn","email":"ikhudoshyn@mirantis.com","username":"ikhudoshyn"},"change_message_id":"94df3a90086a2372fbb3c3a16ad0727472ea64d8","unresolved":false,"context_lines":[{"line_number":179,"context_line":"           |"},{"line_number":180,"context_line":"           +-- compute/"},{"line_number":181,"context_line":"           |   |"},{"line_number":182,"context_line":"           |   +-- main.py"},{"line_number":183,"context_line":"           |"},{"line_number":184,"context_line":"           +-- identity/"},{"line_number":185,"context_line":"           |   | # Here is common service when we care to do things"}],"source_content_type":"text/x-rst","patch_set":23,"id":"9a68dd71_76085e2e","line":182,"range":{"start_line":182,"start_character":23,"end_line":182,"end_character":24},"updated":"2016-01-26 09:32:30.000000000","message":"We are not going to have any executables here, are we?\nI guess __init__.py suites better here.","commit_id":"cbfa361fe815460c863437f6e6c9ff918e8763a5"},{"author":{"_account_id":8491,"name":"Illia Khudoshyn","email":"ikhudoshyn@mirantis.com","username":"ikhudoshyn"},"change_message_id":"94df3a90086a2372fbb3c3a16ad0727472ea64d8","unresolved":false,"context_lines":[{"line_number":186,"context_line":"           |   | # and regardless of which API/service is used for"},{"line_number":187,"context_line":"           |   | # that. So we will implement here parts that can be"},{"line_number":188,"context_line":"           |   | # done in both."},{"line_number":189,"context_line":"           |   +-- main.py"},{"line_number":190,"context_line":"           |   | # Here is api for working with specific API"},{"line_number":191,"context_line":"           |   | # version/service Like keystone_v2/keystone_v3 or"},{"line_number":192,"context_line":"           |   | # nova_network/neutron. This will be used in"}],"source_content_type":"text/x-rst","patch_set":23,"id":"9a68dd71_6112da5a","line":189,"range":{"start_line":189,"start_character":24,"end_line":189,"end_character":26},"updated":"2016-01-26 09:32:30.000000000","message":"Ditto","commit_id":"cbfa361fe815460c863437f6e6c9ff918e8763a5"},{"author":{"_account_id":8491,"name":"Illia Khudoshyn","email":"ikhudoshyn@mirantis.com","username":"ikhudoshyn"},"change_message_id":"94df3a90086a2372fbb3c3a16ad0727472ea64d8","unresolved":false,"context_lines":[{"line_number":200,"context_line":"           |   | # and regardless of which API/service is used for"},{"line_number":201,"context_line":"           |   | # that. So we will implement here parts that can be"},{"line_number":202,"context_line":"           |   | # done in both."},{"line_number":203,"context_line":"           |   +-- main.py"},{"line_number":204,"context_line":"           |   | # Here is api for working with specific API"},{"line_number":205,"context_line":"           |   | # version/service Like nova_network/neutron."},{"line_number":206,"context_line":"           |   | # This will be used in main.py for implementation."}],"source_content_type":"text/x-rst","patch_set":23,"id":"9a68dd71_4119d678","line":203,"range":{"start_line":203,"start_character":19,"end_line":203,"end_character":23},"updated":"2016-01-26 09:32:30.000000000","message":"Ditto","commit_id":"cbfa361fe815460c863437f6e6c9ff918e8763a5"},{"author":{"_account_id":6172,"name":"Boris Pavlovic","email":"boris@pavlovic.me","username":"boris-42"},"change_message_id":"2380eb3f438234be1df7b80f96a5f165fd28d68e","unresolved":false,"context_lines":[{"line_number":233,"context_line":"                                argument must be None or \u0027Default\u0027."},{"line_number":234,"context_line":"            \"\"\""},{"line_number":235,"context_line":""},{"line_number":236,"context_line":"    class KeystoneV2Wrapper(IdentityService):"},{"line_number":237,"context_line":"        def create_project(self, project_name, domain_name\u003d\"Default\","},{"line_number":238,"context_line":"                           **kwargs):"},{"line_number":239,"context_line":"            self._check_domain(domain_name)"}],"source_content_type":"text/x-rst","patch_set":23,"id":"5a2ca52d_5b8b97c3","line":236,"updated":"2015-10-15 07:31:43.000000000","message":"Let\u0027s call it KeystoneV2Service","commit_id":"cbfa361fe815460c863437f6e6c9ff918e8763a5"},{"author":{"_account_id":6172,"name":"Boris Pavlovic","email":"boris@pavlovic.me","username":"boris-42"},"change_message_id":"2380eb3f438234be1df7b80f96a5f165fd28d68e","unresolved":false,"context_lines":[{"line_number":236,"context_line":"    class KeystoneV2Wrapper(IdentityService):"},{"line_number":237,"context_line":"        def create_project(self, project_name, domain_name\u003d\"Default\","},{"line_number":238,"context_line":"                           **kwargs):"},{"line_number":239,"context_line":"            self._check_domain(domain_name)"},{"line_number":240,"context_line":"            tenant \u003d self.client.tenants.create(project_name)"},{"line_number":241,"context_line":"            return KeystoneV2Wrapper._wrap_v2_tenant(tenant)"},{"line_number":242,"context_line":""}],"source_content_type":"text/x-rst","patch_set":23,"id":"5a2ca52d_1b951fdd","line":239,"updated":"2015-10-15 07:31:43.000000000","message":"self._check_domain is waht?","commit_id":"cbfa361fe815460c863437f6e6c9ff918e8763a5"},{"author":{"_account_id":6172,"name":"Boris Pavlovic","email":"boris@pavlovic.me","username":"boris-42"},"change_message_id":"2380eb3f438234be1df7b80f96a5f165fd28d68e","unresolved":false,"context_lines":[{"line_number":237,"context_line":"        def create_project(self, project_name, domain_name\u003d\"Default\","},{"line_number":238,"context_line":"                           **kwargs):"},{"line_number":239,"context_line":"            self._check_domain(domain_name)"},{"line_number":240,"context_line":"            tenant \u003d self.client.tenants.create(project_name)"},{"line_number":241,"context_line":"            return KeystoneV2Wrapper._wrap_v2_tenant(tenant)"},{"line_number":242,"context_line":""},{"line_number":243,"context_line":"    class KeystoneV3Wrapper(IdentityService):"}],"source_content_type":"text/x-rst","patch_set":23,"id":"5a2ca52d_9bb7ef85","line":240,"updated":"2015-10-15 07:31:43.000000000","message":"where self.client is set up?","commit_id":"cbfa361fe815460c863437f6e6c9ff918e8763a5"},{"author":{"_account_id":6172,"name":"Boris Pavlovic","email":"boris@pavlovic.me","username":"boris-42"},"change_message_id":"2380eb3f438234be1df7b80f96a5f165fd28d68e","unresolved":false,"context_lines":[{"line_number":240,"context_line":"            tenant \u003d self.client.tenants.create(project_name)"},{"line_number":241,"context_line":"            return KeystoneV2Wrapper._wrap_v2_tenant(tenant)"},{"line_number":242,"context_line":""},{"line_number":243,"context_line":"    class KeystoneV3Wrapper(IdentityService):"},{"line_number":244,"context_line":"        def create_project(self, project_name, domain_name\u003d\"Default\""},{"line_number":245,"context_line":"                           **kwargs):"},{"line_number":246,"context_line":"            domain_id \u003d self._get_domain_id(domain_name)"}],"source_content_type":"text/x-rst","patch_set":23,"id":"5a2ca52d_16e97614","line":243,"updated":"2015-10-15 07:31:43.000000000","message":"KeystoneV3Service","commit_id":"cbfa361fe815460c863437f6e6c9ff918e8763a5"},{"author":{"_account_id":6172,"name":"Boris Pavlovic","email":"boris@pavlovic.me","username":"boris-42"},"change_message_id":"2380eb3f438234be1df7b80f96a5f165fd28d68e","unresolved":false,"context_lines":[{"line_number":266,"context_line":"            :param name_length: length of the random part of tenant name"},{"line_number":267,"context_line":"            :param kwargs: Other optional parameters"},{"line_number":268,"context_line":"            \"\"\""},{"line_number":269,"context_line":"            name \u003d self._generate_random_name(length\u003dname_length)"},{"line_number":270,"context_line":"            self.services(\"identity\").create_project(name,"},{"line_number":271,"context_line":"                                                     **kwargs)"},{"line_number":272,"context_line":"Users context:"}],"source_content_type":"text/x-rst","patch_set":23,"id":"5a2ca52d_3669128c","line":269,"updated":"2015-10-15 07:31:43.000000000","message":"We shouldn\u0027t allow users to generate name with custom name length","commit_id":"cbfa361fe815460c863437f6e6c9ff918e8763a5"},{"author":{"_account_id":6172,"name":"Boris Pavlovic","email":"boris@pavlovic.me","username":"boris-42"},"change_message_id":"2380eb3f438234be1df7b80f96a5f165fd28d68e","unresolved":false,"context_lines":[{"line_number":267,"context_line":"            :param kwargs: Other optional parameters"},{"line_number":268,"context_line":"            \"\"\""},{"line_number":269,"context_line":"            name \u003d self._generate_random_name(length\u003dname_length)"},{"line_number":270,"context_line":"            self.services(\"identity\").create_project(name,"},{"line_number":271,"context_line":"                                                     **kwargs)"},{"line_number":272,"context_line":"Users context:"},{"line_number":273,"context_line":""}],"source_content_type":"text/x-rst","patch_set":23,"id":"5a2ca52d_76f6aad8","line":270,"updated":"2015-10-15 07:31:43.000000000","message":"I would like to see the implantation of self.services","commit_id":"cbfa361fe815460c863437f6e6c9ff918e8763a5"},{"author":{"_account_id":8491,"name":"Illia Khudoshyn","email":"ikhudoshyn@mirantis.com","username":"ikhudoshyn"},"change_message_id":"94df3a90086a2372fbb3c3a16ad0727472ea64d8","unresolved":false,"context_lines":[{"line_number":294,"context_line":"Work Items"},{"line_number":295,"context_line":"----------"},{"line_number":296,"context_line":""},{"line_number":297,"context_line":"#. Create ServiceManager in openstack/service/base.py"},{"line_number":298,"context_line":"#. Repeat until will get rid of utils"},{"line_number":299,"context_line":""},{"line_number":300,"context_line":"  * port portions by portions of scenario utils to services"}],"source_content_type":"text/x-rst","patch_set":23,"id":"9a68dd71_a1e692ae","line":297,"range":{"start_line":297,"start_character":0,"end_line":297,"end_character":53},"updated":"2016-01-26 09:32:30.000000000","message":"Sorry for my ignorance, as I joined to the discussion late, but do we expect services configured in runtime, akin to Java\u0027s Spring IoC? Why do we need a ServiceManager class at all? \nMaybe it is worth adding at least a brief hints as for how is is going to look like and how it is going to be used?","commit_id":"cbfa361fe815460c863437f6e6c9ff918e8763a5"}],"doc/specs/in-progress/refactor_scenario_utils.rst":[{"author":{"_account_id":9545,"name":"Andriy Kurilin","email":"andr.kurilin@gmail.com","username":"akurilin"},"change_message_id":"106a748cbd10b71137462c10d44228d1e2cac057","unresolved":false,"context_lines":[{"line_number":248,"context_line":""},{"line_number":249,"context_line":".. code-block:: python"},{"line_number":250,"context_line":""},{"line_number":251,"context_line":"    class IdentityService(Service):"},{"line_number":252,"context_line":""},{"line_number":253,"context_line":"        def __init__(self, clients, atomic_inst\u003dNone, version\u003dNone):"},{"line_number":254,"context_line":"            super(self).__init__(clients, atomic_inst\u003datomic_inst)"}],"source_content_type":"text/x-rst","patch_set":24,"id":"bae84128_6dce74b5","line":251,"range":{"start_line":251,"start_character":10,"end_line":251,"end_character":26},"updated":"2016-02-22 16:43:17.000000000","message":"It would be nice to mention that IdentityService class will include only those methods which exists in both APIs","commit_id":"f76e9d4d7bac9e17caeffeb8bf780783b2383b96"},{"author":{"_account_id":6172,"name":"Boris Pavlovic","email":"boris@pavlovic.me","username":"boris-42"},"change_message_id":"a33bfe955c7c6d96c980c439b2dff72d72a02cd6","unresolved":false,"context_lines":[{"line_number":248,"context_line":""},{"line_number":249,"context_line":".. code-block:: python"},{"line_number":250,"context_line":""},{"line_number":251,"context_line":"    class IdentityService(Service):"},{"line_number":252,"context_line":""},{"line_number":253,"context_line":"        def __init__(self, clients, atomic_inst\u003dNone, version\u003dNone):"},{"line_number":254,"context_line":"            super(self).__init__(clients, atomic_inst\u003datomic_inst)"}],"source_content_type":"text/x-rst","patch_set":24,"id":"bae84128_d021134f","line":251,"range":{"start_line":251,"start_character":10,"end_line":251,"end_character":26},"in_reply_to":"bae84128_6dce74b5","updated":"2016-02-22 17:03:07.000000000","message":"Done","commit_id":"f76e9d4d7bac9e17caeffeb8bf780783b2383b96"},{"author":{"_account_id":9545,"name":"Andriy Kurilin","email":"andr.kurilin@gmail.com","username":"akurilin"},"change_message_id":"106a748cbd10b71137462c10d44228d1e2cac057","unresolved":false,"context_lines":[{"line_number":262,"context_line":"                self.impl \u003d auto_discover_version()"},{"line_number":263,"context_line":""},{"line_number":264,"context_line":"        def project_create(self, name, **kwargs):"},{"line_number":265,"context_line":"            result \u003d  self.impl.project_create(name)"},{"line_number":266,"context_line":"            return magic(result)"},{"line_number":267,"context_line":""},{"line_number":268,"context_line":"        # ..."},{"line_number":269,"context_line":""}],"source_content_type":"text/x-rst","patch_set":24,"id":"bae84128_8d581834","line":266,"range":{"start_line":265,"start_character":12,"end_line":266,"end_character":32},"updated":"2016-02-22 16:43:17.000000000","message":"please, describe what is magic. Something like:\n\n    result \u003d self.impl.project_create(name)\n    # handle the difference between implementations\n    return results","commit_id":"f76e9d4d7bac9e17caeffeb8bf780783b2383b96"},{"author":{"_account_id":6172,"name":"Boris Pavlovic","email":"boris@pavlovic.me","username":"boris-42"},"change_message_id":"a33bfe955c7c6d96c980c439b2dff72d72a02cd6","unresolved":false,"context_lines":[{"line_number":262,"context_line":"                self.impl \u003d auto_discover_version()"},{"line_number":263,"context_line":""},{"line_number":264,"context_line":"        def project_create(self, name, **kwargs):"},{"line_number":265,"context_line":"            result \u003d  self.impl.project_create(name)"},{"line_number":266,"context_line":"            return magic(result)"},{"line_number":267,"context_line":""},{"line_number":268,"context_line":"        # ..."},{"line_number":269,"context_line":""}],"source_content_type":"text/x-rst","patch_set":24,"id":"bae84128_f016d7ef","line":266,"range":{"start_line":265,"start_character":12,"end_line":266,"end_character":32},"in_reply_to":"bae84128_8d581834","updated":"2016-02-22 17:03:07.000000000","message":"Done","commit_id":"f76e9d4d7bac9e17caeffeb8bf780783b2383b96"},{"author":{"_account_id":11748,"name":"Chris St. Pierre","email":"cstpierr@cisco.com","username":"stpierre"},"change_message_id":"c6232d3bb8f0bd0b491009ac91834872bb512441","unresolved":false,"context_lines":[{"line_number":235,"context_line":"                # NOTE(boris-42): This allows us to use atomic actions"},{"line_number":236,"context_line":"                #                 decorators but they will add values"},{"line_number":237,"context_line":"                #                 to the scenario or context instance"},{"line_number":238,"context_line":"                self._atomic_actions \u003d atomic_inst._atomic_actions"},{"line_number":239,"context_line":"            else:"},{"line_number":240,"context_line":"                # NOTE(boris-42): If one is using this not for scenarios and"},{"line_number":241,"context_line":"                #                 context, Service instance will store atomic"}],"source_content_type":"text/x-rst","patch_set":25,"id":"bae84128_23f2bb6f","line":238,"updated":"2016-02-22 17:40:14.000000000","message":"This whole block is ugly for several reasons:\n\n1. Blatant and wanton access to private attributes, which could easily break in the future;\n\n2. isinstance() type comparison when what we really want is hasattr(atomic_inst, \"_atomic_actions\") duck-typing;\n\n3. No error message.\n\nI know this is just sample code so this won\u0027t make me -1 it, but let\u0027s make sure the code we actually merge is better than this.","commit_id":"af3826a480683c563ff0b2de4a39514b1922dc57"},{"author":{"_account_id":6172,"name":"Boris Pavlovic","email":"boris@pavlovic.me","username":"boris-42"},"change_message_id":"b39e7d9f37236354029574097a823c9c0ef626fd","unresolved":false,"context_lines":[{"line_number":235,"context_line":"                # NOTE(boris-42): This allows us to use atomic actions"},{"line_number":236,"context_line":"                #                 decorators but they will add values"},{"line_number":237,"context_line":"                #                 to the scenario or context instance"},{"line_number":238,"context_line":"                self._atomic_actions \u003d atomic_inst._atomic_actions"},{"line_number":239,"context_line":"            else:"},{"line_number":240,"context_line":"                # NOTE(boris-42): If one is using this not for scenarios and"},{"line_number":241,"context_line":"                #                 context, Service instance will store atomic"}],"source_content_type":"text/x-rst","patch_set":25,"id":"bae84128_1b12b709","line":238,"in_reply_to":"bae84128_23f2bb6f","updated":"2016-02-25 15:55:54.000000000","message":"1.a I agree that this is hack, however it\u0027s just few lines of code that saves our lives. We didn\u0027t find any better solution. \n\n1.b This is going to fail fast in unit/functional/integration tests, so it won\u0027t pass the gates, and it\u0027s only one single line of code. In other words if we have even just one scenario that is tested and uses any of subclass of Service we will see that _atomic_actions was changed (because CI will fail) \n\n2. Is instance is way better. We want to check that instance has AtomicActions in subclass and not just have some random field\n\n3. I can add message however it\u0027s just a sample of code that shows idea","commit_id":"af3826a480683c563ff0b2de4a39514b1922dc57"},{"author":{"_account_id":10475,"name":"Alexander Maretskiy","email":"amaretskiy@mirantis.com","username":"maretskiy"},"change_message_id":"71a6c627656abaa2fe31f1ecb9b30c1058f29fb6","unresolved":false,"context_lines":[{"line_number":274,"context_line":""},{"line_number":275,"context_line":".. code-block:: python"},{"line_number":276,"context_line":""},{"line_number":277,"context_line":"    class KeystoneServiceV2(KeystoneService):"},{"line_number":278,"context_line":""},{"line_number":279,"context_line":"        # NOTE(boris-42): we can use specific atomic action names"},{"line_number":280,"context_line":"        #                 for specific implementation of service"}],"source_content_type":"text/x-rst","patch_set":25,"id":"bae84128_f0725748","line":277,"updated":"2016-02-22 17:05:08.000000000","message":"KeystoneV2Service","commit_id":"af3826a480683c563ff0b2de4a39514b1922dc57"},{"author":{"_account_id":6172,"name":"Boris Pavlovic","email":"boris@pavlovic.me","username":"boris-42"},"change_message_id":"6720440d5f56021c5a4632a4afba7b17d56f0b93","unresolved":false,"context_lines":[{"line_number":274,"context_line":""},{"line_number":275,"context_line":".. code-block:: python"},{"line_number":276,"context_line":""},{"line_number":277,"context_line":"    class KeystoneServiceV2(KeystoneService):"},{"line_number":278,"context_line":""},{"line_number":279,"context_line":"        # NOTE(boris-42): we can use specific atomic action names"},{"line_number":280,"context_line":"        #                 for specific implementation of service"}],"source_content_type":"text/x-rst","patch_set":25,"id":"bae84128_b0cd6f5f","line":277,"in_reply_to":"bae84128_f0725748","updated":"2016-02-22 17:06:27.000000000","message":"it doesn\u0027t matter, this is just sample....","commit_id":"af3826a480683c563ff0b2de4a39514b1922dc57"},{"author":{"_account_id":10475,"name":"Alexander Maretskiy","email":"amaretskiy@mirantis.com","username":"maretskiy"},"change_message_id":"3f7e12c2592d36d054fc9a32450a31e2d7e5d7b4","unresolved":false,"context_lines":[{"line_number":332,"context_line":"                                                               **kwargs)"},{"line_number":333,"context_line":""},{"line_number":334,"context_line":"            # NOTE(boris-42): If you need specific operation for keystone v3"},{"line_number":335,"context_line":"            keystone_v3.KeystoneServiceV3(self.clients, self).domain_create()"},{"line_number":336,"context_line":""},{"line_number":337,"context_line":"            # NOTE(boris-42): One of the nice thing is that we can move"},{"line_number":338,"context_line":"            #                 initialization of services to __init__ method"}],"source_content_type":"text/x-rst","patch_set":25,"id":"bae84128_b069ef27","line":335,"updated":"2016-02-22 17:09:08.000000000","message":"Why not common.Identity(self.clients, self, version\u003d\"3\")... ?","commit_id":"af3826a480683c563ff0b2de4a39514b1922dc57"},{"author":{"_account_id":6172,"name":"Boris Pavlovic","email":"boris@pavlovic.me","username":"boris-42"},"change_message_id":"153fb2bfea4d703d2314f9b8607aec8a1b4bb9cb","unresolved":false,"context_lines":[{"line_number":332,"context_line":"                                                               **kwargs)"},{"line_number":333,"context_line":""},{"line_number":334,"context_line":"            # NOTE(boris-42): If you need specific operation for keystone v3"},{"line_number":335,"context_line":"            keystone_v3.KeystoneServiceV3(self.clients, self).domain_create()"},{"line_number":336,"context_line":""},{"line_number":337,"context_line":"            # NOTE(boris-42): One of the nice thing is that we can move"},{"line_number":338,"context_line":"            #                 initialization of services to __init__ method"}],"source_content_type":"text/x-rst","patch_set":25,"id":"9aed3d3a_c59a6ec5","line":335,"in_reply_to":"9aed3d3a_a2d48047","updated":"2016-02-25 17:19:23.000000000","message":"Chris, \n\nThere are some rights point in theory that you are explaining.\n\nHowever, reality is a bit different. Let\u0027s assume that we have like 20 jobs that are testing different configuration of everything. And it\u0027s actually testing mostly just master, this should be multple by 3 times to test stable releases and after that you are saying that (instead of making code that will fail unit tests) we should make the code that will fail only integration tests we should multple all jobs for matrix of all versions. Which will produce 60 * multple(len(service.versions)! for service in service) which close to infinite amount of  jobs that are required for testing. \n\nI believe it\u0027s better to extend the samples to cover micro versions support by this approach and see how it looks in real life.","commit_id":"af3826a480683c563ff0b2de4a39514b1922dc57"},{"author":{"_account_id":11748,"name":"Chris St. Pierre","email":"cstpierr@cisco.com","username":"stpierre"},"change_message_id":"88d586ea7d432f8ebf91f08059c3127df484f831","unresolved":false,"context_lines":[{"line_number":332,"context_line":"                                                               **kwargs)"},{"line_number":333,"context_line":""},{"line_number":334,"context_line":"            # NOTE(boris-42): If you need specific operation for keystone v3"},{"line_number":335,"context_line":"            keystone_v3.KeystoneServiceV3(self.clients, self).domain_create()"},{"line_number":336,"context_line":""},{"line_number":337,"context_line":"            # NOTE(boris-42): One of the nice thing is that we can move"},{"line_number":338,"context_line":"            #                 initialization of services to __init__ method"}],"source_content_type":"text/x-rst","patch_set":25,"id":"9aed3d3a_16973791","line":335,"in_reply_to":"9aed3d3a_c59a6ec5","updated":"2016-02-26 12:35:32.000000000","message":"Wait, so you\u0027re saying that we should *not* test all supported API versions in our gate? If that\u0027s something you\u0027re honestly concerned about, then we should be able to make my proposal fail \"unit\" tests if we scope our unit slightly larger -- e.g., we mock out the entire keystone client and then call a scenario with each API version that it supports. Since we\u0027d be mocking out the client instead of the IdentityCommon object, then anything in the IdentityCommon that raised NotImplemented would be caught earlier. (TBH I think treating each scenario as a \"unit\" instead of each function would be better anyway, since some of our unit testing is pretty clearly implementation testing. So that\u0027d be a win-win.)\n\nSo if too much testing is a concern -- which seems strange given that a take-away from the Rally meeting Monday was to do more testing for better coverage -- then I think there are elegant ways to make things fail in unit tests.","commit_id":"af3826a480683c563ff0b2de4a39514b1922dc57"},{"author":{"_account_id":11748,"name":"Chris St. Pierre","email":"cstpierr@cisco.com","username":"stpierre"},"change_message_id":"c6232d3bb8f0bd0b491009ac91834872bb512441","unresolved":false,"context_lines":[{"line_number":332,"context_line":"                                                               **kwargs)"},{"line_number":333,"context_line":""},{"line_number":334,"context_line":"            # NOTE(boris-42): If you need specific operation for keystone v3"},{"line_number":335,"context_line":"            keystone_v3.KeystoneServiceV3(self.clients, self).domain_create()"},{"line_number":336,"context_line":""},{"line_number":337,"context_line":"            # NOTE(boris-42): One of the nice thing is that we can move"},{"line_number":338,"context_line":"            #                 initialization of services to __init__ method"}],"source_content_type":"text/x-rst","patch_set":25,"id":"bae84128_e6b58131","line":335,"in_reply_to":"bae84128_10837b99","updated":"2016-02-22 17:40:14.000000000","message":"I think I\u0027d prefer that common.Identity contained all methods, and the specific implementations raised NotImplementedError if they couldn\u0027t do it, for several reasons:\n\n* This code is ugly. It requires that the author select a specific API version, which isn\u0027t futureproof, and it requires creating two separate Keystone service objects even though we\u0027re talking to the same (unitary) keystone service.\n\n* This approach starts to get difficult when we have more than two API versions. For instance, if Keystone v4 includes the notion of domains, will domain_create() be added to common.Identity? If not, then the scenario author will be responsible for writing duplicated boilerplate code to select the correct keystone API version every time they need to deal with domains. If so -- for instance, if common.Identity.domain_create() raises NotImplementedError if Keystone v2 is selected -- then why not just do that now so that we\u0027re futureproof?\n\n* By making the common.Identity object stub out all methods, you still don\u0027t lose the ability to select a specific API version on the rare occasions where it\u0027s necessary. The code will still be ugly and you\u0027ll still need to construct an extra service object, but nothing is lost -- it\u0027s no worse than it would be under this organization.","commit_id":"af3826a480683c563ff0b2de4a39514b1922dc57"},{"author":{"_account_id":6172,"name":"Boris Pavlovic","email":"boris@pavlovic.me","username":"boris-42"},"change_message_id":"97edf0fb0cfb3d05dac27cf4765e5d0d866f7a99","unresolved":false,"context_lines":[{"line_number":332,"context_line":"                                                               **kwargs)"},{"line_number":333,"context_line":""},{"line_number":334,"context_line":"            # NOTE(boris-42): If you need specific operation for keystone v3"},{"line_number":335,"context_line":"            keystone_v3.KeystoneServiceV3(self.clients, self).domain_create()"},{"line_number":336,"context_line":""},{"line_number":337,"context_line":"            # NOTE(boris-42): One of the nice thing is that we can move"},{"line_number":338,"context_line":"            #                 initialization of services to __init__ method"}],"source_content_type":"text/x-rst","patch_set":25,"id":"bae84128_10837b99","line":335,"in_reply_to":"bae84128_30f2ff6f","updated":"2016-02-22 17:13:21.000000000","message":"and if you read the comment, we need specific method from specific version.","commit_id":"af3826a480683c563ff0b2de4a39514b1922dc57"},{"author":{"_account_id":11748,"name":"Chris St. Pierre","email":"cstpierr@cisco.com","username":"stpierre"},"change_message_id":"96bd58da98c2d8d1ed838002d1a4ecc0a2308b7e","unresolved":false,"context_lines":[{"line_number":332,"context_line":"                                                               **kwargs)"},{"line_number":333,"context_line":""},{"line_number":334,"context_line":"            # NOTE(boris-42): If you need specific operation for keystone v3"},{"line_number":335,"context_line":"            keystone_v3.KeystoneServiceV3(self.clients, self).domain_create()"},{"line_number":336,"context_line":""},{"line_number":337,"context_line":"            # NOTE(boris-42): One of the nice thing is that we can move"},{"line_number":338,"context_line":"            #                 initialization of services to __init__ method"}],"source_content_type":"text/x-rst","patch_set":25,"id":"9aed3d3a_a2d48047","line":335,"in_reply_to":"bae84128_3ea5e903","updated":"2016-02-25 17:05:50.000000000","message":"\u003e  * It doesn\u0027t require users to specify specific version\n\nGreat. Please demonstrate how this code could be rewritten to avoid use of keystone_v3.KeystoneServiceV3, since that\u0027s not clear. If it can\u0027t be, then it *does* require users (that is, scenario authors) to specify a version.\n\n    \u003e  * Actually it is not complicated. You can have common class for 3/4 versions \n\nThat\u0027s hardly an elegant solution, since it (at least theoretically) scales at 2^n - 1 classes for n versions. And that\u0027s not a merely theoretical concern, either; if we ever have to distinguish between API microversions, Nova already has 28 of them. (This is not an unrealistic concern; the name pattern work ran into a fairly significant snag over permissible names in Ironic, which were changed in a microversion. Distinguishing between Ironic API microversions would have made some of that work easier.) And it still breaks forward compatibility. If Keystone v4 supports domains, every line that references keystone_v3.KeystoneServiceV3 will need to be changed.\n\n    \u003e  * This is road to the hell, and why I had to block wrappers effort. Basically people will start using (they try) in common context (such as network) common services, thinking that it will work everywhere. And the thing that method is stub it will work well until we run \"integration\" testing for that specific sceanrio/context, which is called \"fail late\" and will produce zillons of mistakes in code \n\nThis is a fair point, but that\u0027s why we have integration testing. It should produce zero mistakes in merged code.\n\n    \u003e It will hard to find what are the common methods, and what are the specific for some version. If you want to work with specific version use the class that works with specific version.\n\nIf this is hard to do once, why won\u0027t it be hard to do every time you have to call a method? With the methods spread out over 2^n - 1 classes, every time I call a method I\u0027ll need to grep through the service classes, figure out which one(s) support the method I want to call, potentially instantiate a new object for that version, and call the correct method. (And not only will I need to do that, but new contributors will, too.) That sounds much more difficult than finding out the common methods once.\n\nAnd, given that your solution involves generating common classes for each combination of API versions, we\u0027ll *still* need to figure out common and specific methods -- in fact, we\u0027ll need to do it more, since we\u0027ll need to compare each pair of API versions.\n\nI think it\u0027s worth doing a little thought exercise here. Let\u0027s imagine that Keystone v4 has been released. Under your plan, we\u0027ll need to:\n\n* Create new IdentityCommon23, IdentityCommon34, and KeystoneServiceV4 classes\n* Figure out what API calls are new in Keystone v4, and add them to KeystoneServiceV4\n* Figure out if there are any API calls that were in Keystone v2, removed in Keystone v3, and restored in Keystone v4; create a IdentityCommon24 and add them there.\n* Figure out what API calls have been removed in Keystone v4. With that list:\n  * If the call was in Keystone v2 and v3, move it from common.Identity to IdentityCommon23\n  * If the call was only in Keystone v3, do nothing.\n* Figure out which calls exist in Keystone v4 and Keystone v3 but not in Keystone v2, and add them to IdentityCommon34\n* Figure out what API calls have been changed in Keystone v4 and abstract around the change in the appropriate IdentityCommon* class\n* Carefully consider and update (almost certainly in a non-mechanized fashion) each line of code that referenced IdentityCommon, KeystoneServiceV2, or KeystoneServiceV3 to use the new, correct class.\n* Provide backwards compatibility and deprecation logging for all of those changes.\n\nUnder my plan, we\u0027ll need to:\n\n* Run integration tests against Keystone v4. This will instantly tell us which Keystone v4 methods have been removed or changed, since forward compatibility Just Works.\n* Create a new _KeystoneV4 implementation for identity.Common.\n* Create new implementations of the removed methods that raise NotImplemented in _KeystoneV4\n* Either abstract around changed API calls in the IdentityCommon class, or, if the change was big enough, add a new implementation in _KeystoneV4\n* Figure out what API calls are new in Keystone v4 and add them to _KeystoneV4\n\nThere is no need to consider which methods are common, no need to change any scenario code. Backwards compatibility Just Works.\n\n    \u003e Nope it won\u0027t be hard. End users won\u0027t need to do this work in scenarios. For example, you can create IdentityCommon (which works in 2,3, 4) and IdentityCommon34 (which works only in 3 and 4), and have all functionality described in KesytoneV2, KeysoneV3, KeystoneV4.\n\nIn that case, it will only be hard to pick from among the classes (don\u0027t forget IdentityCommon23, and possibly even IdentityCommon24 -- and work it out if there are four supported versions, or 28 supported microversions!) and juggle all of the objects.\n\nI outlined what it would take to add support for a new API version earlier, but, in fairness, we shouldn\u0027t necessarily optimize for that. It\u0027s rare, after all. Writing new scenarios isn\u0027t, though. Let\u0027s look at some pseudocode:\n\n    identity \u003d common.Identity(self.clients, self)\n    identity.create_project(name, **kwargs)\n    identity.domain_create()\n\nEasy, straightforward. Works on Keystone v3, fails on Keystone v2, just like your example code. If Keystone v4 supports those calls, it automatically just works, unlike your example code.\n\nNow let\u0027s look at your code. Before that domain_create() line, the author needs to consider: W API version(s) does this call work in? Does it work the same in all API versions? These are small questions, but they need to be asked every time you make an API call. That approach pessimises for coding.","commit_id":"af3826a480683c563ff0b2de4a39514b1922dc57"},{"author":{"_account_id":9545,"name":"Andriy Kurilin","email":"andr.kurilin@gmail.com","username":"akurilin"},"change_message_id":"d09a9b77e94b6420c52401d51ca480a8715833a1","unresolved":false,"context_lines":[{"line_number":332,"context_line":"                                                               **kwargs)"},{"line_number":333,"context_line":""},{"line_number":334,"context_line":"            # NOTE(boris-42): If you need specific operation for keystone v3"},{"line_number":335,"context_line":"            keystone_v3.KeystoneServiceV3(self.clients, self).domain_create()"},{"line_number":336,"context_line":""},{"line_number":337,"context_line":"            # NOTE(boris-42): One of the nice thing is that we can move"},{"line_number":338,"context_line":"            #                 initialization of services to __init__ method"}],"source_content_type":"text/x-rst","patch_set":25,"id":"bae84128_30f2ff6f","line":335,"in_reply_to":"bae84128_b069ef27","updated":"2016-02-22 17:11:04.000000000","message":"because common.Identity will cut all v3 specific parameters from results.","commit_id":"af3826a480683c563ff0b2de4a39514b1922dc57"},{"author":{"_account_id":6172,"name":"Boris Pavlovic","email":"boris@pavlovic.me","username":"boris-42"},"change_message_id":"b39e7d9f37236354029574097a823c9c0ef626fd","unresolved":false,"context_lines":[{"line_number":332,"context_line":"                                                               **kwargs)"},{"line_number":333,"context_line":""},{"line_number":334,"context_line":"            # NOTE(boris-42): If you need specific operation for keystone v3"},{"line_number":335,"context_line":"            keystone_v3.KeystoneServiceV3(self.clients, self).domain_create()"},{"line_number":336,"context_line":""},{"line_number":337,"context_line":"            # NOTE(boris-42): One of the nice thing is that we can move"},{"line_number":338,"context_line":"            #                 initialization of services to __init__ method"}],"source_content_type":"text/x-rst","patch_set":25,"id":"bae84128_3ea5e903","line":335,"in_reply_to":"bae84128_e6b58131","updated":"2016-02-25 15:55:54.000000000","message":"Some comments: \n\nAbout first point :\n  * This code is not ugly. \n  * It doesn\u0027t require users to specify specific version\n  * However user can set specific version (which allows us to use  api_version context with these services)\n\n\nAbout \"This approach starts to get difficult when we have more than two API versions:\"\n\n  * Actually it is not complicated. You can have common class for 3/4 versions \n\n\nAbout \"By making the common.Identity object stub out all methods, you still don\u0027t lose the ability to select a specific API version on the rare occasions where it\u0027s necessary. \"\n\n  * This is road to the hell, and why I had to block wrappers effort. Basically people will start using (they try) in common context (such as network) common services, thinking that it will work everywhere. And the thing that method is stub it will work well until we run \"integration\" testing for that specific sceanrio/context, which is called \"fail late\" and will produce zillons of mistakes in code \n\n* It will hard to find what are the common methods, and what are the specific for some version. If you want to work with specific version use the class that works with specific version. \n\n\nAbout \" if Keystone v4 includes the notion of domains, will domain_create() be added to common.Identity? If not, then the scenario author will be responsible for writing duplicated boilerplate code to select the correct keystone API version every time they need to deal with domains. If so -- for instance, if \"\n\n* Nope it won\u0027t be hard. End users won\u0027t need to do this work in scenarios. For example, you can create IdentityCommon (which works in 2,3, 4) and IdentityCommon34 (which works only in 3 and 4), and have all functionality described in KesytoneV2, KeysoneV3, KeystoneV4.","commit_id":"af3826a480683c563ff0b2de4a39514b1922dc57"}]}
