)]}'
{"/COMMIT_MSG":[{"author":{"_account_id":15197,"name":"Pierre Riteau","email":"pierre@stackhpc.com","username":"priteau","status":"StackHPC"},"change_message_id":"1a4a7b5f07e33e88eba91d80ab527b3458b78969","unresolved":false,"context_lines":[{"line_number":6,"context_line":""},{"line_number":7,"context_line":"Add ability to run playbooks before and after a kayobe command"},{"line_number":8,"context_line":""},{"line_number":9,"context_line":"Sometimes there is a need to develop site specific playbooks. Currently,"},{"line_number":10,"context_line":"it is necessary to manually invoke these at the right point during the"},{"line_number":11,"context_line":"deployment. Adding the ability to automatically run these custom playbooks"},{"line_number":12,"context_line":"will reduce the chance of running these playbooks at the wrong point or"},{"line_number":13,"context_line":"forgetting to run them at all."},{"line_number":14,"context_line":""},{"line_number":15,"context_line":"Change-Id: I1ae0f1f94665925326c8b1869dd75038f6f1b87d"},{"line_number":16,"context_line":"Story: 2001663"}],"source_content_type":"text/x-gerrit-commit-message","patch_set":4,"id":"1f493fa4_78558af9","line":13,"range":{"start_line":9,"start_character":0,"end_line":13,"end_character":30},"updated":"2020-05-01 15:40:44.000000000","message":"Nit: wrap lines","commit_id":"2af499b7616d28668b93cf51de64ee1d90e3cec5"}],"doc/source/custom-ansible-playbooks.rst":[{"author":{"_account_id":14826,"name":"Mark Goddard","email":"markgoddard86@gmail.com","username":"mgoddard"},"change_message_id":"4b2be7bcea8431274bfafb5f4bbe6cee5b7ce3e5","unresolved":false,"context_lines":[{"line_number":128,"context_line":"    Hooks are an experimental feature and the design could change in the future."},{"line_number":129,"context_line":"    You may have to update your config if there are any changes to the design."},{"line_number":130,"context_line":"    This warning will be removed when the design has been stabilised."},{"line_number":131,"context_line":""},{"line_number":132,"context_line":"Hooks are created by symlinking an existing playbook into the the relavent directory under"},{"line_number":133,"context_line":"``KAYOBE_CONFIG_PATH/hooks``. Kayobe will search the hooks directory for sub-directories"},{"line_number":134,"context_line":"matching ``\u003ccommand\u003e.\u003ctarget\u003e.d```, where ``command`` is the name of a kayobe command"}],"source_content_type":"text/x-rst","patch_set":6,"id":"1f493fa4_3b9dbcbb","line":131,"updated":"2020-05-01 16:25:56.000000000","message":"It probably needs a sentence to describe what this is trying to achieve.","commit_id":"22b31c6dc1840c7da480fd556e1b4ce733e05774"},{"author":{"_account_id":14826,"name":"Mark Goddard","email":"markgoddard86@gmail.com","username":"mgoddard"},"change_message_id":"4b2be7bcea8431274bfafb5f4bbe6cee5b7ce3e5","unresolved":false,"context_lines":[{"line_number":132,"context_line":"Hooks are created by symlinking an existing playbook into the the relavent directory under"},{"line_number":133,"context_line":"``KAYOBE_CONFIG_PATH/hooks``. Kayobe will search the hooks directory for sub-directories"},{"line_number":134,"context_line":"matching ``\u003ccommand\u003e.\u003ctarget\u003e.d```, where ``command`` is the name of a kayobe command"},{"line_number":135,"context_line":"with any spaces replaced with dashes, and ``target`` is a one of the supported targets for"},{"line_number":136,"context_line":"the command. Currently only the ``pre`` and ``post`` targets are supported. These are"},{"line_number":137,"context_line":"available for every command. Additional targets may be added in the future to support"},{"line_number":138,"context_line":"running hooks mid-command."}],"source_content_type":"text/x-rst","patch_set":6,"id":"1f493fa4_9bab30d4","line":135,"range":{"start_line":135,"start_character":56,"end_line":135,"end_character":58},"updated":"2020-05-01 16:25:56.000000000","message":"remove","commit_id":"22b31c6dc1840c7da480fd556e1b4ce733e05774"},{"author":{"_account_id":14826,"name":"Mark Goddard","email":"markgoddard86@gmail.com","username":"mgoddard"},"change_message_id":"453353b812d1a6bddc72b3f29a1de0c9e45ddd26","unresolved":false,"context_lines":[{"line_number":122,"context_line":"    (kayobe) $ kayobe playbook run $KAYOBE_CONFIG_PATH/ansible/foo.yml"},{"line_number":123,"context_line":""},{"line_number":124,"context_line":"Hooks"},{"line_number":125,"context_line":"\u003d\u003d\u003d\u003d\u003d"},{"line_number":126,"context_line":""},{"line_number":127,"context_line":".. warning::"},{"line_number":128,"context_line":"    Hooks are an experimental feature and the design could change in the future."}],"source_content_type":"text/x-rst","patch_set":7,"id":"ff570b3c_be64bae5","line":125,"updated":"2020-05-14 13:37:40.000000000","message":"Docs looking good. Could you say something about failure handling - what happens if a hook fails? What happens to remaining hooks if a command fails?","commit_id":"06fe76e13789fc8f2925e1293a0adf37e4d97504"},{"author":{"_account_id":14826,"name":"Mark Goddard","email":"markgoddard86@gmail.com","username":"mgoddard"},"change_message_id":"453353b812d1a6bddc72b3f29a1de0c9e45ddd26","unresolved":false,"context_lines":[{"line_number":134,"context_line":"as a ``target``. Please see the :ref:`list of available targets\u003cHook Targets\u003e`."},{"line_number":135,"context_line":""},{"line_number":136,"context_line":"Hooks are created by symlinking an existing playbook into the the relevant directory under"},{"line_number":137,"context_line":"``KAYOBE_CONFIG_PATH/hooks``. Kayobe will search the hooks directory for sub-directories"},{"line_number":138,"context_line":"matching ``\u003ccommand\u003e.\u003ctarget\u003e.d``, where ``command`` is the name of a kayobe command"},{"line_number":139,"context_line":"with any spaces replaced with dashes, and ``target`` is one of the supported targets for"},{"line_number":140,"context_line":"the command."}],"source_content_type":"text/x-rst","patch_set":7,"id":"ff570b3c_db4f0090","line":137,"range":{"start_line":137,"start_character":2,"end_line":137,"end_character":20},"updated":"2020-05-14 13:37:40.000000000","message":"$KAYOBE_CONFIG_PATH","commit_id":"06fe76e13789fc8f2925e1293a0adf37e4d97504"},{"author":{"_account_id":14826,"name":"Mark Goddard","email":"markgoddard86@gmail.com","username":"mgoddard"},"change_message_id":"453353b812d1a6bddc72b3f29a1de0c9e45ddd26","unresolved":false,"context_lines":[{"line_number":145,"context_line":""},{"line_number":146,"context_line":"kayobe will search the paths:"},{"line_number":147,"context_line":""},{"line_number":148,"context_line":"- ``KAYOBE_CONFIG_PATH/hooks/control-host-bootstrap/pre.d``"},{"line_number":149,"context_line":"- ``KAYOBE_CONFIG_PATH/hooks/control-host-bootstrap/post.d``"},{"line_number":150,"context_line":""},{"line_number":151,"context_line":"Any playbooks listed under the ``pre.d`` directory will be run before kayobe executes"}],"source_content_type":"text/x-rst","patch_set":7,"id":"ff570b3c_bb5a0c4c","line":148,"updated":"2020-05-14 13:37:40.000000000","message":"$","commit_id":"06fe76e13789fc8f2925e1293a0adf37e4d97504"},{"author":{"_account_id":14826,"name":"Mark Goddard","email":"markgoddard86@gmail.com","username":"mgoddard"},"change_message_id":"453353b812d1a6bddc72b3f29a1de0c9e45ddd26","unresolved":false,"context_lines":[{"line_number":146,"context_line":"kayobe will search the paths:"},{"line_number":147,"context_line":""},{"line_number":148,"context_line":"- ``KAYOBE_CONFIG_PATH/hooks/control-host-bootstrap/pre.d``"},{"line_number":149,"context_line":"- ``KAYOBE_CONFIG_PATH/hooks/control-host-bootstrap/post.d``"},{"line_number":150,"context_line":""},{"line_number":151,"context_line":"Any playbooks listed under the ``pre.d`` directory will be run before kayobe executes"},{"line_number":152,"context_line":"its own playbooks and any playbooks under ``post.d`` will be run after. You can affect"}],"source_content_type":"text/x-rst","patch_set":7,"id":"ff570b3c_fb31240d","line":149,"updated":"2020-05-14 13:37:40.000000000","message":"$","commit_id":"06fe76e13789fc8f2925e1293a0adf37e4d97504"},{"author":{"_account_id":15197,"name":"Pierre Riteau","email":"pierre@stackhpc.com","username":"priteau","status":"StackHPC"},"change_message_id":"5d049504257d5ecd1c2c25deec85a0f5b79d9661","unresolved":false,"context_lines":[{"line_number":149,"context_line":"- ``$KAYOBE_CONFIG_PATH/hooks/control-host-bootstrap/post.d``"},{"line_number":150,"context_line":""},{"line_number":151,"context_line":"Any playbooks listed under the ``pre.d`` directory will be run before kayobe executes"},{"line_number":152,"context_line":"its own playbooks and any playbooks under ``post.d`` will be run after. You can affect"},{"line_number":153,"context_line":"the order of the playbooks by prefixing the symlink with a sequence number. Playbooks"},{"line_number":154,"context_line":"with smaller sequence numbers are run before playbooks with larger ones. Any ties are"},{"line_number":155,"context_line":"broken by alphabetical ordering."},{"line_number":156,"context_line":""}],"source_content_type":"text/x-rst","patch_set":8,"id":"ff570b3c_f51fcf06","line":153,"range":{"start_line":152,"start_character":72,"end_line":153,"end_character":75},"updated":"2020-05-22 13:17:39.000000000","message":"We should make it clear that the prefix should be composed of the number *and* a dash. The current working is ambiguous.","commit_id":"6bedb43a7b1dd05e9bc86b6e70bc700a8e0191fe"},{"author":{"_account_id":15197,"name":"Pierre Riteau","email":"pierre@stackhpc.com","username":"priteau","status":"StackHPC"},"change_message_id":"5d049504257d5ecd1c2c25deec85a0f5b79d9661","unresolved":false,"context_lines":[{"line_number":181,"context_line":"        fail:"},{"line_number":182,"context_line":"        ignore_errors: true"},{"line_number":183,"context_line":""},{"line_number":184,"context_line":"A failure in the ``Deliberately fail`` task would not prevent subseqent tasks, hooks,"},{"line_number":185,"context_line":"and playbooks from running."},{"line_number":186,"context_line":""},{"line_number":187,"context_line":".. _Hook Targets:"}],"source_content_type":"text/x-rst","patch_set":8,"id":"ff570b3c_7a172e53","line":184,"range":{"start_line":184,"start_character":62,"end_line":184,"end_character":71},"updated":"2020-05-22 13:17:39.000000000","message":"subsequent","commit_id":"6bedb43a7b1dd05e9bc86b6e70bc700a8e0191fe"}],"kayobe/cli/commands.py":[{"author":{"_account_id":28048,"name":"Will Szumski","email":"will@stackhpc.com","username":"jovial"},"change_message_id":"533a63c4a42570e75316e05109a8aa2028e8cf3e","unresolved":false,"context_lines":[{"line_number":173,"context_line":"            return []"},{"line_number":174,"context_line":"        # Hooks can be prefixed with priority to adjust order, e.g"},{"line_number":175,"context_line":"        # 10-my-custom-playbook.yml."},{"line_number":176,"context_line":"        hooks \u003d sorted(glob.glob(os.path.join(path, \"*.yml\")))"},{"line_number":177,"context_line":"        # Resolve symlinks so that we can reference roles."},{"line_number":178,"context_line":"        hooks \u003d [os.path.realpath(hook) for hook in hooks]"},{"line_number":179,"context_line":"        self.logger.debug(f\"Discovered the following hooks: {hooks}\")"}],"source_content_type":"text/x-python","patch_set":1,"id":"1f493fa4_6db793f6","line":176,"updated":"2020-05-01 10:58:33.000000000","message":"This sorts lexicographically. Probably need something custom to sort via prefix.","commit_id":"e733432a7a6cb715a3fa042b683bb71f1b4cd894"},{"author":{"_account_id":14826,"name":"Mark Goddard","email":"markgoddard86@gmail.com","username":"mgoddard"},"change_message_id":"4b2be7bcea8431274bfafb5f4bbe6cee5b7ce3e5","unresolved":false,"context_lines":[{"line_number":158,"context_line":"        return (DEFAULT_HOOK_PRIORITY, hook)"},{"line_number":159,"context_line":""},{"line_number":160,"context_line":""},{"line_number":161,"context_line":"class HookDispatcher(object):"},{"line_number":162,"context_line":"    \"\"\"stevedore extension that runs pre and post hooks for each command\"\"\""},{"line_number":163,"context_line":""},{"line_number":164,"context_line":"# Order of calls: get_epilog, get_parser, before, after"}],"source_content_type":"text/x-python","patch_set":4,"id":"1f493fa4_58b9ae76","line":161,"range":{"start_line":161,"start_character":6,"end_line":161,"end_character":20},"updated":"2020-05-01 16:25:56.000000000","message":"Why not subclass cliff.hooks.CommandHook?","commit_id":"2af499b7616d28668b93cf51de64ee1d90e3cec5"},{"author":{"_account_id":14826,"name":"Mark Goddard","email":"markgoddard86@gmail.com","username":"mgoddard"},"change_message_id":"4b2be7bcea8431274bfafb5f4bbe6cee5b7ce3e5","unresolved":false,"context_lines":[{"line_number":174,"context_line":"        # Strip the leading kayobe, and replace white space with dashes for"},{"line_number":175,"context_line":"        # consistency with ansible playbooks."},{"line_number":176,"context_line":"        # Example prog_name: kayobe control host bootstrap"},{"line_number":177,"context_line":"        self.name \u003d \"-\".join(prog_name.prog.split()[1:])"},{"line_number":178,"context_line":""},{"line_number":179,"context_line":"    def _find_hooks(self, config_path, target):"},{"line_number":180,"context_line":"        name \u003d self.name"}],"source_content_type":"text/x-python","patch_set":6,"id":"1f493fa4_b826f2cc","line":177,"range":{"start_line":177,"start_character":13,"end_line":177,"end_character":17},"updated":"2020-05-01 16:25:56.000000000","message":"Is this accessible via self.command.cmd_name?","commit_id":"22b31c6dc1840c7da480fd556e1b4ce733e05774"},{"author":{"_account_id":14826,"name":"Mark Goddard","email":"markgoddard86@gmail.com","username":"mgoddard"},"change_message_id":"4b2be7bcea8431274bfafb5f4bbe6cee5b7ce3e5","unresolved":false,"context_lines":[{"line_number":207,"context_line":"        return parsed_args"},{"line_number":208,"context_line":""},{"line_number":209,"context_line":"    def after(self, parsed_args, return_code):"},{"line_number":210,"context_line":"        self.run_hooks(parsed_args, \"post\")"},{"line_number":211,"context_line":"        return return_code"},{"line_number":212,"context_line":""},{"line_number":213,"context_line":""}],"source_content_type":"text/x-python","patch_set":6,"id":"1f493fa4_181f266c","line":210,"updated":"2020-05-01 16:25:56.000000000","message":"Should the hook run if the return code is non-zero?","commit_id":"22b31c6dc1840c7da480fd556e1b4ce733e05774"}],"kayobe/tests/unit/cli/test_commands.py":[{"author":{"_account_id":14826,"name":"Mark Goddard","email":"markgoddard86@gmail.com","username":"mgoddard"},"change_message_id":"4b2be7bcea8431274bfafb5f4bbe6cee5b7ce3e5","unresolved":false,"context_lines":[{"line_number":1987,"context_line":"            \"no-prefix.yml\""},{"line_number":1988,"context_line":"        ]"},{"line_number":1989,"context_line":"        expected_result \u003d ["},{"line_number":1990,"context_line":"            \"5-hook.yml\","},{"line_number":1991,"context_line":"            \"10-before-hook.yml\","},{"line_number":1992,"context_line":"            \"10-hook.yml\","},{"line_number":1993,"context_line":"            \"no-prefix.yml\","}],"source_content_type":"text/x-python","patch_set":6,"id":"1f493fa4_5b58882f","line":1990,"updated":"2020-05-01 16:25:56.000000000","message":"Higher numbers should execute first?","commit_id":"22b31c6dc1840c7da480fd556e1b4ce733e05774"},{"author":{"_account_id":14826,"name":"Mark Goddard","email":"markgoddard86@gmail.com","username":"mgoddard"},"change_message_id":"4b2be7bcea8431274bfafb5f4bbe6cee5b7ce3e5","unresolved":false,"context_lines":[{"line_number":1991,"context_line":"            \"10-before-hook.yml\","},{"line_number":1992,"context_line":"            \"10-hook.yml\","},{"line_number":1993,"context_line":"            \"no-prefix.yml\","},{"line_number":1994,"context_line":"            \"%s-hook.yml\" % greater_than_default_priority,"},{"line_number":1995,"context_line":"        ]"},{"line_number":1996,"context_line":"        mock_path.realpath.side_effect \u003d lambda x: x"},{"line_number":1997,"context_line":"        actual \u003d dispatcher.hooks(\"config/path\", \"pre\")"}],"source_content_type":"text/x-python","patch_set":6,"id":"1f493fa4_9b3df0bc","line":1994,"updated":"2020-05-01 16:25:56.000000000","message":"I don\u0027t see where this logic lives (or if it makes sense)","commit_id":"22b31c6dc1840c7da480fd556e1b4ce733e05774"}]}
