)]}'
{"/COMMIT_MSG":[{"author":{"_account_id":6618,"name":"Ruby Loo","email":"opensrloo@gmail.com","username":"rloo"},"change_message_id":"f87e79e85f96c7ea669ff59ad216b6533d909ba2","unresolved":false,"context_lines":[{"line_number":8,"context_line":""},{"line_number":9,"context_line":"This patch adds \"ironic create\" and \"openstack create\" commands"},{"line_number":10,"context_line":"understanding JSON and YAML files, documentation for it will be"},{"line_number":11,"context_line":"added in the further patches."},{"line_number":12,"context_line":""},{"line_number":13,"context_line":"Partial-bug: #1588339"},{"line_number":14,"context_line":"Co-Authored-By: Lucas Alvares Gomes \u003clucasagomes@gmail.com\u003e"}],"source_content_type":"text/x-gerrit-commit-message","patch_set":13,"id":"1aa78d24_af95f187","line":11,"updated":"2016-07-06 17:47:29.000000000","message":"s/the further patches/a subsequent patch/ ?","commit_id":"dc667add6327de0cf912e87f70f2b1ba76897acd"},{"author":{"_account_id":12356,"name":"Vladyslav Drok","email":"vdrok@mirantis.com","username":"vdrok"},"change_message_id":"4dd7c6e39b91060ba669c6cbfa0ab0771e9a9a57","unresolved":false,"context_lines":[{"line_number":8,"context_line":""},{"line_number":9,"context_line":"This patch adds \"ironic create\" and \"openstack create\" commands"},{"line_number":10,"context_line":"understanding JSON and YAML files, documentation for it will be"},{"line_number":11,"context_line":"added in the further patches."},{"line_number":12,"context_line":""},{"line_number":13,"context_line":"Partial-bug: #1588339"},{"line_number":14,"context_line":"Co-Authored-By: Lucas Alvares Gomes \u003clucasagomes@gmail.com\u003e"}],"source_content_type":"text/x-gerrit-commit-message","patch_set":13,"id":"1aa78d24_44da394c","line":11,"in_reply_to":"1aa78d24_af95f187","updated":"2016-07-13 13:00:21.000000000","message":"Done","commit_id":"dc667add6327de0cf912e87f70f2b1ba76897acd"}],"ironicclient/osc/v1/baremetal_create.py":[{"author":{"_account_id":12356,"name":"Vladyslav Drok","email":"vdrok@mirantis.com","username":"vdrok"},"change_message_id":"98e5df1019ab0a79a368680dec6e0f58e9a70b7f","unresolved":false,"context_lines":[{"line_number":19,"context_line":"from ironicclient.v1 import create_resources"},{"line_number":20,"context_line":""},{"line_number":21,"context_line":""},{"line_number":22,"context_line":"class CreateBaremetal(baremetal_node.CreateBaremetalNode):"},{"line_number":23,"context_line":"    \"\"\"Register a new node (DEPRECATED) or create resources from files\"\"\""},{"line_number":24,"context_line":""},{"line_number":25,"context_line":"    log \u003d logging.getLogger(__name__ + \".CreateBaremetal\")"}],"source_content_type":"text/x-python","patch_set":11,"id":"3aaa91ec_1dfcb471","line":22,"updated":"2016-07-01 17:44:49.000000000","message":"Add unittests for it.","commit_id":"24fa7f5565d90c755035493c908baa3513f7aeed"},{"author":{"_account_id":12356,"name":"Vladyslav Drok","email":"vdrok@mirantis.com","username":"vdrok"},"change_message_id":"6b254eb500a8a9e9989c6cd0ef1d741b1988532a","unresolved":false,"context_lines":[{"line_number":19,"context_line":"from ironicclient.v1 import create_resources"},{"line_number":20,"context_line":""},{"line_number":21,"context_line":""},{"line_number":22,"context_line":"class CreateBaremetal(baremetal_node.CreateBaremetalNode):"},{"line_number":23,"context_line":"    \"\"\"Register a new node (DEPRECATED) or create resources from files\"\"\""},{"line_number":24,"context_line":""},{"line_number":25,"context_line":"    log \u003d logging.getLogger(__name__ + \".CreateBaremetal\")"}],"source_content_type":"text/x-python","patch_set":11,"id":"1aa78d24_f9ca6c4e","line":22,"in_reply_to":"3aaa91ec_1dfcb471","updated":"2016-07-04 16:37:07.000000000","message":"Done","commit_id":"24fa7f5565d90c755035493c908baa3513f7aeed"},{"author":{"_account_id":12356,"name":"Vladyslav Drok","email":"vdrok@mirantis.com","username":"vdrok"},"change_message_id":"98e5df1019ab0a79a368680dec6e0f58e9a70b7f","unresolved":false,"context_lines":[{"line_number":52,"context_line":"                \"a list of .json or .yaml files, but no files were provided.\"))"},{"line_number":53,"context_line":"        create_resources.create_resources(self.app.client_manager.baremetal,"},{"line_number":54,"context_line":"                                          parsed_args.resource_files)"},{"line_number":55,"context_line":"        return [], None"}],"source_content_type":"text/x-python","patch_set":11,"id":"3aaa91ec_bd064083","line":55,"updated":"2016-07-01 17:44:49.000000000","message":"Add a comment why this return is needed.","commit_id":"24fa7f5565d90c755035493c908baa3513f7aeed"},{"author":{"_account_id":12356,"name":"Vladyslav Drok","email":"vdrok@mirantis.com","username":"vdrok"},"change_message_id":"6b254eb500a8a9e9989c6cd0ef1d741b1988532a","unresolved":false,"context_lines":[{"line_number":52,"context_line":"                \"a list of .json or .yaml files, but no files were provided.\"))"},{"line_number":53,"context_line":"        create_resources.create_resources(self.app.client_manager.baremetal,"},{"line_number":54,"context_line":"                                          parsed_args.resource_files)"},{"line_number":55,"context_line":"        return [], None"}],"source_content_type":"text/x-python","patch_set":11,"id":"1aa78d24_ca723de5","line":55,"in_reply_to":"3aaa91ec_bd064083","updated":"2016-07-04 16:37:07.000000000","message":"Done","commit_id":"24fa7f5565d90c755035493c908baa3513f7aeed"},{"author":{"_account_id":6618,"name":"Ruby Loo","email":"opensrloo@gmail.com","username":"rloo"},"change_message_id":"f87e79e85f96c7ea669ff59ad216b6533d909ba2","unresolved":false,"context_lines":[{"line_number":20,"context_line":""},{"line_number":21,"context_line":""},{"line_number":22,"context_line":"class CreateBaremetal(baremetal_node.CreateBaremetalNode):"},{"line_number":23,"context_line":"    \"\"\"Register a new node (DEPRECATED) or create resources from files\"\"\""},{"line_number":24,"context_line":""},{"line_number":25,"context_line":"    log \u003d logging.getLogger(__name__ + \".CreateBaremetal\")"},{"line_number":26,"context_line":""}],"source_content_type":"text/x-python","patch_set":13,"id":"1aa78d24_91a2ae97","line":23,"updated":"2016-07-06 17:47:29.000000000","message":"I would reverse this and elaborate more, eg: \u0027Create resources from files (by only specifying the files) or register a new node by specifying one or more optional arguments (DEPRECATED; use \u0027openstack baremetal node create instead))\u0027.\n\nI did a \u0027openstack help baremetal create\u0027 and it didn\u0027t show this string. Not sure why.","commit_id":"dc667add6327de0cf912e87f70f2b1ba76897acd"},{"author":{"_account_id":12356,"name":"Vladyslav Drok","email":"vdrok@mirantis.com","username":"vdrok"},"change_message_id":"4dd7c6e39b91060ba669c6cbfa0ab0771e9a9a57","unresolved":false,"context_lines":[{"line_number":20,"context_line":""},{"line_number":21,"context_line":""},{"line_number":22,"context_line":"class CreateBaremetal(baremetal_node.CreateBaremetalNode):"},{"line_number":23,"context_line":"    \"\"\"Register a new node (DEPRECATED) or create resources from files\"\"\""},{"line_number":24,"context_line":""},{"line_number":25,"context_line":"    log \u003d logging.getLogger(__name__ + \".CreateBaremetal\")"},{"line_number":26,"context_line":""}],"source_content_type":"text/x-python","patch_set":13,"id":"1aa78d24_79224e53","line":23,"in_reply_to":"1aa78d24_11877ad8","updated":"2016-07-13 13:00:21.000000000","message":"Done","commit_id":"dc667add6327de0cf912e87f70f2b1ba76897acd"},{"author":{"_account_id":6773,"name":"Lucas Alvares Gomes","email":"lucasagomes@gmail.com","username":"lucasagomes"},"change_message_id":"5c25242c1949b294ec4cd62d858be7dedf55e4e9","unresolved":false,"context_lines":[{"line_number":20,"context_line":""},{"line_number":21,"context_line":""},{"line_number":22,"context_line":"class CreateBaremetal(baremetal_node.CreateBaremetalNode):"},{"line_number":23,"context_line":"    \"\"\"Register a new node (DEPRECATED) or create resources from files\"\"\""},{"line_number":24,"context_line":""},{"line_number":25,"context_line":"    log \u003d logging.getLogger(__name__ + \".CreateBaremetal\")"},{"line_number":26,"context_line":""}],"source_content_type":"text/x-python","patch_set":13,"id":"1aa78d24_11877ad8","line":23,"in_reply_to":"1aa78d24_91a2ae97","updated":"2016-07-08 08:35:19.000000000","message":"+1 for the docstring\n\nand yes, we should make sure that the user sees the deprecation message","commit_id":"dc667add6327de0cf912e87f70f2b1ba76897acd"},{"author":{"_account_id":6618,"name":"Ruby Loo","email":"opensrloo@gmail.com","username":"rloo"},"change_message_id":"f87e79e85f96c7ea669ff59ad216b6533d909ba2","unresolved":false,"context_lines":[{"line_number":21,"context_line":""},{"line_number":22,"context_line":"class CreateBaremetal(baremetal_node.CreateBaremetalNode):"},{"line_number":23,"context_line":"    \"\"\"Register a new node (DEPRECATED) or create resources from files\"\"\""},{"line_number":24,"context_line":""},{"line_number":25,"context_line":"    log \u003d logging.getLogger(__name__ + \".CreateBaremetal\")"},{"line_number":26,"context_line":""},{"line_number":27,"context_line":"    def get_parser(self, prog_name):"}],"source_content_type":"text/x-python","patch_set":13,"id":"1aa78d24_314c9a9d","line":24,"updated":"2016-07-06 17:47:29.000000000","message":"Could you put back the TODO that was there, so we remember to delete the node-creation stuff. eg:\n\nTODO(thrash or vdrok): Remove support for new node creation in the \u0027P\u0027 cycle.","commit_id":"dc667add6327de0cf912e87f70f2b1ba76897acd"},{"author":{"_account_id":12356,"name":"Vladyslav Drok","email":"vdrok@mirantis.com","username":"vdrok"},"change_message_id":"4dd7c6e39b91060ba669c6cbfa0ab0771e9a9a57","unresolved":false,"context_lines":[{"line_number":21,"context_line":""},{"line_number":22,"context_line":"class CreateBaremetal(baremetal_node.CreateBaremetalNode):"},{"line_number":23,"context_line":"    \"\"\"Register a new node (DEPRECATED) or create resources from files\"\"\""},{"line_number":24,"context_line":""},{"line_number":25,"context_line":"    log \u003d logging.getLogger(__name__ + \".CreateBaremetal\")"},{"line_number":26,"context_line":""},{"line_number":27,"context_line":"    def get_parser(self, prog_name):"}],"source_content_type":"text/x-python","patch_set":13,"id":"1aa78d24_19b50aec","line":24,"in_reply_to":"1aa78d24_314c9a9d","updated":"2016-07-13 13:00:21.000000000","message":"Done","commit_id":"dc667add6327de0cf912e87f70f2b1ba76897acd"},{"author":{"_account_id":6618,"name":"Ruby Loo","email":"opensrloo@gmail.com","username":"rloo"},"change_message_id":"f87e79e85f96c7ea669ff59ad216b6533d909ba2","unresolved":false,"context_lines":[{"line_number":34,"context_line":"        parser.add_argument("},{"line_number":35,"context_line":"            \u0027--driver\u0027,"},{"line_number":36,"context_line":"            metavar\u003d\u0027\u003cdriver\u003e\u0027,"},{"line_number":37,"context_line":"            help\u003d\u0027Driver used to control the node.\u0027)"},{"line_number":38,"context_line":"        parser.add_argument("},{"line_number":39,"context_line":"            \"resource_files\", metavar\u003d\"\u003cfile\u003e\", default\u003d[], nargs\u003d\"*\","},{"line_number":40,"context_line":"            help\u003d\"File(s) containing descriptions of the resources to create\")"}],"source_content_type":"text/x-python","patch_set":13,"id":"1aa78d24_54a2f44b","line":37,"updated":"2016-07-06 17:47:29.000000000","message":"Maybe \u0027Specify this and any other optional arguments if you want to create a node only. Note that this is deprecated; please use \u0027openstack baremetal node create\u0027 instead.\u0027","commit_id":"dc667add6327de0cf912e87f70f2b1ba76897acd"},{"author":{"_account_id":6773,"name":"Lucas Alvares Gomes","email":"lucasagomes@gmail.com","username":"lucasagomes"},"change_message_id":"5c25242c1949b294ec4cd62d858be7dedf55e4e9","unresolved":false,"context_lines":[{"line_number":34,"context_line":"        parser.add_argument("},{"line_number":35,"context_line":"            \u0027--driver\u0027,"},{"line_number":36,"context_line":"            metavar\u003d\u0027\u003cdriver\u003e\u0027,"},{"line_number":37,"context_line":"            help\u003d\u0027Driver used to control the node.\u0027)"},{"line_number":38,"context_line":"        parser.add_argument("},{"line_number":39,"context_line":"            \"resource_files\", metavar\u003d\"\u003cfile\u003e\", default\u003d[], nargs\u003d\"*\","},{"line_number":40,"context_line":"            help\u003d\"File(s) containing descriptions of the resources to create\")"}],"source_content_type":"text/x-python","patch_set":13,"id":"1aa78d24_f15e2e78","line":37,"in_reply_to":"1aa78d24_54a2f44b","updated":"2016-07-08 08:35:19.000000000","message":"Should we indicate here that the --driver parameter is deprecated in favor of \"baremetal node create\" ?","commit_id":"dc667add6327de0cf912e87f70f2b1ba76897acd"},{"author":{"_account_id":12356,"name":"Vladyslav Drok","email":"vdrok@mirantis.com","username":"vdrok"},"change_message_id":"4dd7c6e39b91060ba669c6cbfa0ab0771e9a9a57","unresolved":false,"context_lines":[{"line_number":34,"context_line":"        parser.add_argument("},{"line_number":35,"context_line":"            \u0027--driver\u0027,"},{"line_number":36,"context_line":"            metavar\u003d\u0027\u003cdriver\u003e\u0027,"},{"line_number":37,"context_line":"            help\u003d\u0027Driver used to control the node.\u0027)"},{"line_number":38,"context_line":"        parser.add_argument("},{"line_number":39,"context_line":"            \"resource_files\", metavar\u003d\"\u003cfile\u003e\", default\u003d[], nargs\u003d\"*\","},{"line_number":40,"context_line":"            help\u003d\"File(s) containing descriptions of the resources to create\")"}],"source_content_type":"text/x-python","patch_set":13,"id":"1aa78d24_7956ce5c","line":37,"in_reply_to":"1aa78d24_f15e2e78","updated":"2016-07-13 13:00:21.000000000","message":"Done","commit_id":"dc667add6327de0cf912e87f70f2b1ba76897acd"},{"author":{"_account_id":6618,"name":"Ruby Loo","email":"opensrloo@gmail.com","username":"rloo"},"change_message_id":"f87e79e85f96c7ea669ff59ad216b6533d909ba2","unresolved":false,"context_lines":[{"line_number":37,"context_line":"            help\u003d\u0027Driver used to control the node.\u0027)"},{"line_number":38,"context_line":"        parser.add_argument("},{"line_number":39,"context_line":"            \"resource_files\", metavar\u003d\"\u003cfile\u003e\", default\u003d[], nargs\u003d\"*\","},{"line_number":40,"context_line":"            help\u003d\"File(s) containing descriptions of the resources to create\")"},{"line_number":41,"context_line":"        return parser"},{"line_number":42,"context_line":""},{"line_number":43,"context_line":"    def take_action(self, parsed_args):"}],"source_content_type":"text/x-python","patch_set":13,"id":"1aa78d24_f1e332a2","line":40,"updated":"2016-07-06 17:47:29.000000000","message":"Maybe same string as from \u0027ironic create\u0027: \n\nFile (.yaml or .json) containing descriptions of the resources to create. Can be specified multiple times.\n\nI think we might actually want to add more to it. Maybe \u0027If you want to create resources, only specify the files. Do not specify any of the optional arguments.\u0027","commit_id":"dc667add6327de0cf912e87f70f2b1ba76897acd"},{"author":{"_account_id":12356,"name":"Vladyslav Drok","email":"vdrok@mirantis.com","username":"vdrok"},"change_message_id":"4dd7c6e39b91060ba669c6cbfa0ab0771e9a9a57","unresolved":false,"context_lines":[{"line_number":37,"context_line":"            help\u003d\u0027Driver used to control the node.\u0027)"},{"line_number":38,"context_line":"        parser.add_argument("},{"line_number":39,"context_line":"            \"resource_files\", metavar\u003d\"\u003cfile\u003e\", default\u003d[], nargs\u003d\"*\","},{"line_number":40,"context_line":"            help\u003d\"File(s) containing descriptions of the resources to create\")"},{"line_number":41,"context_line":"        return parser"},{"line_number":42,"context_line":""},{"line_number":43,"context_line":"    def take_action(self, parsed_args):"}],"source_content_type":"text/x-python","patch_set":13,"id":"1aa78d24_59d832ef","line":40,"in_reply_to":"1aa78d24_f1e332a2","updated":"2016-07-13 13:00:21.000000000","message":"Done","commit_id":"dc667add6327de0cf912e87f70f2b1ba76897acd"},{"author":{"_account_id":6618,"name":"Ruby Loo","email":"opensrloo@gmail.com","username":"rloo"},"change_message_id":"f87e79e85f96c7ea669ff59ad216b6533d909ba2","unresolved":false,"context_lines":[{"line_number":55,"context_line":"        # NOTE(vdrok): CreateBaremetal is still inherited from ShowOne class,"},{"line_number":56,"context_line":"        # which requires the return value of the function to be of certain"},{"line_number":57,"context_line":"        # type, leave this workaround until creation of nodes is removed and"},{"line_number":58,"context_line":"        # then change the base class to be just Command"},{"line_number":59,"context_line":"        return tuple(), tuple()"}],"source_content_type":"text/x-python","patch_set":13,"id":"1aa78d24_b1988ac1","line":58,"updated":"2016-07-06 17:47:29.000000000","message":"maybe s/change the base class to be just Command/change so that this inherits from command.Command/ ?","commit_id":"dc667add6327de0cf912e87f70f2b1ba76897acd"},{"author":{"_account_id":12356,"name":"Vladyslav Drok","email":"vdrok@mirantis.com","username":"vdrok"},"change_message_id":"4dd7c6e39b91060ba669c6cbfa0ab0771e9a9a57","unresolved":false,"context_lines":[{"line_number":55,"context_line":"        # NOTE(vdrok): CreateBaremetal is still inherited from ShowOne class,"},{"line_number":56,"context_line":"        # which requires the return value of the function to be of certain"},{"line_number":57,"context_line":"        # type, leave this workaround until creation of nodes is removed and"},{"line_number":58,"context_line":"        # then change the base class to be just Command"},{"line_number":59,"context_line":"        return tuple(), tuple()"}],"source_content_type":"text/x-python","patch_set":13,"id":"1aa78d24_79040e49","line":58,"in_reply_to":"1aa78d24_b1988ac1","updated":"2016-07-13 13:00:21.000000000","message":"Done","commit_id":"dc667add6327de0cf912e87f70f2b1ba76897acd"},{"author":{"_account_id":6618,"name":"Ruby Loo","email":"opensrloo@gmail.com","username":"rloo"},"change_message_id":"f87e79e85f96c7ea669ff59ad216b6533d909ba2","unresolved":false,"context_lines":[{"line_number":56,"context_line":"        # which requires the return value of the function to be of certain"},{"line_number":57,"context_line":"        # type, leave this workaround until creation of nodes is removed and"},{"line_number":58,"context_line":"        # then change the base class to be just Command"},{"line_number":59,"context_line":"        return tuple(), tuple()"}],"source_content_type":"text/x-python","patch_set":13,"id":"1aa78d24_f174d236","line":59,"updated":"2016-07-06 17:47:29.000000000","message":"Would there be a problem changing it so that it returns Nothing later? I think not, but I\u0027m not that familiar with this code.","commit_id":"dc667add6327de0cf912e87f70f2b1ba76897acd"},{"author":{"_account_id":12356,"name":"Vladyslav Drok","email":"vdrok@mirantis.com","username":"vdrok"},"change_message_id":"4dd7c6e39b91060ba669c6cbfa0ab0771e9a9a57","unresolved":false,"context_lines":[{"line_number":56,"context_line":"        # which requires the return value of the function to be of certain"},{"line_number":57,"context_line":"        # type, leave this workaround until creation of nodes is removed and"},{"line_number":58,"context_line":"        # then change the base class to be just Command"},{"line_number":59,"context_line":"        return tuple(), tuple()"}],"source_content_type":"text/x-python","patch_set":13,"id":"1aa78d24_997a9ab8","line":59,"in_reply_to":"1aa78d24_f174d236","updated":"2016-07-13 13:00:21.000000000","message":"Nope, there should be no problem here, just in current situation, the return value is used to print stuff, in case of inheriting from Command it won\u0027t happen.","commit_id":"dc667add6327de0cf912e87f70f2b1ba76897acd"}],"ironicclient/tests/unit/osc/v1/test_baremetal_create.py":[{"author":{"_account_id":6618,"name":"Ruby Loo","email":"opensrloo@gmail.com","username":"rloo"},"change_message_id":"f87e79e85f96c7ea669ff59ad216b6533d909ba2","unresolved":false,"context_lines":[{"line_number":61,"context_line":"    def test_baremetal_create_no_args(self):"},{"line_number":62,"context_line":"        parsed_args \u003d self.check_parser(self.cmd, [], [])"},{"line_number":63,"context_line":"        self.assertRaises(exc.ValidationError,"},{"line_number":64,"context_line":"                          self.cmd.take_action, parsed_args)"},{"line_number":65,"context_line":""},{"line_number":66,"context_line":"    @mock.patch.object(create_resources, \u0027create_resources\u0027, autospec\u003dTrue)"},{"line_number":67,"context_line":"    def test_baremetal_create_resource_files(self, mock_create):"}],"source_content_type":"text/x-python","patch_set":13,"id":"1aa78d24_3a390fa5","line":64,"updated":"2016-07-06 17:47:29.000000000","message":"what is the diff between this and test_baremetal_create_parser_no_options() (L28). Do we need the one at L28?","commit_id":"dc667add6327de0cf912e87f70f2b1ba76897acd"},{"author":{"_account_id":12356,"name":"Vladyslav Drok","email":"vdrok@mirantis.com","username":"vdrok"},"change_message_id":"4dd7c6e39b91060ba669c6cbfa0ab0771e9a9a57","unresolved":false,"context_lines":[{"line_number":61,"context_line":"    def test_baremetal_create_no_args(self):"},{"line_number":62,"context_line":"        parsed_args \u003d self.check_parser(self.cmd, [], [])"},{"line_number":63,"context_line":"        self.assertRaises(exc.ValidationError,"},{"line_number":64,"context_line":"                          self.cmd.take_action, parsed_args)"},{"line_number":65,"context_line":""},{"line_number":66,"context_line":"    @mock.patch.object(create_resources, \u0027create_resources\u0027, autospec\u003dTrue)"},{"line_number":67,"context_line":"    def test_baremetal_create_resource_files(self, mock_create):"}],"source_content_type":"text/x-python","patch_set":13,"id":"1aa78d24_149dd1bb","line":64,"in_reply_to":"1aa78d24_3a390fa5","updated":"2016-07-13 13:00:21.000000000","message":"Done","commit_id":"dc667add6327de0cf912e87f70f2b1ba76897acd"}],"ironicclient/tests/unit/v1/test_create_resources.py":[{"author":{"_account_id":6618,"name":"Ruby Loo","email":"opensrloo@gmail.com","username":"rloo"},"change_message_id":"f87e79e85f96c7ea669ff59ad216b6533d909ba2","unresolved":false,"context_lines":[{"line_number":53,"context_line":"    }]"},{"line_number":54,"context_line":"}"},{"line_number":55,"context_line":""},{"line_number":56,"context_line":"ironic_pov_invalid_json \u003d {"},{"line_number":57,"context_line":"    \"nodes\": [{"},{"line_number":58,"context_line":"        \"driver\": \"non_existent\","},{"line_number":59,"context_line":"        \"ports\": [{"}],"source_content_type":"text/x-python","patch_set":13,"id":"1aa78d24_5ae05bfa","line":56,"updated":"2016-07-06 17:47:29.000000000","message":"what does \u0027pov\u0027 stand for? (I think of it as point-of-view)","commit_id":"dc667add6327de0cf912e87f70f2b1ba76897acd"},{"author":{"_account_id":12356,"name":"Vladyslav Drok","email":"vdrok@mirantis.com","username":"vdrok"},"change_message_id":"4dd7c6e39b91060ba669c6cbfa0ab0771e9a9a57","unresolved":false,"context_lines":[{"line_number":53,"context_line":"    }]"},{"line_number":54,"context_line":"}"},{"line_number":55,"context_line":""},{"line_number":56,"context_line":"ironic_pov_invalid_json \u003d {"},{"line_number":57,"context_line":"    \"nodes\": [{"},{"line_number":58,"context_line":"        \"driver\": \"non_existent\","},{"line_number":59,"context_line":"        \"ports\": [{"}],"source_content_type":"text/x-python","patch_set":13,"id":"1aa78d24_b4e03d27","line":56,"in_reply_to":"1aa78d24_5ae05bfa","updated":"2016-07-13 13:00:21.000000000","message":"correct, dunno how to keep it short and clear at the same time :)","commit_id":"dc667add6327de0cf912e87f70f2b1ba76897acd"},{"author":{"_account_id":6618,"name":"Ruby Loo","email":"opensrloo@gmail.com","username":"rloo"},"change_message_id":"f87e79e85f96c7ea669ff59ad216b6533d909ba2","unresolved":false,"context_lines":[{"line_number":64,"context_line":""},{"line_number":65,"context_line":"schema_pov_invalid_json \u003d {\"meow\": \"woof!\"}"},{"line_number":66,"context_line":""},{"line_number":67,"context_line":""},{"line_number":68,"context_line":"class CreateSchemaTest(utils.BaseTestCase):"},{"line_number":69,"context_line":""},{"line_number":70,"context_line":"    def test_schema(self):"}],"source_content_type":"text/x-python","patch_set":13,"id":"1aa78d24_da9a8b6d","line":67,"updated":"2016-07-06 17:47:29.000000000","message":"should we test .yaml too? (ugh)","commit_id":"dc667add6327de0cf912e87f70f2b1ba76897acd"},{"author":{"_account_id":12356,"name":"Vladyslav Drok","email":"vdrok@mirantis.com","username":"vdrok"},"change_message_id":"4dd7c6e39b91060ba669c6cbfa0ab0771e9a9a57","unresolved":false,"context_lines":[{"line_number":64,"context_line":""},{"line_number":65,"context_line":"schema_pov_invalid_json \u003d {\"meow\": \"woof!\"}"},{"line_number":66,"context_line":""},{"line_number":67,"context_line":""},{"line_number":68,"context_line":"class CreateSchemaTest(utils.BaseTestCase):"},{"line_number":69,"context_line":""},{"line_number":70,"context_line":"    def test_schema(self):"}],"source_content_type":"text/x-python","patch_set":13,"id":"1aa78d24_146031a4","line":67,"in_reply_to":"1aa78d24_da9a8b6d","updated":"2016-07-13 13:00:21.000000000","message":"So you\u0027ve asked about it earlier, I think we should not. both yaml.load and json.load will return a python dictionary, so adding tests with json/yaml instead of python dict will be testing json/yaml serializer instead of client...","commit_id":"dc667add6327de0cf912e87f70f2b1ba76897acd"},{"author":{"_account_id":6618,"name":"Ruby Loo","email":"opensrloo@gmail.com","username":"rloo"},"change_message_id":"f87e79e85f96c7ea669ff59ad216b6533d909ba2","unresolved":false,"context_lines":[{"line_number":248,"context_line":"        self.client.node.create.assert_called_once_with(driver\u003d\u0027fake\u0027)"},{"line_number":249,"context_line":""},{"line_number":250,"context_line":"    def test_create_single_node_with_ports(self):"},{"line_number":251,"context_line":"        params \u003d {\u0027driver\u0027: \u0027fake\u0027, \u0027ports\u0027: [\u0027some ports here\u0027]}"},{"line_number":252,"context_line":"        self.client.node.create.return_value \u003d mock.Mock(uuid\u003d\u0027uuid\u0027)"},{"line_number":253,"context_line":"        self.assertEqual("},{"line_number":254,"context_line":"            (\u0027uuid\u0027, None),"}],"source_content_type":"text/x-python","patch_set":13,"id":"1aa78d24_fad94723","line":251,"updated":"2016-07-06 17:47:29.000000000","message":"i\u0027d prefer if there was something that looked more like a port than \u0027some ports here\u0027 but maybe it isn\u0027t worth it. (To give folks a more realistic example of what it should be.)","commit_id":"dc667add6327de0cf912e87f70f2b1ba76897acd"},{"author":{"_account_id":12356,"name":"Vladyslav Drok","email":"vdrok@mirantis.com","username":"vdrok"},"change_message_id":"4dd7c6e39b91060ba669c6cbfa0ab0771e9a9a57","unresolved":false,"context_lines":[{"line_number":248,"context_line":"        self.client.node.create.assert_called_once_with(driver\u003d\u0027fake\u0027)"},{"line_number":249,"context_line":""},{"line_number":250,"context_line":"    def test_create_single_node_with_ports(self):"},{"line_number":251,"context_line":"        params \u003d {\u0027driver\u0027: \u0027fake\u0027, \u0027ports\u0027: [\u0027some ports here\u0027]}"},{"line_number":252,"context_line":"        self.client.node.create.return_value \u003d mock.Mock(uuid\u003d\u0027uuid\u0027)"},{"line_number":253,"context_line":"        self.assertEqual("},{"line_number":254,"context_line":"            (\u0027uuid\u0027, None),"}],"source_content_type":"text/x-python","patch_set":13,"id":"1aa78d24_34de0d3e","line":251,"in_reply_to":"1aa78d24_fad94723","updated":"2016-07-13 13:00:21.000000000","message":"I can do it, but there is an example at the top of the file. If you think it should be done I\u0027ll add that :)","commit_id":"dc667add6327de0cf912e87f70f2b1ba76897acd"},{"author":{"_account_id":6618,"name":"Ruby Loo","email":"opensrloo@gmail.com","username":"rloo"},"change_message_id":"7284327baf329dcb16814b40f775819baf12de2f","unresolved":false,"context_lines":[{"line_number":90,"context_line":"            self, mock_load, mock_validate, mock_chassis, mock_nodes):"},{"line_number":91,"context_line":"        resources_files \u003d [\u0027file.json\u0027]"},{"line_number":92,"context_line":"        create_resources.create_resources(self.client, resources_files)"},{"line_number":93,"context_line":"        mock_load.assert_has_calls(["},{"line_number":94,"context_line":"            mock.call(\u0027file.json\u0027)"},{"line_number":95,"context_line":"        ])"},{"line_number":96,"context_line":"        mock_validate.assert_called_once_with(valid_json, mock.ANY)"}],"source_content_type":"text/x-python","patch_set":15,"id":"3ac371cc_540426bf","line":93,"updated":"2016-08-15 18:53:36.000000000","message":"This will also be true if mock_load was called more than once. Why not just do mock_load.assert_called_once_with()?","commit_id":"91c4539bf3baff643ac9fe1ac460f9ce3dfaf59a"},{"author":{"_account_id":12356,"name":"Vladyslav Drok","email":"vdrok@mirantis.com","username":"vdrok"},"change_message_id":"4b007723385fe60d719ebc034f90d6e50662dc73","unresolved":false,"context_lines":[{"line_number":90,"context_line":"            self, mock_load, mock_validate, mock_chassis, mock_nodes):"},{"line_number":91,"context_line":"        resources_files \u003d [\u0027file.json\u0027]"},{"line_number":92,"context_line":"        create_resources.create_resources(self.client, resources_files)"},{"line_number":93,"context_line":"        mock_load.assert_has_calls(["},{"line_number":94,"context_line":"            mock.call(\u0027file.json\u0027)"},{"line_number":95,"context_line":"        ])"},{"line_number":96,"context_line":"        mock_validate.assert_called_once_with(valid_json, mock.ANY)"}],"source_content_type":"text/x-python","patch_set":15,"id":"3ac371cc_5e6cc7cf","line":93,"in_reply_to":"3ac371cc_540426bf","updated":"2016-08-17 17:33:33.000000000","message":"Will do","commit_id":"91c4539bf3baff643ac9fe1ac460f9ce3dfaf59a"},{"author":{"_account_id":6618,"name":"Ruby Loo","email":"opensrloo@gmail.com","username":"rloo"},"change_message_id":"7284327baf329dcb16814b40f775819baf12de2f","unresolved":false,"context_lines":[{"line_number":156,"context_line":"        mock_validate.assert_has_calls(["},{"line_number":157,"context_line":"            mock.call(valid_json, mock.ANY),"},{"line_number":158,"context_line":"            mock.call(schema_pov_invalid_json, mock.ANY)"},{"line_number":159,"context_line":"        ])"},{"line_number":160,"context_line":"        self.assertFalse(mock_chassis.called)"},{"line_number":161,"context_line":"        self.assertFalse(mock_nodes.called)"},{"line_number":162,"context_line":""}],"source_content_type":"text/x-python","patch_set":15,"id":"3ac371cc_94ee9e89","line":159,"updated":"2016-08-15 18:53:36.000000000","message":"This checks that mock_validate was called with these calls, in this order, but not that these were the only calls. Do you also want to check that there were exactly two calls to mock_validate?","commit_id":"91c4539bf3baff643ac9fe1ac460f9ce3dfaf59a"},{"author":{"_account_id":12356,"name":"Vladyslav Drok","email":"vdrok@mirantis.com","username":"vdrok"},"change_message_id":"4b007723385fe60d719ebc034f90d6e50662dc73","unresolved":false,"context_lines":[{"line_number":156,"context_line":"        mock_validate.assert_has_calls(["},{"line_number":157,"context_line":"            mock.call(valid_json, mock.ANY),"},{"line_number":158,"context_line":"            mock.call(schema_pov_invalid_json, mock.ANY)"},{"line_number":159,"context_line":"        ])"},{"line_number":160,"context_line":"        self.assertFalse(mock_chassis.called)"},{"line_number":161,"context_line":"        self.assertFalse(mock_nodes.called)"},{"line_number":162,"context_line":""}],"source_content_type":"text/x-python","patch_set":15,"id":"3ac371cc_1e39afa4","line":159,"in_reply_to":"3ac371cc_94ee9e89","updated":"2016-08-17 17:33:33.000000000","message":"Done","commit_id":"91c4539bf3baff643ac9fe1ac460f9ce3dfaf59a"},{"author":{"_account_id":6618,"name":"Ruby Loo","email":"opensrloo@gmail.com","username":"rloo"},"change_message_id":"7284327baf329dcb16814b40f775819baf12de2f","unresolved":false,"context_lines":[{"line_number":240,"context_line":""},{"line_number":241,"context_line":"    def test_create_single_node(self):"},{"line_number":242,"context_line":"        params \u003d {\u0027driver\u0027: \u0027fake\u0027}"},{"line_number":243,"context_line":"        self.client.node.create.return_value \u003d mock.Mock(uuid\u003d\u0027uuid\u0027)"},{"line_number":244,"context_line":"        self.assertEqual("},{"line_number":245,"context_line":"            (\u0027uuid\u0027, None),"},{"line_number":246,"context_line":"            create_resources.create_single_node(self.client, **params)"}],"source_content_type":"text/x-python","patch_set":15,"id":"3ac371cc_4f7813f3","line":243,"updated":"2016-08-15 18:53:36.000000000","message":"i\u0027d prefer some uuid instead of \u0027uuid\u0027 but maybe that is a nit.","commit_id":"91c4539bf3baff643ac9fe1ac460f9ce3dfaf59a"},{"author":{"_account_id":12356,"name":"Vladyslav Drok","email":"vdrok@mirantis.com","username":"vdrok"},"change_message_id":"4b007723385fe60d719ebc034f90d6e50662dc73","unresolved":false,"context_lines":[{"line_number":240,"context_line":""},{"line_number":241,"context_line":"    def test_create_single_node(self):"},{"line_number":242,"context_line":"        params \u003d {\u0027driver\u0027: \u0027fake\u0027}"},{"line_number":243,"context_line":"        self.client.node.create.return_value \u003d mock.Mock(uuid\u003d\u0027uuid\u0027)"},{"line_number":244,"context_line":"        self.assertEqual("},{"line_number":245,"context_line":"            (\u0027uuid\u0027, None),"},{"line_number":246,"context_line":"            create_resources.create_single_node(self.client, **params)"}],"source_content_type":"text/x-python","patch_set":15,"id":"3ac371cc_1e07efca","line":243,"in_reply_to":"3ac371cc_4f7813f3","updated":"2016-08-17 17:33:33.000000000","message":"I think it\u0027s fine, we don\u0027t do any validation on client side anyway.","commit_id":"91c4539bf3baff643ac9fe1ac460f9ce3dfaf59a"},{"author":{"_account_id":6618,"name":"Ruby Loo","email":"opensrloo@gmail.com","username":"rloo"},"change_message_id":"7284327baf329dcb16814b40f775819baf12de2f","unresolved":false,"context_lines":[{"line_number":348,"context_line":"        self.assertFalse(self.client.node.create.called)"},{"line_number":349,"context_line":"        self.assertFalse(mock_create_ports.called)"},{"line_number":350,"context_line":"        self.assertEqual(1, len(errs))"},{"line_number":351,"context_line":"        self.assertIsInstance(errs[0], exc.ClientException)"},{"line_number":352,"context_line":""},{"line_number":353,"context_line":"    @mock.patch.object(create_resources, \u0027create_ports\u0027, autospec\u003dTrue)"},{"line_number":354,"context_line":"    def test_create_nodes_no_ports(self, mock_create_ports):"}],"source_content_type":"text/x-python","patch_set":15,"id":"3ac371cc_c1269767","line":351,"updated":"2016-08-15 18:53:36.000000000","message":"do we want a test like this, but with the call to .create_nodes(chassis_uuid\u003dNone)?","commit_id":"91c4539bf3baff643ac9fe1ac460f9ce3dfaf59a"},{"author":{"_account_id":12356,"name":"Vladyslav Drok","email":"vdrok@mirantis.com","username":"vdrok"},"change_message_id":"4b007723385fe60d719ebc034f90d6e50662dc73","unresolved":false,"context_lines":[{"line_number":348,"context_line":"        self.assertFalse(self.client.node.create.called)"},{"line_number":349,"context_line":"        self.assertFalse(mock_create_ports.called)"},{"line_number":350,"context_line":"        self.assertEqual(1, len(errs))"},{"line_number":351,"context_line":"        self.assertIsInstance(errs[0], exc.ClientException)"},{"line_number":352,"context_line":""},{"line_number":353,"context_line":"    @mock.patch.object(create_resources, \u0027create_ports\u0027, autospec\u003dTrue)"},{"line_number":354,"context_line":"    def test_create_nodes_no_ports(self, mock_create_ports):"}],"source_content_type":"text/x-python","patch_set":15,"id":"3ac371cc_fec01352","line":351,"in_reply_to":"3ac371cc_c1269767","updated":"2016-08-17 17:33:33.000000000","message":"I don\u0027t think it\u0027s worth adding another test, I\u0027d just add it on L324","commit_id":"91c4539bf3baff643ac9fe1ac460f9ce3dfaf59a"}],"ironicclient/tests/unit/v1/test_create_resources_shell.py":[{"author":{"_account_id":6618,"name":"Ruby Loo","email":"opensrloo@gmail.com","username":"rloo"},"change_message_id":"c38368d2b7fe83eb17143282ea343d9216424991","unresolved":false,"context_lines":[{"line_number":65,"context_line":"schema_pov_invalid_json \u003d {\"meow\": \"woof!\"}"},{"line_number":66,"context_line":""},{"line_number":67,"context_line":""},{"line_number":68,"context_line":"class CreateResourcesShellTest(utils.BaseTestCase):"},{"line_number":69,"context_line":""},{"line_number":70,"context_line":"    def setUp(self):"},{"line_number":71,"context_line":"        super(CreateResourcesShellTest, self).setUp()"}],"source_content_type":"text/x-python","patch_set":10,"id":"3aaa91ec_a6a305ff","line":68,"updated":"2016-06-30 21:04:19.000000000","message":"I\u0027m too tired to review the tests today. Will do that another day.\n\nJust wondering though; why don\u0027t we just add some .yaml and .json test files in this directory, for testing purposes?","commit_id":"412a40d19a0b3a998288d33640f25136db7166a6"},{"author":{"_account_id":12356,"name":"Vladyslav Drok","email":"vdrok@mirantis.com","username":"vdrok"},"change_message_id":"d66106b6728011d2d366023b0429639fe32b49be","unresolved":false,"context_lines":[{"line_number":65,"context_line":"schema_pov_invalid_json \u003d {\"meow\": \"woof!\"}"},{"line_number":66,"context_line":""},{"line_number":67,"context_line":""},{"line_number":68,"context_line":"class CreateResourcesShellTest(utils.BaseTestCase):"},{"line_number":69,"context_line":""},{"line_number":70,"context_line":"    def setUp(self):"},{"line_number":71,"context_line":"        super(CreateResourcesShellTest, self).setUp()"}],"source_content_type":"text/x-python","patch_set":10,"id":"1aa78d24_74604336","line":68,"in_reply_to":"3aaa91ec_220a2f7a","updated":"2016-07-04 17:14:20.000000000","message":"I\u0027ve added some tests for these 3 dictionaries, it kind of assures that the schema is valid. As for testing yamls, I\u0027m not sure if it\u0027s worth it - in this case we would be testing yaml loader, as after deserialization it will still be a dictionary like these three.","commit_id":"412a40d19a0b3a998288d33640f25136db7166a6"},{"author":{"_account_id":12356,"name":"Vladyslav Drok","email":"vdrok@mirantis.com","username":"vdrok"},"change_message_id":"986173cd02dff587e708a08c41943248b22b98f6","unresolved":false,"context_lines":[{"line_number":65,"context_line":"schema_pov_invalid_json \u003d {\"meow\": \"woof!\"}"},{"line_number":66,"context_line":""},{"line_number":67,"context_line":""},{"line_number":68,"context_line":"class CreateResourcesShellTest(utils.BaseTestCase):"},{"line_number":69,"context_line":""},{"line_number":70,"context_line":"    def setUp(self):"},{"line_number":71,"context_line":"        super(CreateResourcesShellTest, self).setUp()"}],"source_content_type":"text/x-python","patch_set":10,"id":"3aaa91ec_220a2f7a","line":68,"in_reply_to":"3aaa91ec_a6a305ff","updated":"2016-07-01 17:41:44.000000000","message":"Will add in later patch sets.","commit_id":"412a40d19a0b3a998288d33640f25136db7166a6"},{"author":{"_account_id":6618,"name":"Ruby Loo","email":"opensrloo@gmail.com","username":"rloo"},"change_message_id":"f87e79e85f96c7ea669ff59ad216b6533d909ba2","unresolved":false,"context_lines":[{"line_number":20,"context_line":"class TestCreateResourcesShell(utils.BaseTestCase):"},{"line_number":21,"context_line":"    def setUp(self):"},{"line_number":22,"context_line":"        super(TestCreateResourcesShell, self).setUp()"},{"line_number":23,"context_line":"        self.client \u003d mock.MagicMock(autospec\u003dTrue)"},{"line_number":24,"context_line":""},{"line_number":25,"context_line":"    @mock.patch.object(create_resources, \u0027create_resources\u0027)"},{"line_number":26,"context_line":"    def test_create_shell(self, mock_create_resources):"}],"source_content_type":"text/x-python","patch_set":13,"id":"1aa78d24_d7f70657","line":23,"updated":"2016-07-06 17:47:29.000000000","message":"just wondering. what does it mean to put \u0027autospec\u003dTrue\u0027 for a mock.MagicMock?","commit_id":"dc667add6327de0cf912e87f70f2b1ba76897acd"},{"author":{"_account_id":12356,"name":"Vladyslav Drok","email":"vdrok@mirantis.com","username":"vdrok"},"change_message_id":"4dd7c6e39b91060ba669c6cbfa0ab0771e9a9a57","unresolved":false,"context_lines":[{"line_number":20,"context_line":"class TestCreateResourcesShell(utils.BaseTestCase):"},{"line_number":21,"context_line":"    def setUp(self):"},{"line_number":22,"context_line":"        super(TestCreateResourcesShell, self).setUp()"},{"line_number":23,"context_line":"        self.client \u003d mock.MagicMock(autospec\u003dTrue)"},{"line_number":24,"context_line":""},{"line_number":25,"context_line":"    @mock.patch.object(create_resources, \u0027create_resources\u0027)"},{"line_number":26,"context_line":"    def test_create_shell(self, mock_create_resources):"}],"source_content_type":"text/x-python","patch_set":13,"id":"1aa78d24_34b1ede0","line":23,"in_reply_to":"1aa78d24_d7f70657","updated":"2016-07-13 13:00:21.000000000","message":"It\u0027s the same as usual in mock.patch.object - you won\u0027t be able to call non-existing functions, like assert_has_three_calls_yesterday() - it will be throwing attributeerror","commit_id":"dc667add6327de0cf912e87f70f2b1ba76897acd"}],"ironicclient/v1/create_resources.py":[{"author":{"_account_id":12356,"name":"Vladyslav Drok","email":"vdrok@mirantis.com","username":"vdrok"},"change_message_id":"98e5df1019ab0a79a368680dec6e0f58e9a70b7f","unresolved":false,"context_lines":[{"line_number":93,"context_line":"                                  \u0027%(err)s\u0027 % {\u0027err\u0027: e, \u0027file\u0027: filename})"},{"line_number":94,"context_line":""},{"line_number":95,"context_line":""},{"line_number":96,"context_line":"def client_create_handler(create_method, resource_type, **params):"},{"line_number":97,"context_line":"    \"\"\"Handle errors of the client create call."},{"line_number":98,"context_line":""},{"line_number":99,"context_line":"    :param create_method: method to catch exceptions from."}],"source_content_type":"text/x-python","patch_set":11,"id":"3aaa91ec_7dbfb8aa","line":96,"updated":"2016-07-01 17:44:49.000000000","message":"This can be rewritten as a decorator too.","commit_id":"24fa7f5565d90c755035493c908baa3513f7aeed"},{"author":{"_account_id":12356,"name":"Vladyslav Drok","email":"vdrok@mirantis.com","username":"vdrok"},"change_message_id":"6b254eb500a8a9e9989c6cd0ef1d741b1988532a","unresolved":false,"context_lines":[{"line_number":93,"context_line":"                                  \u0027%(err)s\u0027 % {\u0027err\u0027: e, \u0027file\u0027: filename})"},{"line_number":94,"context_line":""},{"line_number":95,"context_line":""},{"line_number":96,"context_line":"def client_create_handler(create_method, resource_type, **params):"},{"line_number":97,"context_line":"    \"\"\"Handle errors of the client create call."},{"line_number":98,"context_line":""},{"line_number":99,"context_line":"    :param create_method: method to catch exceptions from."}],"source_content_type":"text/x-python","patch_set":11,"id":"1aa78d24_1b55b54f","line":96,"in_reply_to":"3aaa91ec_7dbfb8aa","updated":"2016-07-04 16:37:07.000000000","message":"Done","commit_id":"24fa7f5565d90c755035493c908baa3513f7aeed"},{"author":{"_account_id":6618,"name":"Ruby Loo","email":"opensrloo@gmail.com","username":"rloo"},"change_message_id":"f87e79e85f96c7ea669ff59ad216b6533d909ba2","unresolved":false,"context_lines":[{"line_number":41,"context_line":"}"},{"line_number":42,"context_line":""},{"line_number":43,"context_line":""},{"line_number":44,"context_line":"def create_resources(client, filenames):"},{"line_number":45,"context_line":"    errors \u003d []"},{"line_number":46,"context_line":"    resources \u003d []"},{"line_number":47,"context_line":"    for resource_file in filenames:"}],"source_content_type":"text/x-python","patch_set":13,"id":"1aa78d24_51296636","line":44,"updated":"2016-07-06 17:47:29.000000000","message":"would be good to have a docstring that describes this method, parameters, raises, return value.","commit_id":"dc667add6327de0cf912e87f70f2b1ba76897acd"},{"author":{"_account_id":12356,"name":"Vladyslav Drok","email":"vdrok@mirantis.com","username":"vdrok"},"change_message_id":"4dd7c6e39b91060ba669c6cbfa0ab0771e9a9a57","unresolved":false,"context_lines":[{"line_number":41,"context_line":"}"},{"line_number":42,"context_line":""},{"line_number":43,"context_line":""},{"line_number":44,"context_line":"def create_resources(client, filenames):"},{"line_number":45,"context_line":"    errors \u003d []"},{"line_number":46,"context_line":"    resources \u003d []"},{"line_number":47,"context_line":"    for resource_file in filenames:"}],"source_content_type":"text/x-python","patch_set":13,"id":"1aa78d24_74c7f544","line":44,"in_reply_to":"1aa78d24_51296636","updated":"2016-07-13 13:00:21.000000000","message":"Done","commit_id":"dc667add6327de0cf912e87f70f2b1ba76897acd"},{"author":{"_account_id":6618,"name":"Ruby Loo","email":"opensrloo@gmail.com","username":"rloo"},"change_message_id":"f87e79e85f96c7ea669ff59ad216b6533d909ba2","unresolved":false,"context_lines":[{"line_number":97,"context_line":"    \"\"\"Catch errors of the creation of a single resource."},{"line_number":98,"context_line":""},{"line_number":99,"context_line":"    This decorator appends an error to the return value of the create_method,"},{"line_number":100,"context_line":"    changing the return value from just UUID to (UUID, error), and does some"},{"line_number":101,"context_line":"    exception handling."},{"line_number":102,"context_line":""},{"line_number":103,"context_line":"    :param resource_type: string value, the type of the resource being created,"}],"source_content_type":"text/x-python","patch_set":13,"id":"1aa78d24_6b18f875","line":100,"updated":"2016-07-06 17:47:29.000000000","message":"The error is an exception, not an error string. Might be worth adding a comment about that.","commit_id":"dc667add6327de0cf912e87f70f2b1ba76897acd"},{"author":{"_account_id":12356,"name":"Vladyslav Drok","email":"vdrok@mirantis.com","username":"vdrok"},"change_message_id":"4dd7c6e39b91060ba669c6cbfa0ab0771e9a9a57","unresolved":false,"context_lines":[{"line_number":97,"context_line":"    \"\"\"Catch errors of the creation of a single resource."},{"line_number":98,"context_line":""},{"line_number":99,"context_line":"    This decorator appends an error to the return value of the create_method,"},{"line_number":100,"context_line":"    changing the return value from just UUID to (UUID, error), and does some"},{"line_number":101,"context_line":"    exception handling."},{"line_number":102,"context_line":""},{"line_number":103,"context_line":"    :param resource_type: string value, the type of the resource being created,"}],"source_content_type":"text/x-python","patch_set":13,"id":"1aa78d24_142dd1fd","line":100,"in_reply_to":"1aa78d24_6b18f875","updated":"2016-07-13 13:00:21.000000000","message":"Done","commit_id":"dc667add6327de0cf912e87f70f2b1ba76897acd"},{"author":{"_account_id":6618,"name":"Ruby Loo","email":"opensrloo@gmail.com","username":"rloo"},"change_message_id":"f87e79e85f96c7ea669ff59ad216b6533d909ba2","unresolved":false,"context_lines":[{"line_number":120,"context_line":"            except Exception as e:"},{"line_number":121,"context_line":"                error \u003d exc.ClientException("},{"line_number":122,"context_line":"                    \u0027Unable to create the %(resource)s with the specified \u0027"},{"line_number":123,"context_line":"                    \u0027attributes (%(params)s), the error is: %(error)s\u0027 %"},{"line_number":124,"context_line":"                    {\u0027error\u0027: e, \u0027resource\u0027: resource_type, \u0027params\u0027: params})"},{"line_number":125,"context_line":"            return uuid, error"},{"line_number":126,"context_line":"        return wrapper"}],"source_content_type":"text/x-python","patch_set":13,"id":"1aa78d24_6be2b830","line":123,"updated":"2016-07-06 17:47:29.000000000","message":"if you mention \u0027the specified attributes\u0027, then it doesn\u0027t make sense to put the params in parentheses. You could:\n\u0027the specified attributes: \u003cparams\u003e\u0027\n\u0027Unable to create a \u003cresource\u003e (with the specified attributes \u003cparams\u003e) ...","commit_id":"dc667add6327de0cf912e87f70f2b1ba76897acd"},{"author":{"_account_id":12356,"name":"Vladyslav Drok","email":"vdrok@mirantis.com","username":"vdrok"},"change_message_id":"4dd7c6e39b91060ba669c6cbfa0ab0771e9a9a57","unresolved":false,"context_lines":[{"line_number":120,"context_line":"            except Exception as e:"},{"line_number":121,"context_line":"                error \u003d exc.ClientException("},{"line_number":122,"context_line":"                    \u0027Unable to create the %(resource)s with the specified \u0027"},{"line_number":123,"context_line":"                    \u0027attributes (%(params)s), the error is: %(error)s\u0027 %"},{"line_number":124,"context_line":"                    {\u0027error\u0027: e, \u0027resource\u0027: resource_type, \u0027params\u0027: params})"},{"line_number":125,"context_line":"            return uuid, error"},{"line_number":126,"context_line":"        return wrapper"}],"source_content_type":"text/x-python","patch_set":13,"id":"1aa78d24_b4195dd3","line":123,"in_reply_to":"1aa78d24_6be2b830","updated":"2016-07-13 13:00:21.000000000","message":"Done","commit_id":"dc667add6327de0cf912e87f70f2b1ba76897acd"},{"author":{"_account_id":6618,"name":"Ruby Loo","email":"opensrloo@gmail.com","username":"rloo"},"change_message_id":"f87e79e85f96c7ea669ff59ad216b6533d909ba2","unresolved":false,"context_lines":[{"line_number":214,"context_line":"        endpoint, if some of them contain \"ports\" key, its content is POSTed"},{"line_number":215,"context_line":"        separately to /ports endpoint."},{"line_number":216,"context_line":"    :param chassis_uuid: UUID of a chassis the nodes should be associated with."},{"line_number":217,"context_line":"    :returns: array of exceptions happened during creation."},{"line_number":218,"context_line":"    \"\"\""},{"line_number":219,"context_line":"    errors \u003d []"},{"line_number":220,"context_line":"    for node in node_list:"}],"source_content_type":"text/x-python","patch_set":13,"id":"1aa78d24_97e58339","line":217,"updated":"2016-07-06 17:47:29.000000000","message":"s/happened/encountered/","commit_id":"dc667add6327de0cf912e87f70f2b1ba76897acd"},{"author":{"_account_id":12356,"name":"Vladyslav Drok","email":"vdrok@mirantis.com","username":"vdrok"},"change_message_id":"4dd7c6e39b91060ba669c6cbfa0ab0771e9a9a57","unresolved":false,"context_lines":[{"line_number":214,"context_line":"        endpoint, if some of them contain \"ports\" key, its content is POSTed"},{"line_number":215,"context_line":"        separately to /ports endpoint."},{"line_number":216,"context_line":"    :param chassis_uuid: UUID of a chassis the nodes should be associated with."},{"line_number":217,"context_line":"    :returns: array of exceptions happened during creation."},{"line_number":218,"context_line":"    \"\"\""},{"line_number":219,"context_line":"    errors \u003d []"},{"line_number":220,"context_line":"    for node in node_list:"}],"source_content_type":"text/x-python","patch_set":13,"id":"1aa78d24_d47509fa","line":217,"in_reply_to":"1aa78d24_97e58339","updated":"2016-07-13 13:00:21.000000000","message":"Done","commit_id":"dc667add6327de0cf912e87f70f2b1ba76897acd"},{"author":{"_account_id":6618,"name":"Ruby Loo","email":"opensrloo@gmail.com","username":"rloo"},"change_message_id":"f87e79e85f96c7ea669ff59ad216b6533d909ba2","unresolved":false,"context_lines":[{"line_number":247,"context_line":"    :param chassis_list: list of dictionaries to be POSTed to /chassis"},{"line_number":248,"context_line":"        endpoint, if some of them contain \"nodes\" key, its content is POSTed"},{"line_number":249,"context_line":"        separately to /nodes endpoint."},{"line_number":250,"context_line":"    :returns: array of exceptions happened during creation."},{"line_number":251,"context_line":"    \"\"\""},{"line_number":252,"context_line":"    errors \u003d []"},{"line_number":253,"context_line":"    for chassis in chassis_list:"}],"source_content_type":"text/x-python","patch_set":13,"id":"1aa78d24_37f80fc3","line":250,"updated":"2016-07-06 17:47:29.000000000","message":"s/happened/encountered/","commit_id":"dc667add6327de0cf912e87f70f2b1ba76897acd"},{"author":{"_account_id":12356,"name":"Vladyslav Drok","email":"vdrok@mirantis.com","username":"vdrok"},"change_message_id":"4dd7c6e39b91060ba669c6cbfa0ab0771e9a9a57","unresolved":false,"context_lines":[{"line_number":247,"context_line":"    :param chassis_list: list of dictionaries to be POSTed to /chassis"},{"line_number":248,"context_line":"        endpoint, if some of them contain \"nodes\" key, its content is POSTed"},{"line_number":249,"context_line":"        separately to /nodes endpoint."},{"line_number":250,"context_line":"    :returns: array of exceptions happened during creation."},{"line_number":251,"context_line":"    \"\"\""},{"line_number":252,"context_line":"    errors \u003d []"},{"line_number":253,"context_line":"    for chassis in chassis_list:"}],"source_content_type":"text/x-python","patch_set":13,"id":"1aa78d24_946f012a","line":250,"in_reply_to":"1aa78d24_37f80fc3","updated":"2016-07-13 13:00:21.000000000","message":"Done","commit_id":"dc667add6327de0cf912e87f70f2b1ba76897acd"}],"ironicclient/v1/create_resources_schema.json":[{"author":{"_account_id":10239,"name":"Dmitry Tantsur","email":"dtantsur@protonmail.com","username":"dtantsur"},"change_message_id":"680237186c4ae3c885dee6e3d07de815d2c9be75","unresolved":false,"context_lines":[{"line_number":35,"context_line":"                    \"items\": {"},{"line_number":36,"context_line":"                        \"$ref\": \"#/definitions/node\""},{"line_number":37,"context_line":"                    }"},{"line_number":38,"context_line":"                }"},{"line_number":39,"context_line":"            },"},{"line_number":40,"context_line":"            \"additionalProperties\": false"},{"line_number":41,"context_line":"        },"}],"source_content_type":"application/json","patch_set":6,"id":"7aa08908_f93a20cc","line":38,"updated":"2016-06-17 12:57:02.000000000","message":"please don\u0027t list all possible fields, it\u0027s API\u0027s job","commit_id":"821f5506bbb4939e68ad1c392f00cb6a922f13fb"},{"author":{"_account_id":12356,"name":"Vladyslav Drok","email":"vdrok@mirantis.com","username":"vdrok"},"change_message_id":"02e9ed3593cd5884ca512cfc21a3c04652982ad1","unresolved":false,"context_lines":[{"line_number":35,"context_line":"                    \"items\": {"},{"line_number":36,"context_line":"                        \"$ref\": \"#/definitions/node\""},{"line_number":37,"context_line":"                    }"},{"line_number":38,"context_line":"                }"},{"line_number":39,"context_line":"            },"},{"line_number":40,"context_line":"            \"additionalProperties\": false"},{"line_number":41,"context_line":"        },"}],"source_content_type":"application/json","patch_set":6,"id":"3aaa91ec_69a6e254","line":38,"in_reply_to":"7aa08908_f93a20cc","updated":"2016-06-27 15:08:59.000000000","message":"Makes sense, I\u0027ll switch to a super simple in-code schema then.","commit_id":"821f5506bbb4939e68ad1c392f00cb6a922f13fb"},{"author":{"_account_id":10239,"name":"Dmitry Tantsur","email":"dtantsur@protonmail.com","username":"dtantsur"},"change_message_id":"680237186c4ae3c885dee6e3d07de815d2c9be75","unresolved":false,"context_lines":[{"line_number":37,"context_line":"                    }"},{"line_number":38,"context_line":"                }"},{"line_number":39,"context_line":"            },"},{"line_number":40,"context_line":"            \"additionalProperties\": false"},{"line_number":41,"context_line":"        },"},{"line_number":42,"context_line":"        \"node\": {"},{"line_number":43,"context_line":"            \"properties\": {"}],"source_content_type":"application/json","patch_set":6,"id":"7aa08908_d93764e1","line":40,"updated":"2016-06-17 12:57:02.000000000","message":"or at least don\u0027t do this","commit_id":"821f5506bbb4939e68ad1c392f00cb6a922f13fb"},{"author":{"_account_id":10239,"name":"Dmitry Tantsur","email":"dtantsur@protonmail.com","username":"dtantsur"},"change_message_id":"680237186c4ae3c885dee6e3d07de815d2c9be75","unresolved":false,"context_lines":[{"line_number":63,"context_line":"                },"},{"line_number":64,"context_line":"                \"extra\": {"},{"line_number":65,"context_line":"                    \"type\": \"object\""},{"line_number":66,"context_line":"                },"},{"line_number":67,"context_line":"                \"ports\": {"},{"line_number":68,"context_line":"                    \"type\": \"array\","},{"line_number":69,"context_line":"                    \"items\": {"}],"source_content_type":"application/json","patch_set":6,"id":"7aa08908_393148ee","line":66,"updated":"2016-06-17 12:57:02.000000000","message":"ditto","commit_id":"821f5506bbb4939e68ad1c392f00cb6a922f13fb"},{"author":{"_account_id":10239,"name":"Dmitry Tantsur","email":"dtantsur@protonmail.com","username":"dtantsur"},"change_message_id":"680237186c4ae3c885dee6e3d07de815d2c9be75","unresolved":false,"context_lines":[{"line_number":72,"context_line":"                }"},{"line_number":73,"context_line":"            },"},{"line_number":74,"context_line":"            \"required\": [\"driver\"],"},{"line_number":75,"context_line":"            \"additionalProperties\": false"},{"line_number":76,"context_line":"        },"},{"line_number":77,"context_line":"        \"port\": {"},{"line_number":78,"context_line":"            \"properties\": {"}],"source_content_type":"application/json","patch_set":6,"id":"7aa08908_192e0c8c","line":75,"updated":"2016-06-17 12:57:02.000000000","message":"or ditto","commit_id":"821f5506bbb4939e68ad1c392f00cb6a922f13fb"}],"ironicclient/v1/create_resources_shell.py":[{"author":{"_account_id":10239,"name":"Dmitry Tantsur","email":"dtantsur@protonmail.com","username":"dtantsur"},"change_message_id":"99bb547ee31ccf5bf23f4d5fd59d28a70a693a81","unresolved":false,"context_lines":[{"line_number":38,"context_line":"        try:"},{"line_number":39,"context_line":"            resources \u003d load_from_file(resource_file)"},{"line_number":40,"context_line":"            jsonschema.validate(resources, schema)"},{"line_number":41,"context_line":"        except Exception as e:"},{"line_number":42,"context_line":"            errors.append(e)"},{"line_number":43,"context_line":"            # Do not try to create resources if they don\u0027t satisfy the schema"},{"line_number":44,"context_line":"            continue"}],"source_content_type":"text/x-python","patch_set":6,"id":"5a9d85d2_695cfc25","line":41,"updated":"2016-06-20 16:53:08.000000000","message":"these 2 functions raise a limited set of errors, we can explicitly name them here","commit_id":"821f5506bbb4939e68ad1c392f00cb6a922f13fb"},{"author":{"_account_id":12356,"name":"Vladyslav Drok","email":"vdrok@mirantis.com","username":"vdrok"},"change_message_id":"02e9ed3593cd5884ca512cfc21a3c04652982ad1","unresolved":false,"context_lines":[{"line_number":38,"context_line":"        try:"},{"line_number":39,"context_line":"            resources \u003d load_from_file(resource_file)"},{"line_number":40,"context_line":"            jsonschema.validate(resources, schema)"},{"line_number":41,"context_line":"        except Exception as e:"},{"line_number":42,"context_line":"            errors.append(e)"},{"line_number":43,"context_line":"            # Do not try to create resources if they don\u0027t satisfy the schema"},{"line_number":44,"context_line":"            continue"}],"source_content_type":"text/x-python","patch_set":6,"id":"3aaa91ec_53dab3ea","line":41,"in_reply_to":"5a9d85d2_695cfc25","updated":"2016-06-27 15:08:59.000000000","message":"Done","commit_id":"821f5506bbb4939e68ad1c392f00cb6a922f13fb"},{"author":{"_account_id":10239,"name":"Dmitry Tantsur","email":"dtantsur@protonmail.com","username":"dtantsur"},"change_message_id":"99bb547ee31ccf5bf23f4d5fd59d28a70a693a81","unresolved":false,"context_lines":[{"line_number":43,"context_line":"            # Do not try to create resources if they don\u0027t satisfy the schema"},{"line_number":44,"context_line":"            continue"},{"line_number":45,"context_line":"        create_chassis(cc, resources.get(\u0027chassis\u0027, []), errors)"},{"line_number":46,"context_line":"        create_nodes(cc, resources.get(\u0027nodes\u0027, []), errors)"},{"line_number":47,"context_line":"    if errors:"},{"line_number":48,"context_line":"        raise exc.ClientException(\u0027During resources creation, the following \u0027"},{"line_number":49,"context_line":"                                  \u0027errors appeared: %s\u0027 % errors)"}],"source_content_type":"text/x-python","patch_set":6,"id":"5a9d85d2_c941b03b","line":46,"updated":"2016-06-20 16:53:08.000000000","message":"I think we should first validate all the files supplied, then proceed with creating stuff. This will end up with 2 for loops, but will report obvious errors like non-existing file much faster.","commit_id":"821f5506bbb4939e68ad1c392f00cb6a922f13fb"},{"author":{"_account_id":12356,"name":"Vladyslav Drok","email":"vdrok@mirantis.com","username":"vdrok"},"change_message_id":"02e9ed3593cd5884ca512cfc21a3c04652982ad1","unresolved":false,"context_lines":[{"line_number":43,"context_line":"            # Do not try to create resources if they don\u0027t satisfy the schema"},{"line_number":44,"context_line":"            continue"},{"line_number":45,"context_line":"        create_chassis(cc, resources.get(\u0027chassis\u0027, []), errors)"},{"line_number":46,"context_line":"        create_nodes(cc, resources.get(\u0027nodes\u0027, []), errors)"},{"line_number":47,"context_line":"    if errors:"},{"line_number":48,"context_line":"        raise exc.ClientException(\u0027During resources creation, the following \u0027"},{"line_number":49,"context_line":"                                  \u0027errors appeared: %s\u0027 % errors)"}],"source_content_type":"text/x-python","patch_set":6,"id":"3aaa91ec_73e1af9a","line":46,"in_reply_to":"5a9d85d2_c941b03b","updated":"2016-06-27 15:08:59.000000000","message":"Done","commit_id":"821f5506bbb4939e68ad1c392f00cb6a922f13fb"},{"author":{"_account_id":10239,"name":"Dmitry Tantsur","email":"dtantsur@protonmail.com","username":"dtantsur"},"change_message_id":"99bb547ee31ccf5bf23f4d5fd59d28a70a693a81","unresolved":false,"context_lines":[{"line_number":46,"context_line":"        create_nodes(cc, resources.get(\u0027nodes\u0027, []), errors)"},{"line_number":47,"context_line":"    if errors:"},{"line_number":48,"context_line":"        raise exc.ClientException(\u0027During resources creation, the following \u0027"},{"line_number":49,"context_line":"                                  \u0027errors appeared: %s\u0027 % errors)"},{"line_number":50,"context_line":""},{"line_number":51,"context_line":""},{"line_number":52,"context_line":"def load_from_file(filename, filetype\u003d\u0027Resource\u0027):"}],"source_content_type":"text/x-python","patch_set":6,"id":"5a9d85d2_a93ee4b5","line":49,"updated":"2016-06-20 16:53:08.000000000","message":"what about\n\n \"error appeared:\\n%s\" % \"\\n\".join(str(exc) for exc in errors)\n\nthis will end up with much nicer formatting","commit_id":"821f5506bbb4939e68ad1c392f00cb6a922f13fb"},{"author":{"_account_id":12356,"name":"Vladyslav Drok","email":"vdrok@mirantis.com","username":"vdrok"},"change_message_id":"02e9ed3593cd5884ca512cfc21a3c04652982ad1","unresolved":false,"context_lines":[{"line_number":46,"context_line":"        create_nodes(cc, resources.get(\u0027nodes\u0027, []), errors)"},{"line_number":47,"context_line":"    if errors:"},{"line_number":48,"context_line":"        raise exc.ClientException(\u0027During resources creation, the following \u0027"},{"line_number":49,"context_line":"                                  \u0027errors appeared: %s\u0027 % errors)"},{"line_number":50,"context_line":""},{"line_number":51,"context_line":""},{"line_number":52,"context_line":"def load_from_file(filename, filetype\u003d\u0027Resource\u0027):"}],"source_content_type":"text/x-python","patch_set":6,"id":"3aaa91ec_6602920d","line":49,"in_reply_to":"5a9d85d2_a93ee4b5","updated":"2016-06-27 15:08:59.000000000","message":"Done","commit_id":"821f5506bbb4939e68ad1c392f00cb6a922f13fb"},{"author":{"_account_id":10239,"name":"Dmitry Tantsur","email":"dtantsur@protonmail.com","username":"dtantsur"},"change_message_id":"99bb547ee31ccf5bf23f4d5fd59d28a70a693a81","unresolved":false,"context_lines":[{"line_number":62,"context_line":"        with open(filename) as f:"},{"line_number":63,"context_line":"            if filename.endswith(\u0027.yaml\u0027):"},{"line_number":64,"context_line":"                return yaml.load(f)"},{"line_number":65,"context_line":"            # Try JSON by default"},{"line_number":66,"context_line":"            return json.load(f)"},{"line_number":67,"context_line":"    except IOError as e:"},{"line_number":68,"context_line":"        raise exc.ClientException(\u0027Can not read %(type)s file %(file)s, the \u0027"}],"source_content_type":"text/x-python","patch_set":6,"id":"5a9d85d2_094c586f","line":65,"updated":"2016-06-20 16:53:08.000000000","message":"lets not do it (or lets require a --type argument). what if we add a new format one day?","commit_id":"821f5506bbb4939e68ad1c392f00cb6a922f13fb"},{"author":{"_account_id":12356,"name":"Vladyslav Drok","email":"vdrok@mirantis.com","username":"vdrok"},"change_message_id":"02e9ed3593cd5884ca512cfc21a3c04652982ad1","unresolved":false,"context_lines":[{"line_number":62,"context_line":"        with open(filename) as f:"},{"line_number":63,"context_line":"            if filename.endswith(\u0027.yaml\u0027):"},{"line_number":64,"context_line":"                return yaml.load(f)"},{"line_number":65,"context_line":"            # Try JSON by default"},{"line_number":66,"context_line":"            return json.load(f)"},{"line_number":67,"context_line":"    except IOError as e:"},{"line_number":68,"context_line":"        raise exc.ClientException(\u0027Can not read %(type)s file %(file)s, the \u0027"}],"source_content_type":"text/x-python","patch_set":6,"id":"3aaa91ec_73f88f4a","line":65,"in_reply_to":"5a9d85d2_094c586f","updated":"2016-06-27 15:08:59.000000000","message":"Done","commit_id":"821f5506bbb4939e68ad1c392f00cb6a922f13fb"},{"author":{"_account_id":10239,"name":"Dmitry Tantsur","email":"dtantsur@protonmail.com","username":"dtantsur"},"change_message_id":"99bb547ee31ccf5bf23f4d5fd59d28a70a693a81","unresolved":false,"context_lines":[{"line_number":64,"context_line":"                return yaml.load(f)"},{"line_number":65,"context_line":"            # Try JSON by default"},{"line_number":66,"context_line":"            return json.load(f)"},{"line_number":67,"context_line":"    except IOError as e:"},{"line_number":68,"context_line":"        raise exc.ClientException(\u0027Can not read %(type)s file %(file)s, the \u0027"},{"line_number":69,"context_line":"                                  \u0027error is: %(err)s\u0027 %"},{"line_number":70,"context_line":"                                  {\u0027err\u0027: e, \u0027file\u0027: filename,"}],"source_content_type":"text/x-python","patch_set":6,"id":"5a9d85d2_e948ec5d","line":67,"updated":"2016-06-20 16:53:08.000000000","message":"s/IOError/EnvironmentError/ to also cover OSError","commit_id":"821f5506bbb4939e68ad1c392f00cb6a922f13fb"},{"author":{"_account_id":12356,"name":"Vladyslav Drok","email":"vdrok@mirantis.com","username":"vdrok"},"change_message_id":"02e9ed3593cd5884ca512cfc21a3c04652982ad1","unresolved":false,"context_lines":[{"line_number":64,"context_line":"                return yaml.load(f)"},{"line_number":65,"context_line":"            # Try JSON by default"},{"line_number":66,"context_line":"            return json.load(f)"},{"line_number":67,"context_line":"    except IOError as e:"},{"line_number":68,"context_line":"        raise exc.ClientException(\u0027Can not read %(type)s file %(file)s, the \u0027"},{"line_number":69,"context_line":"                                  \u0027error is: %(err)s\u0027 %"},{"line_number":70,"context_line":"                                  {\u0027err\u0027: e, \u0027file\u0027: filename,"}],"source_content_type":"text/x-python","patch_set":6,"id":"3aaa91ec_d39343ff","line":67,"in_reply_to":"5a9d85d2_e948ec5d","updated":"2016-06-27 15:08:59.000000000","message":"I think open can only raise IOError in py2, and in py3 a bunch of errors were merged into a single OSError class, with IOError being OSError synonym, so it should be OK to leave as is.","commit_id":"821f5506bbb4939e68ad1c392f00cb6a922f13fb"},{"author":{"_account_id":10239,"name":"Dmitry Tantsur","email":"dtantsur@protonmail.com","username":"dtantsur"},"change_message_id":"99bb547ee31ccf5bf23f4d5fd59d28a70a693a81","unresolved":false,"context_lines":[{"line_number":92,"context_line":"    except exc.InvalidAttribute:"},{"line_number":93,"context_line":"        raise exc.InvalidAttribute(\u0027Some of the attributes (%s) provided to \u0027"},{"line_number":94,"context_line":"                                   \u0027the client to create an ironic resource \u0027"},{"line_number":95,"context_line":"                                   \u0027are invalid.\u0027 % params)"},{"line_number":96,"context_line":"    except Exception as e:"},{"line_number":97,"context_line":"        raise exc.ClientException(\u0027Unable to create the ironic resource, the \u0027"},{"line_number":98,"context_line":"                                  \u0027error is: %s\u0027 % e)"}],"source_content_type":"text/x-python","patch_set":6,"id":"5a9d85d2_4974a09b","line":95,"updated":"2016-06-20 16:53:08.000000000","message":"please include the original exception\n\nalso nit: other messages don\u0027t include a dot in the end","commit_id":"821f5506bbb4939e68ad1c392f00cb6a922f13fb"},{"author":{"_account_id":12356,"name":"Vladyslav Drok","email":"vdrok@mirantis.com","username":"vdrok"},"change_message_id":"02e9ed3593cd5884ca512cfc21a3c04652982ad1","unresolved":false,"context_lines":[{"line_number":92,"context_line":"    except exc.InvalidAttribute:"},{"line_number":93,"context_line":"        raise exc.InvalidAttribute(\u0027Some of the attributes (%s) provided to \u0027"},{"line_number":94,"context_line":"                                   \u0027the client to create an ironic resource \u0027"},{"line_number":95,"context_line":"                                   \u0027are invalid.\u0027 % params)"},{"line_number":96,"context_line":"    except Exception as e:"},{"line_number":97,"context_line":"        raise exc.ClientException(\u0027Unable to create the ironic resource, the \u0027"},{"line_number":98,"context_line":"                                  \u0027error is: %s\u0027 % e)"}],"source_content_type":"text/x-python","patch_set":6,"id":"3aaa91ec_96c36938","line":95,"in_reply_to":"5a9d85d2_4974a09b","updated":"2016-06-27 15:08:59.000000000","message":"It is with dot as there is no exception substitution :) Done.","commit_id":"821f5506bbb4939e68ad1c392f00cb6a922f13fb"},{"author":{"_account_id":10239,"name":"Dmitry Tantsur","email":"dtantsur@protonmail.com","username":"dtantsur"},"change_message_id":"99bb547ee31ccf5bf23f4d5fd59d28a70a693a81","unresolved":false,"context_lines":[{"line_number":93,"context_line":"        raise exc.InvalidAttribute(\u0027Some of the attributes (%s) provided to \u0027"},{"line_number":94,"context_line":"                                   \u0027the client to create an ironic resource \u0027"},{"line_number":95,"context_line":"                                   \u0027are invalid.\u0027 % params)"},{"line_number":96,"context_line":"    except Exception as e:"},{"line_number":97,"context_line":"        raise exc.ClientException(\u0027Unable to create the ironic resource, the \u0027"},{"line_number":98,"context_line":"                                  \u0027error is: %s\u0027 % e)"},{"line_number":99,"context_line":""}],"source_content_type":"text/x-python","patch_set":6,"id":"5a9d85d2_29795494","line":96,"updated":"2016-06-20 16:53:08.000000000","message":"What about LOG.exception here? otherwise the failure can be pretty cryptic in case of e.g. KeyError","commit_id":"821f5506bbb4939e68ad1c392f00cb6a922f13fb"},{"author":{"_account_id":12356,"name":"Vladyslav Drok","email":"vdrok@mirantis.com","username":"vdrok"},"change_message_id":"02e9ed3593cd5884ca512cfc21a3c04652982ad1","unresolved":false,"context_lines":[{"line_number":93,"context_line":"        raise exc.InvalidAttribute(\u0027Some of the attributes (%s) provided to \u0027"},{"line_number":94,"context_line":"                                   \u0027the client to create an ironic resource \u0027"},{"line_number":95,"context_line":"                                   \u0027are invalid.\u0027 % params)"},{"line_number":96,"context_line":"    except Exception as e:"},{"line_number":97,"context_line":"        raise exc.ClientException(\u0027Unable to create the ironic resource, the \u0027"},{"line_number":98,"context_line":"                                  \u0027error is: %s\u0027 % e)"},{"line_number":99,"context_line":""}],"source_content_type":"text/x-python","patch_set":6,"id":"3aaa91ec_7654fd20","line":96,"in_reply_to":"5a9d85d2_29795494","updated":"2016-06-27 15:08:59.000000000","message":"Umm, what do you mean by LOG.exception? I don\u0027t know what to include there apart from \"Unable to create the ironic resource, the error is\" anyway, so dunno why to add a log here.","commit_id":"821f5506bbb4939e68ad1c392f00cb6a922f13fb"},{"author":{"_account_id":10239,"name":"Dmitry Tantsur","email":"dtantsur@protonmail.com","username":"dtantsur"},"change_message_id":"99bb547ee31ccf5bf23f4d5fd59d28a70a693a81","unresolved":false,"context_lines":[{"line_number":109,"context_line":"        create_method are invalid;"},{"line_number":110,"context_line":"    :raises: ClientException, if the creation of the node fails."},{"line_number":111,"context_line":"    \"\"\""},{"line_number":112,"context_line":"    params \u003d params.copy()"},{"line_number":113,"context_line":"    params.pop(\u0027ports\u0027, None)"},{"line_number":114,"context_line":"    ret \u003d client_create_handler(client.node.create, **params)"},{"line_number":115,"context_line":"    return ret.uuid"}],"source_content_type":"text/x-python","patch_set":6,"id":"5a9d85d2_896e88c7","line":112,"updated":"2016-06-20 16:53:08.000000000","message":"this is not needed for ** arguments","commit_id":"821f5506bbb4939e68ad1c392f00cb6a922f13fb"},{"author":{"_account_id":12356,"name":"Vladyslav Drok","email":"vdrok@mirantis.com","username":"vdrok"},"change_message_id":"02e9ed3593cd5884ca512cfc21a3c04652982ad1","unresolved":false,"context_lines":[{"line_number":109,"context_line":"        create_method are invalid;"},{"line_number":110,"context_line":"    :raises: ClientException, if the creation of the node fails."},{"line_number":111,"context_line":"    \"\"\""},{"line_number":112,"context_line":"    params \u003d params.copy()"},{"line_number":113,"context_line":"    params.pop(\u0027ports\u0027, None)"},{"line_number":114,"context_line":"    ret \u003d client_create_handler(client.node.create, **params)"},{"line_number":115,"context_line":"    return ret.uuid"}],"source_content_type":"text/x-python","patch_set":6,"id":"3aaa91ec_4912065a","line":112,"in_reply_to":"5a9d85d2_896e88c7","updated":"2016-06-27 15:08:59.000000000","message":"Yup, indeed.","commit_id":"821f5506bbb4939e68ad1c392f00cb6a922f13fb"},{"author":{"_account_id":10239,"name":"Dmitry Tantsur","email":"dtantsur@protonmail.com","username":"dtantsur"},"change_message_id":"99bb547ee31ccf5bf23f4d5fd59d28a70a693a81","unresolved":false,"context_lines":[{"line_number":140,"context_line":"        create_method are invalid;"},{"line_number":141,"context_line":"    :raises: ClientException, if the creation of the chassis fails."},{"line_number":142,"context_line":"    \"\"\""},{"line_number":143,"context_line":"    params \u003d params.copy()"},{"line_number":144,"context_line":"    params.pop(\u0027nodes\u0027, None)"},{"line_number":145,"context_line":"    ret \u003d client_create_handler(client.chassis.create, **params)"},{"line_number":146,"context_line":"    return ret.uuid"}],"source_content_type":"text/x-python","patch_set":6,"id":"5a9d85d2_69735cb2","line":143,"updated":"2016-06-20 16:53:08.000000000","message":"ditto","commit_id":"821f5506bbb4939e68ad1c392f00cb6a922f13fb"},{"author":{"_account_id":12356,"name":"Vladyslav Drok","email":"vdrok@mirantis.com","username":"vdrok"},"change_message_id":"02e9ed3593cd5884ca512cfc21a3c04652982ad1","unresolved":false,"context_lines":[{"line_number":140,"context_line":"        create_method are invalid;"},{"line_number":141,"context_line":"    :raises: ClientException, if the creation of the chassis fails."},{"line_number":142,"context_line":"    \"\"\""},{"line_number":143,"context_line":"    params \u003d params.copy()"},{"line_number":144,"context_line":"    params.pop(\u0027nodes\u0027, None)"},{"line_number":145,"context_line":"    ret \u003d client_create_handler(client.chassis.create, **params)"},{"line_number":146,"context_line":"    return ret.uuid"}],"source_content_type":"text/x-python","patch_set":6,"id":"3aaa91ec_290fba2f","line":143,"in_reply_to":"5a9d85d2_69735cb2","updated":"2016-06-27 15:08:59.000000000","message":"Done","commit_id":"821f5506bbb4939e68ad1c392f00cb6a922f13fb"},{"author":{"_account_id":10239,"name":"Dmitry Tantsur","email":"dtantsur@protonmail.com","username":"dtantsur"},"change_message_id":"99bb547ee31ccf5bf23f4d5fd59d28a70a693a81","unresolved":false,"context_lines":[{"line_number":146,"context_line":"    return ret.uuid"},{"line_number":147,"context_line":""},{"line_number":148,"context_line":""},{"line_number":149,"context_line":"def create_single_handler(create_method, errors, client, **params):"},{"line_number":150,"context_line":"    \"\"\"Catch errors of the creation of a single resource."},{"line_number":151,"context_line":""},{"line_number":152,"context_line":"    :param create_method: method to catch exceptions from;"}],"source_content_type":"text/x-python","patch_set":6,"id":"5a9d85d2_c96890bd","line":149,"updated":"2016-06-20 16:53:08.000000000","message":"we have client_create_handler, why do we need this one?","commit_id":"821f5506bbb4939e68ad1c392f00cb6a922f13fb"},{"author":{"_account_id":12356,"name":"Vladyslav Drok","email":"vdrok@mirantis.com","username":"vdrok"},"change_message_id":"02e9ed3593cd5884ca512cfc21a3c04652982ad1","unresolved":false,"context_lines":[{"line_number":146,"context_line":"    return ret.uuid"},{"line_number":147,"context_line":""},{"line_number":148,"context_line":""},{"line_number":149,"context_line":"def create_single_handler(create_method, errors, client, **params):"},{"line_number":150,"context_line":"    \"\"\"Catch errors of the creation of a single resource."},{"line_number":151,"context_line":""},{"line_number":152,"context_line":"    :param create_method: method to catch exceptions from;"}],"source_content_type":"text/x-python","patch_set":6,"id":"3aaa91ec_29505a5e","line":149,"in_reply_to":"5a9d85d2_c96890bd","updated":"2016-06-27 15:08:59.000000000","message":"client_create_handler does excrption type conversion and adds more detail about the reason of an exception. This one accumulates the errors in the array. It is needed to avoid doing\n\n try:\n   ...\n except ...:\n   ...\n\nin every of the create_ports/nodes/chassis methods. It needs to be present in all the methods as we don\u0027t want to stop the creation on the first error.\n\nFor example we create 3 chassis with 3 nodes each and each node having 2 ports, if first chassis create fails, we skip creating first 3 nodes and all their ports; the second chassis created successfully, but the second node creation in this chassis fails, we want to proceed with 3d node in this chassis. Same for ports.","commit_id":"821f5506bbb4939e68ad1c392f00cb6a922f13fb"},{"author":{"_account_id":6618,"name":"Ruby Loo","email":"opensrloo@gmail.com","username":"rloo"},"change_message_id":"1479a7f93538ef96313ed8c32671ae84c1886b80","unresolved":false,"context_lines":[{"line_number":43,"context_line":""},{"line_number":44,"context_line":"@cliutils.arg(\u0027resources_files\u0027, nargs\u003d\u0027+\u0027, metavar\u003d\u0027\u003cfile\u003e\u0027, action\u003d\u0027append\u0027,"},{"line_number":45,"context_line":"              default\u003d[], help\u003d\u0027One or more files containing descriptions of \u0027"},{"line_number":46,"context_line":"                               \u0027the resources to create.\u0027)"},{"line_number":47,"context_line":"def do_create(cc, args):"},{"line_number":48,"context_line":"    \"\"\"Create resources using their JSON or YAML descriptions."},{"line_number":49,"context_line":""}],"source_content_type":"text/x-python","patch_set":8,"id":"3aaa91ec_be06011e","line":46,"updated":"2016-06-29 01:41:46.000000000","message":"Might be useful (I know, it\u0027ll be long) to indicate that they should be .yaml or .json.\n\nI looked at how we described \u0027ironic node-delete\u0027 (because it can take one or more uuids) and the help describes one uuid, but the help for some other commands (that can specify one or more fields) describes one field but mentions that more can be specified. Sigh.\n\nSo something like \u0027File (.yaml or .json) containing descriptions of the resources to create. Can be specified multiple times.\u0027 ?","commit_id":"3dc8b78c5b30e0c59916558cc807a7a4967608c1"},{"author":{"_account_id":12356,"name":"Vladyslav Drok","email":"vdrok@mirantis.com","username":"vdrok"},"change_message_id":"4800db2230f224af19a8b5be269897201e78614a","unresolved":false,"context_lines":[{"line_number":43,"context_line":""},{"line_number":44,"context_line":"@cliutils.arg(\u0027resources_files\u0027, nargs\u003d\u0027+\u0027, metavar\u003d\u0027\u003cfile\u003e\u0027, action\u003d\u0027append\u0027,"},{"line_number":45,"context_line":"              default\u003d[], help\u003d\u0027One or more files containing descriptions of \u0027"},{"line_number":46,"context_line":"                               \u0027the resources to create.\u0027)"},{"line_number":47,"context_line":"def do_create(cc, args):"},{"line_number":48,"context_line":"    \"\"\"Create resources using their JSON or YAML descriptions."},{"line_number":49,"context_line":""}],"source_content_type":"text/x-python","patch_set":8,"id":"3aaa91ec_7d757196","line":46,"in_reply_to":"3aaa91ec_be06011e","updated":"2016-06-30 12:08:13.000000000","message":"Done","commit_id":"3dc8b78c5b30e0c59916558cc807a7a4967608c1"},{"author":{"_account_id":6618,"name":"Ruby Loo","email":"opensrloo@gmail.com","username":"rloo"},"change_message_id":"1479a7f93538ef96313ed8c32671ae84c1886b80","unresolved":false,"context_lines":[{"line_number":50,"context_line":"    This functions tries to create all the resources it can, printing all the"},{"line_number":51,"context_line":"    errors. If any of the files fail to validate against the schema, resource"},{"line_number":52,"context_line":"    creation does not happen."},{"line_number":53,"context_line":"    \"\"\""},{"line_number":54,"context_line":"    errors \u003d []"},{"line_number":55,"context_line":"    resources \u003d []"},{"line_number":56,"context_line":"    for resource_file in args.resources_files[0]:"}],"source_content_type":"text/x-python","patch_set":8,"id":"3aaa91ec_7920334a","line":53,"updated":"2016-06-29 01:41:46.000000000","message":"This docstring will show up if you do an \u0027ironic help create\u0027, so we should try to elaborate on this. [I\u0027ll try to suggest something later.]","commit_id":"3dc8b78c5b30e0c59916558cc807a7a4967608c1"},{"author":{"_account_id":6618,"name":"Ruby Loo","email":"opensrloo@gmail.com","username":"rloo"},"change_message_id":"1479a7f93538ef96313ed8c32671ae84c1886b80","unresolved":false,"context_lines":[{"line_number":62,"context_line":"            errors.append(e)"},{"line_number":63,"context_line":"    if errors:"},{"line_number":64,"context_line":"        raise exc.ClientException(\u0027During resources files validation, the \u0027"},{"line_number":65,"context_line":"                                  \u0027following errors appeared:\\n%s\u0027 %"},{"line_number":66,"context_line":"                                  \u0027\\n\u0027.join(six.text_type(e) for e in errors))"},{"line_number":67,"context_line":"    for r in resources:"},{"line_number":68,"context_line":"        create_chassis(cc, r.get(\u0027chassis\u0027, []), errors)"}],"source_content_type":"text/x-python","patch_set":8,"id":"3aaa91ec_6b217afc","line":65,"updated":"2016-06-29 01:41:46.000000000","message":"I\u0027m not sure we need to mention \u0027During resources files validation\u0027. Does the user care (or understand) ? How about \u0027The following error(s) were encountered:\u0027","commit_id":"3dc8b78c5b30e0c59916558cc807a7a4967608c1"},{"author":{"_account_id":12356,"name":"Vladyslav Drok","email":"vdrok@mirantis.com","username":"vdrok"},"change_message_id":"4800db2230f224af19a8b5be269897201e78614a","unresolved":false,"context_lines":[{"line_number":62,"context_line":"            errors.append(e)"},{"line_number":63,"context_line":"    if errors:"},{"line_number":64,"context_line":"        raise exc.ClientException(\u0027During resources files validation, the \u0027"},{"line_number":65,"context_line":"                                  \u0027following errors appeared:\\n%s\u0027 %"},{"line_number":66,"context_line":"                                  \u0027\\n\u0027.join(six.text_type(e) for e in errors))"},{"line_number":67,"context_line":"    for r in resources:"},{"line_number":68,"context_line":"        create_chassis(cc, r.get(\u0027chassis\u0027, []), errors)"}],"source_content_type":"text/x-python","patch_set":8,"id":"3aaa91ec_3d492961","line":65,"in_reply_to":"3aaa91ec_6b217afc","updated":"2016-06-30 12:08:13.000000000","message":"I think yes, it will give a notion to the user that some of the files are wrong, I\u0027ll add the details of how they are validated to the docs.","commit_id":"3dc8b78c5b30e0c59916558cc807a7a4967608c1"},{"author":{"_account_id":6618,"name":"Ruby Loo","email":"opensrloo@gmail.com","username":"rloo"},"change_message_id":"1479a7f93538ef96313ed8c32671ae84c1886b80","unresolved":false,"context_lines":[{"line_number":70,"context_line":"    if errors:"},{"line_number":71,"context_line":"        raise exc.ClientException(\u0027During resources creation, the following \u0027"},{"line_number":72,"context_line":"                                  \u0027errors appeared:\\n%s\u0027 %"},{"line_number":73,"context_line":"                                  \u0027\\n\u0027.join(six.text_type(e) for e in errors))"},{"line_number":74,"context_line":""},{"line_number":75,"context_line":""},{"line_number":76,"context_line":"def load_from_file(filename):"}],"source_content_type":"text/x-python","patch_set":8,"id":"3aaa91ec_eb90b150","line":73,"updated":"2016-06-29 01:41:46.000000000","message":"Ditto about the msg.\n\nAt this point, though, some things might have actually been created, right? So we might want to distinguish the two types of errors by eg \u0027nothing was created\u0027 versus \u0027something? might have been created\u0027. Would it be worth keeping track of what was created, or whether anything was created? or maybe the errors will inform as to what was NOT created...","commit_id":"3dc8b78c5b30e0c59916558cc807a7a4967608c1"},{"author":{"_account_id":12356,"name":"Vladyslav Drok","email":"vdrok@mirantis.com","username":"vdrok"},"change_message_id":"4800db2230f224af19a8b5be269897201e78614a","unresolved":false,"context_lines":[{"line_number":70,"context_line":"    if errors:"},{"line_number":71,"context_line":"        raise exc.ClientException(\u0027During resources creation, the following \u0027"},{"line_number":72,"context_line":"                                  \u0027errors appeared:\\n%s\u0027 %"},{"line_number":73,"context_line":"                                  \u0027\\n\u0027.join(six.text_type(e) for e in errors))"},{"line_number":74,"context_line":""},{"line_number":75,"context_line":""},{"line_number":76,"context_line":"def load_from_file(filename):"}],"source_content_type":"text/x-python","patch_set":8,"id":"3aaa91ec_7d83b156","line":73,"in_reply_to":"3aaa91ec_eb90b150","updated":"2016-06-30 12:08:13.000000000","message":"Well, I think it would be too much :) Errors will tell what are the things that were not created (it is inside the exception messages already).","commit_id":"3dc8b78c5b30e0c59916558cc807a7a4967608c1"},{"author":{"_account_id":6618,"name":"Ruby Loo","email":"opensrloo@gmail.com","username":"rloo"},"change_message_id":"1479a7f93538ef96313ed8c32671ae84c1886b80","unresolved":false,"context_lines":[{"line_number":77,"context_line":"    \"\"\"Deserialize JSON or YAML from file."},{"line_number":78,"context_line":""},{"line_number":79,"context_line":"    :param filename: name of the file containing JSON or YAML;"},{"line_number":80,"context_line":"    :returns: a dictionary deserialized from JSON or YAML;"},{"line_number":81,"context_line":"    :raises: ClientException if the file can not be loaded or if its contents"},{"line_number":82,"context_line":"        is not a valid JSON or YAML, or if the file extension is not supported."},{"line_number":83,"context_line":"    \"\"\""}],"source_content_type":"text/x-python","patch_set":8,"id":"3aaa91ec_0e828452","line":80,"updated":"2016-06-29 01:41:46.000000000","message":"nit: do we tend to add \u0027;\u0027 at the end?","commit_id":"3dc8b78c5b30e0c59916558cc807a7a4967608c1"},{"author":{"_account_id":12356,"name":"Vladyslav Drok","email":"vdrok@mirantis.com","username":"vdrok"},"change_message_id":"4800db2230f224af19a8b5be269897201e78614a","unresolved":false,"context_lines":[{"line_number":77,"context_line":"    \"\"\"Deserialize JSON or YAML from file."},{"line_number":78,"context_line":""},{"line_number":79,"context_line":"    :param filename: name of the file containing JSON or YAML;"},{"line_number":80,"context_line":"    :returns: a dictionary deserialized from JSON or YAML;"},{"line_number":81,"context_line":"    :raises: ClientException if the file can not be loaded or if its contents"},{"line_number":82,"context_line":"        is not a valid JSON or YAML, or if the file extension is not supported."},{"line_number":83,"context_line":"    \"\"\""}],"source_content_type":"text/x-python","patch_set":8,"id":"3aaa91ec_ddcc658b","line":80,"in_reply_to":"3aaa91ec_0e828452","updated":"2016-06-30 12:08:13.000000000","message":"Done","commit_id":"3dc8b78c5b30e0c59916558cc807a7a4967608c1"},{"author":{"_account_id":6618,"name":"Ruby Loo","email":"opensrloo@gmail.com","username":"rloo"},"change_message_id":"1479a7f93538ef96313ed8c32671ae84c1886b80","unresolved":false,"context_lines":[{"line_number":88,"context_line":"            elif filename.endswith(\u0027.json\u0027):"},{"line_number":89,"context_line":"                return json.load(f)"},{"line_number":90,"context_line":"    except IOError as e:"},{"line_number":91,"context_line":"        raise exc.ClientException(\u0027Can not read resource file %(file)s, the \u0027"},{"line_number":92,"context_line":"                                  \u0027error is: %(err)s\u0027 %"},{"line_number":93,"context_line":"                                  {\u0027err\u0027: e, \u0027file\u0027: filename})"},{"line_number":94,"context_line":"    except (ValueError, yaml.YAMLError) as e:"}],"source_content_type":"text/x-python","patch_set":8,"id":"3aaa91ec_2ee020fa","line":91,"updated":"2016-06-29 01:41:46.000000000","message":"s/%(file)s/\"%(file)s\"/\n\nI\u0027d probably s/resource file/file/ (because the user knows it is a file and I\u0027m not sure they care that we consider it a resource file).","commit_id":"3dc8b78c5b30e0c59916558cc807a7a4967608c1"},{"author":{"_account_id":12356,"name":"Vladyslav Drok","email":"vdrok@mirantis.com","username":"vdrok"},"change_message_id":"4800db2230f224af19a8b5be269897201e78614a","unresolved":false,"context_lines":[{"line_number":88,"context_line":"            elif filename.endswith(\u0027.json\u0027):"},{"line_number":89,"context_line":"                return json.load(f)"},{"line_number":90,"context_line":"    except IOError as e:"},{"line_number":91,"context_line":"        raise exc.ClientException(\u0027Can not read resource file %(file)s, the \u0027"},{"line_number":92,"context_line":"                                  \u0027error is: %(err)s\u0027 %"},{"line_number":93,"context_line":"                                  {\u0027err\u0027: e, \u0027file\u0027: filename})"},{"line_number":94,"context_line":"    except (ValueError, yaml.YAMLError) as e:"}],"source_content_type":"text/x-python","patch_set":8,"id":"3aaa91ec_a837994b","line":91,"in_reply_to":"3aaa91ec_2ee020fa","updated":"2016-06-30 12:08:13.000000000","message":"Done","commit_id":"3dc8b78c5b30e0c59916558cc807a7a4967608c1"},{"author":{"_account_id":6618,"name":"Ruby Loo","email":"opensrloo@gmail.com","username":"rloo"},"change_message_id":"1479a7f93538ef96313ed8c32671ae84c1886b80","unresolved":false,"context_lines":[{"line_number":89,"context_line":"                return json.load(f)"},{"line_number":90,"context_line":"    except IOError as e:"},{"line_number":91,"context_line":"        raise exc.ClientException(\u0027Can not read resource file %(file)s, the \u0027"},{"line_number":92,"context_line":"                                  \u0027error is: %(err)s\u0027 %"},{"line_number":93,"context_line":"                                  {\u0027err\u0027: e, \u0027file\u0027: filename})"},{"line_number":94,"context_line":"    except (ValueError, yaml.YAMLError) as e:"},{"line_number":95,"context_line":"        # json.load raises only ValueError"}],"source_content_type":"text/x-python","patch_set":8,"id":"3aaa91ec_6e90684f","line":92,"updated":"2016-06-29 01:41:46.000000000","message":"maybe \u0027Cannot read file \u003cfile\u003e due to: \u003cerror\u003e\u0027?","commit_id":"3dc8b78c5b30e0c59916558cc807a7a4967608c1"},{"author":{"_account_id":12356,"name":"Vladyslav Drok","email":"vdrok@mirantis.com","username":"vdrok"},"change_message_id":"4800db2230f224af19a8b5be269897201e78614a","unresolved":false,"context_lines":[{"line_number":89,"context_line":"                return json.load(f)"},{"line_number":90,"context_line":"    except IOError as e:"},{"line_number":91,"context_line":"        raise exc.ClientException(\u0027Can not read resource file %(file)s, the \u0027"},{"line_number":92,"context_line":"                                  \u0027error is: %(err)s\u0027 %"},{"line_number":93,"context_line":"                                  {\u0027err\u0027: e, \u0027file\u0027: filename})"},{"line_number":94,"context_line":"    except (ValueError, yaml.YAMLError) as e:"},{"line_number":95,"context_line":"        # json.load raises only ValueError"}],"source_content_type":"text/x-python","patch_set":8,"id":"3aaa91ec_c832e55d","line":92,"in_reply_to":"3aaa91ec_6e90684f","updated":"2016-06-30 12:08:13.000000000","message":"Done","commit_id":"3dc8b78c5b30e0c59916558cc807a7a4967608c1"},{"author":{"_account_id":6618,"name":"Ruby Loo","email":"opensrloo@gmail.com","username":"rloo"},"change_message_id":"1479a7f93538ef96313ed8c32671ae84c1886b80","unresolved":false,"context_lines":[{"line_number":94,"context_line":"    except (ValueError, yaml.YAMLError) as e:"},{"line_number":95,"context_line":"        # json.load raises only ValueError"},{"line_number":96,"context_line":"        raise exc.ClientException(\u0027Resource file %(file)s being used is \u0027"},{"line_number":97,"context_line":"                                  \u0027invalid, the error is: %(err)s\u0027 %"},{"line_number":98,"context_line":"                                  {\u0027err\u0027: e, \u0027file\u0027: filename})"},{"line_number":99,"context_line":"    # Resources file is neither .json, nor .yaml, raise an exception"},{"line_number":100,"context_line":"    raise exc.ClientException(\u0027Resource file %(file)s, should have either \u0027"}],"source_content_type":"text/x-python","patch_set":8,"id":"3aaa91ec_7d2f5f3e","line":97,"updated":"2016-06-29 01:41:46.000000000","message":"Maybe \u0027File \"\u003cfile\u003e\" is invalid due to: \u003cerror\u003e\u0027.","commit_id":"3dc8b78c5b30e0c59916558cc807a7a4967608c1"},{"author":{"_account_id":12356,"name":"Vladyslav Drok","email":"vdrok@mirantis.com","username":"vdrok"},"change_message_id":"4800db2230f224af19a8b5be269897201e78614a","unresolved":false,"context_lines":[{"line_number":94,"context_line":"    except (ValueError, yaml.YAMLError) as e:"},{"line_number":95,"context_line":"        # json.load raises only ValueError"},{"line_number":96,"context_line":"        raise exc.ClientException(\u0027Resource file %(file)s being used is \u0027"},{"line_number":97,"context_line":"                                  \u0027invalid, the error is: %(err)s\u0027 %"},{"line_number":98,"context_line":"                                  {\u0027err\u0027: e, \u0027file\u0027: filename})"},{"line_number":99,"context_line":"    # Resources file is neither .json, nor .yaml, raise an exception"},{"line_number":100,"context_line":"    raise exc.ClientException(\u0027Resource file %(file)s, should have either \u0027"}],"source_content_type":"text/x-python","patch_set":8,"id":"3aaa91ec_2849e9b7","line":97,"in_reply_to":"3aaa91ec_7d2f5f3e","updated":"2016-06-30 12:08:13.000000000","message":"Done","commit_id":"3dc8b78c5b30e0c59916558cc807a7a4967608c1"},{"author":{"_account_id":6618,"name":"Ruby Loo","email":"opensrloo@gmail.com","username":"rloo"},"change_message_id":"1479a7f93538ef96313ed8c32671ae84c1886b80","unresolved":false,"context_lines":[{"line_number":97,"context_line":"                                  \u0027invalid, the error is: %(err)s\u0027 %"},{"line_number":98,"context_line":"                                  {\u0027err\u0027: e, \u0027file\u0027: filename})"},{"line_number":99,"context_line":"    # Resources file is neither .json, nor .yaml, raise an exception"},{"line_number":100,"context_line":"    raise exc.ClientException(\u0027Resource file %(file)s, should have either \u0027"},{"line_number":101,"context_line":"                              \u0027.json or .yaml extension so that client is \u0027"},{"line_number":102,"context_line":"                              \u0027able to determine how to deserialize it.\u0027 %"},{"line_number":103,"context_line":"                              {\u0027file\u0027: filename})"}],"source_content_type":"text/x-python","patch_set":8,"id":"3aaa91ec_eedf380a","line":100,"updated":"2016-06-29 01:41:46.000000000","message":"I would have preferred that we checked for .json or .yaml first, before even trying to open the file etc, but I suppose this is OK. (It is a bit harder to read/follow though. Maybe this should be after line 89 instead of here.)","commit_id":"3dc8b78c5b30e0c59916558cc807a7a4967608c1"},{"author":{"_account_id":12356,"name":"Vladyslav Drok","email":"vdrok@mirantis.com","username":"vdrok"},"change_message_id":"4800db2230f224af19a8b5be269897201e78614a","unresolved":false,"context_lines":[{"line_number":97,"context_line":"                                  \u0027invalid, the error is: %(err)s\u0027 %"},{"line_number":98,"context_line":"                                  {\u0027err\u0027: e, \u0027file\u0027: filename})"},{"line_number":99,"context_line":"    # Resources file is neither .json, nor .yaml, raise an exception"},{"line_number":100,"context_line":"    raise exc.ClientException(\u0027Resource file %(file)s, should have either \u0027"},{"line_number":101,"context_line":"                              \u0027.json or .yaml extension so that client is \u0027"},{"line_number":102,"context_line":"                              \u0027able to determine how to deserialize it.\u0027 %"},{"line_number":103,"context_line":"                              {\u0027file\u0027: filename})"}],"source_content_type":"text/x-python","patch_set":8,"id":"3aaa91ec_0804ed47","line":100,"in_reply_to":"3aaa91ec_eedf380a","updated":"2016-06-30 12:08:13.000000000","message":"Done","commit_id":"3dc8b78c5b30e0c59916558cc807a7a4967608c1"},{"author":{"_account_id":6618,"name":"Ruby Loo","email":"opensrloo@gmail.com","username":"rloo"},"change_message_id":"1479a7f93538ef96313ed8c32671ae84c1886b80","unresolved":false,"context_lines":[{"line_number":99,"context_line":"    # Resources file is neither .json, nor .yaml, raise an exception"},{"line_number":100,"context_line":"    raise exc.ClientException(\u0027Resource file %(file)s, should have either \u0027"},{"line_number":101,"context_line":"                              \u0027.json or .yaml extension so that client is \u0027"},{"line_number":102,"context_line":"                              \u0027able to determine how to deserialize it.\u0027 %"},{"line_number":103,"context_line":"                              {\u0027file\u0027: filename})"},{"line_number":104,"context_line":""},{"line_number":105,"context_line":""}],"source_content_type":"text/x-python","patch_set":8,"id":"3aaa91ec_2ea2e04b","line":102,"updated":"2016-06-29 01:41:46.000000000","message":"I don\u0027t think we need to mention that we want the extension to be able to deserialize it. This might be sufficient: \u0027Cannot process file \u003cfile\u003e; it must have .json or .yaml extension.\u0027 Or s/must/doesn\u0027t/ ?","commit_id":"3dc8b78c5b30e0c59916558cc807a7a4967608c1"},{"author":{"_account_id":12356,"name":"Vladyslav Drok","email":"vdrok@mirantis.com","username":"vdrok"},"change_message_id":"4800db2230f224af19a8b5be269897201e78614a","unresolved":false,"context_lines":[{"line_number":99,"context_line":"    # Resources file is neither .json, nor .yaml, raise an exception"},{"line_number":100,"context_line":"    raise exc.ClientException(\u0027Resource file %(file)s, should have either \u0027"},{"line_number":101,"context_line":"                              \u0027.json or .yaml extension so that client is \u0027"},{"line_number":102,"context_line":"                              \u0027able to determine how to deserialize it.\u0027 %"},{"line_number":103,"context_line":"                              {\u0027file\u0027: filename})"},{"line_number":104,"context_line":""},{"line_number":105,"context_line":""}],"source_content_type":"text/x-python","patch_set":8,"id":"3aaa91ec_88329d0e","line":102,"in_reply_to":"3aaa91ec_2ea2e04b","updated":"2016-06-30 12:08:13.000000000","message":"Done","commit_id":"3dc8b78c5b30e0c59916558cc807a7a4967608c1"},{"author":{"_account_id":6618,"name":"Ruby Loo","email":"opensrloo@gmail.com","username":"rloo"},"change_message_id":"1479a7f93538ef96313ed8c32671ae84c1886b80","unresolved":false,"context_lines":[{"line_number":110,"context_line":"    :param params: dictionary to be POSTed to a corresponding endpoint;"},{"line_number":111,"context_line":"    :returns: the result of the create_method."},{"line_number":112,"context_line":"    :raises: InvalidAttribute, if some parameters passed to create_method are"},{"line_number":113,"context_line":"        invalid;"},{"line_number":114,"context_line":"    :raises: ClientException, if the creation of the resource fails."},{"line_number":115,"context_line":"    \"\"\""},{"line_number":116,"context_line":"    try:"}],"source_content_type":"text/x-python","patch_set":8,"id":"3aaa91ec_5dc5433a","line":113,"updated":"2016-06-29 01:41:46.000000000","message":"how about \u0027if one or more parameters (keys in params dictionary) are not needed for creating the resource\u0027","commit_id":"3dc8b78c5b30e0c59916558cc807a7a4967608c1"},{"author":{"_account_id":12356,"name":"Vladyslav Drok","email":"vdrok@mirantis.com","username":"vdrok"},"change_message_id":"4800db2230f224af19a8b5be269897201e78614a","unresolved":false,"context_lines":[{"line_number":110,"context_line":"    :param params: dictionary to be POSTed to a corresponding endpoint;"},{"line_number":111,"context_line":"    :returns: the result of the create_method."},{"line_number":112,"context_line":"    :raises: InvalidAttribute, if some parameters passed to create_method are"},{"line_number":113,"context_line":"        invalid;"},{"line_number":114,"context_line":"    :raises: ClientException, if the creation of the resource fails."},{"line_number":115,"context_line":"    \"\"\""},{"line_number":116,"context_line":"    try:"}],"source_content_type":"text/x-python","patch_set":8,"id":"3aaa91ec_c306461b","line":113,"in_reply_to":"3aaa91ec_5dc5433a","updated":"2016-06-30 12:08:13.000000000","message":"Dunno, in case of chassis create there are no parameters needed at all, the exception will appear only if the attribute is unknown to the client \u003d\u003e invalid, that was my logic :)","commit_id":"3dc8b78c5b30e0c59916558cc807a7a4967608c1"},{"author":{"_account_id":6618,"name":"Ruby Loo","email":"opensrloo@gmail.com","username":"rloo"},"change_message_id":"1479a7f93538ef96313ed8c32671ae84c1886b80","unresolved":false,"context_lines":[{"line_number":120,"context_line":"                                   \u0027provided to the client to create an \u0027"},{"line_number":121,"context_line":"                                   \u0027ironic resource are invalid, the error \u0027"},{"line_number":122,"context_line":"                                   \u0027is: %(err)s\u0027 % {\u0027params\u0027: params,"},{"line_number":123,"context_line":"                                                    \u0027err\u0027: e})"},{"line_number":124,"context_line":"    except Exception as e:"},{"line_number":125,"context_line":"        raise exc.ClientException(\u0027Unable to create the ironic resource, the \u0027"},{"line_number":126,"context_line":"                                  \u0027error is: %s\u0027 % e)"}],"source_content_type":"text/x-python","patch_set":8,"id":"3aaa91ec_2fe8fe0f","line":123,"updated":"2016-06-29 01:41:46.000000000","message":"It would be better to indicate which attribute is wrong. Which is a separate bug; to get e to have something useful. (It is currently useless). I\u0027ll think of something to say once I fix e.","commit_id":"3dc8b78c5b30e0c59916558cc807a7a4967608c1"},{"author":{"_account_id":6618,"name":"Ruby Loo","email":"opensrloo@gmail.com","username":"rloo"},"change_message_id":"dd946d09a0292edeea88638349e1337d6ea08afa","unresolved":false,"context_lines":[{"line_number":120,"context_line":"                                   \u0027provided to the client to create an \u0027"},{"line_number":121,"context_line":"                                   \u0027ironic resource are invalid, the error \u0027"},{"line_number":122,"context_line":"                                   \u0027is: %(err)s\u0027 % {\u0027params\u0027: params,"},{"line_number":123,"context_line":"                                                    \u0027err\u0027: e})"},{"line_number":124,"context_line":"    except Exception as e:"},{"line_number":125,"context_line":"        raise exc.ClientException(\u0027Unable to create the ironic resource, the \u0027"},{"line_number":126,"context_line":"                                  \u0027error is: %s\u0027 % e)"}],"source_content_type":"text/x-python","patch_set":8,"id":"3aaa91ec_12e1e59a","line":123,"in_reply_to":"3aaa91ec_2fe8fe0f","updated":"2016-06-29 02:35:24.000000000","message":"I changed it so that the exception includes the list of invalid parameters and why they are invalid (https://review.openstack.org/335281).\n\nI think it would be useful to print out params so the user can figure out which resource it is that is wrong. Maybe this can be \u0027Cannot create resource with specified attributes \u003cparams\u003e. \u003cerr\u003e.\u0027\n\nMight actually be useful to pass the type of resource into this method, so it could say \u0027node\u0027 (or \u0027chassis\u0027 or \u0027port\u0027) instead of \u0027resource\u0027 in the error string.\n\nhttps://review.openstack.org/335281","commit_id":"3dc8b78c5b30e0c59916558cc807a7a4967608c1"},{"author":{"_account_id":6618,"name":"Ruby Loo","email":"opensrloo@gmail.com","username":"rloo"},"change_message_id":"1479a7f93538ef96313ed8c32671ae84c1886b80","unresolved":false,"context_lines":[{"line_number":123,"context_line":"                                                    \u0027err\u0027: e})"},{"line_number":124,"context_line":"    except Exception as e:"},{"line_number":125,"context_line":"        raise exc.ClientException(\u0027Unable to create the ironic resource, the \u0027"},{"line_number":126,"context_line":"                                  \u0027error is: %s\u0027 % e)"},{"line_number":127,"context_line":""},{"line_number":128,"context_line":""},{"line_number":129,"context_line":"def create_single_node(client, **params):"}],"source_content_type":"text/x-python","patch_set":8,"id":"3aaa91ec_8fcdb2b9","line":126,"updated":"2016-06-29 01:41:46.000000000","message":"Might be useful to output the params, so that the user will know which resource it is. Unless e is useful.","commit_id":"3dc8b78c5b30e0c59916558cc807a7a4967608c1"},{"author":{"_account_id":12356,"name":"Vladyslav Drok","email":"vdrok@mirantis.com","username":"vdrok"},"change_message_id":"4800db2230f224af19a8b5be269897201e78614a","unresolved":false,"context_lines":[{"line_number":123,"context_line":"                                                    \u0027err\u0027: e})"},{"line_number":124,"context_line":"    except Exception as e:"},{"line_number":125,"context_line":"        raise exc.ClientException(\u0027Unable to create the ironic resource, the \u0027"},{"line_number":126,"context_line":"                                  \u0027error is: %s\u0027 % e)"},{"line_number":127,"context_line":""},{"line_number":128,"context_line":""},{"line_number":129,"context_line":"def create_single_node(client, **params):"}],"source_content_type":"text/x-python","patch_set":8,"id":"3aaa91ec_23158ae4","line":126,"in_reply_to":"3aaa91ec_8fcdb2b9","updated":"2016-06-30 12:08:13.000000000","message":"Done","commit_id":"3dc8b78c5b30e0c59916558cc807a7a4967608c1"},{"author":{"_account_id":6618,"name":"Ruby Loo","email":"opensrloo@gmail.com","username":"rloo"},"change_message_id":"1479a7f93538ef96313ed8c32671ae84c1886b80","unresolved":false,"context_lines":[{"line_number":180,"context_line":"    :param client: ironic client instance;"},{"line_number":181,"context_line":"    :param params: dictionary containing the representation of the resource"},{"line_number":182,"context_line":"        being created;"},{"line_number":183,"context_line":"    :returns: the result of the create_method or None if exception appears."},{"line_number":184,"context_line":"    \"\"\""},{"line_number":185,"context_line":"    try:"},{"line_number":186,"context_line":"        return create_method(client, **params)"}],"source_content_type":"text/x-python","patch_set":8,"id":"3aaa91ec_0b409da4","line":183,"updated":"2016-06-29 01:41:46.000000000","message":"Probably should mention that if there is an exception, it will be appended to errors.","commit_id":"3dc8b78c5b30e0c59916558cc807a7a4967608c1"},{"author":{"_account_id":12356,"name":"Vladyslav Drok","email":"vdrok@mirantis.com","username":"vdrok"},"change_message_id":"4800db2230f224af19a8b5be269897201e78614a","unresolved":false,"context_lines":[{"line_number":180,"context_line":"    :param client: ironic client instance;"},{"line_number":181,"context_line":"    :param params: dictionary containing the representation of the resource"},{"line_number":182,"context_line":"        being created;"},{"line_number":183,"context_line":"    :returns: the result of the create_method or None if exception appears."},{"line_number":184,"context_line":"    \"\"\""},{"line_number":185,"context_line":"    try:"},{"line_number":186,"context_line":"        return create_method(client, **params)"}],"source_content_type":"text/x-python","patch_set":8,"id":"3aaa91ec_2350ead3","line":183,"in_reply_to":"3aaa91ec_0b409da4","updated":"2016-06-30 12:08:13.000000000","message":"Done","commit_id":"3dc8b78c5b30e0c59916558cc807a7a4967608c1"},{"author":{"_account_id":6618,"name":"Ruby Loo","email":"opensrloo@gmail.com","username":"rloo"},"change_message_id":"1479a7f93538ef96313ed8c32671ae84c1886b80","unresolved":false,"context_lines":[{"line_number":198,"context_line":"    :param node_uuid: UUID of a node the ports should be associated with."},{"line_number":199,"context_line":"    \"\"\""},{"line_number":200,"context_line":"    for port in port_list:"},{"line_number":201,"context_line":"        port[\u0027node_uuid\u0027] \u003d node_uuid"},{"line_number":202,"context_line":"        create_single_handler(create_single_port, errors, client, **port)"},{"line_number":203,"context_line":""},{"line_number":204,"context_line":""}],"source_content_type":"text/x-python","patch_set":8,"id":"3aaa91ec_8e05bbc3","line":201,"updated":"2016-06-29 01:41:46.000000000","message":"so here you don\u0027t check to see if port[\u0027node_uuid\u0027] exists and whether it is not the same as node_uuid, whereas you checked in the node/chassis case.","commit_id":"3dc8b78c5b30e0c59916558cc807a7a4967608c1"},{"author":{"_account_id":12356,"name":"Vladyslav Drok","email":"vdrok@mirantis.com","username":"vdrok"},"change_message_id":"4800db2230f224af19a8b5be269897201e78614a","unresolved":false,"context_lines":[{"line_number":198,"context_line":"    :param node_uuid: UUID of a node the ports should be associated with."},{"line_number":199,"context_line":"    \"\"\""},{"line_number":200,"context_line":"    for port in port_list:"},{"line_number":201,"context_line":"        port[\u0027node_uuid\u0027] \u003d node_uuid"},{"line_number":202,"context_line":"        create_single_handler(create_single_port, errors, client, **port)"},{"line_number":203,"context_line":""},{"line_number":204,"context_line":""}],"source_content_type":"text/x-python","patch_set":8,"id":"3aaa91ec_03fb2ec2","line":201,"in_reply_to":"3aaa91ec_8e05bbc3","updated":"2016-06-30 12:08:13.000000000","message":"Yeah, makes sense to check it here too.","commit_id":"3dc8b78c5b30e0c59916558cc807a7a4967608c1"},{"author":{"_account_id":6618,"name":"Ruby Loo","email":"opensrloo@gmail.com","username":"rloo"},"change_message_id":"1479a7f93538ef96313ed8c32671ae84c1886b80","unresolved":false,"context_lines":[{"line_number":203,"context_line":""},{"line_number":204,"context_line":""},{"line_number":205,"context_line":"def create_nodes(client, node_list, errors, chassis_uuid\u003dNone):"},{"line_number":206,"context_line":"    \"\"\"Create chassis from dictionaries."},{"line_number":207,"context_line":""},{"line_number":208,"context_line":"    :param client: ironic client instance;"},{"line_number":209,"context_line":"    :param node_list: list of dictionaries to be POSTed to /nodes"}],"source_content_type":"text/x-python","patch_set":8,"id":"3aaa91ec_ce57c300","line":206,"updated":"2016-06-29 01:41:46.000000000","message":"s/chassis/nodes/","commit_id":"3dc8b78c5b30e0c59916558cc807a7a4967608c1"},{"author":{"_account_id":12356,"name":"Vladyslav Drok","email":"vdrok@mirantis.com","username":"vdrok"},"change_message_id":"4800db2230f224af19a8b5be269897201e78614a","unresolved":false,"context_lines":[{"line_number":203,"context_line":""},{"line_number":204,"context_line":""},{"line_number":205,"context_line":"def create_nodes(client, node_list, errors, chassis_uuid\u003dNone):"},{"line_number":206,"context_line":"    \"\"\"Create chassis from dictionaries."},{"line_number":207,"context_line":""},{"line_number":208,"context_line":"    :param client: ironic client instance;"},{"line_number":209,"context_line":"    :param node_list: list of dictionaries to be POSTed to /nodes"}],"source_content_type":"text/x-python","patch_set":8,"id":"3aaa91ec_6332f2a8","line":206,"in_reply_to":"3aaa91ec_ce57c300","updated":"2016-06-30 12:08:13.000000000","message":"Done","commit_id":"3dc8b78c5b30e0c59916558cc807a7a4967608c1"},{"author":{"_account_id":6618,"name":"Ruby Loo","email":"opensrloo@gmail.com","username":"rloo"},"change_message_id":"1479a7f93538ef96313ed8c32671ae84c1886b80","unresolved":false,"context_lines":[{"line_number":219,"context_line":"                errors.append(exc.ClientException("},{"line_number":220,"context_line":"                    \u0027You are creating a node inside the chassis \u0027"},{"line_number":221,"context_line":"                    \u0027%(chassis_uuid)s, while specifying different chassis \u0027"},{"line_number":222,"context_line":"                    \u0027%(node_chassis_uuid)s inside the node.\u0027 %"},{"line_number":223,"context_line":"                    {\u0027chassis_uuid\u0027: chassis_uuid,"},{"line_number":224,"context_line":"                     \u0027node_chassis_uuid\u0027: node_chassis_uuid}))"},{"line_number":225,"context_line":"                continue"}],"source_content_type":"text/x-python","patch_set":8,"id":"3aaa91ec_8f5bf2f5","line":222,"updated":"2016-06-29 01:41:46.000000000","message":"How about \u0027Cannot create a node as part of chassis \u003cchassis\u003e because the node has a different chassis (\u003cnode_chassis_uuid\u003e) specified.\u0027","commit_id":"3dc8b78c5b30e0c59916558cc807a7a4967608c1"},{"author":{"_account_id":12356,"name":"Vladyslav Drok","email":"vdrok@mirantis.com","username":"vdrok"},"change_message_id":"4800db2230f224af19a8b5be269897201e78614a","unresolved":false,"context_lines":[{"line_number":219,"context_line":"                errors.append(exc.ClientException("},{"line_number":220,"context_line":"                    \u0027You are creating a node inside the chassis \u0027"},{"line_number":221,"context_line":"                    \u0027%(chassis_uuid)s, while specifying different chassis \u0027"},{"line_number":222,"context_line":"                    \u0027%(node_chassis_uuid)s inside the node.\u0027 %"},{"line_number":223,"context_line":"                    {\u0027chassis_uuid\u0027: chassis_uuid,"},{"line_number":224,"context_line":"                     \u0027node_chassis_uuid\u0027: node_chassis_uuid}))"},{"line_number":225,"context_line":"                continue"}],"source_content_type":"text/x-python","patch_set":8,"id":"3aaa91ec_e3cc228b","line":222,"in_reply_to":"3aaa91ec_8f5bf2f5","updated":"2016-06-30 12:08:13.000000000","message":"Done","commit_id":"3dc8b78c5b30e0c59916558cc807a7a4967608c1"},{"author":{"_account_id":6618,"name":"Ruby Loo","email":"opensrloo@gmail.com","username":"rloo"},"change_message_id":"1479a7f93538ef96313ed8c32671ae84c1886b80","unresolved":false,"context_lines":[{"line_number":223,"context_line":"                    {\u0027chassis_uuid\u0027: chassis_uuid,"},{"line_number":224,"context_line":"                     \u0027node_chassis_uuid\u0027: node_chassis_uuid}))"},{"line_number":225,"context_line":"                continue"},{"line_number":226,"context_line":"            node[\u0027chassis_uuid\u0027] \u003d chassis_uuid"},{"line_number":227,"context_line":"        node_uuid \u003d create_single_handler(create_single_node, errors,"},{"line_number":228,"context_line":"                                          client, **node)"},{"line_number":229,"context_line":"        ports \u003d node.get(\u0027ports\u0027)"}],"source_content_type":"text/x-python","patch_set":8,"id":"3aaa91ec_8ed01b55","line":226,"updated":"2016-06-29 01:41:46.000000000","message":"nit, you only need to do this if chassis_uuid didn\u0027t exist but it is fine.","commit_id":"3dc8b78c5b30e0c59916558cc807a7a4967608c1"},{"author":{"_account_id":6618,"name":"Ruby Loo","email":"opensrloo@gmail.com","username":"rloo"},"change_message_id":"1479a7f93538ef96313ed8c32671ae84c1886b80","unresolved":false,"context_lines":[{"line_number":241,"context_line":"        endpoint, if some of them contain \"nodes\" key, its content is POSTed"},{"line_number":242,"context_line":"        separately to /nodes endpoint;"},{"line_number":243,"context_line":"    :param errors: list of encountered exceptions."},{"line_number":244,"context_line":"    \"\"\""},{"line_number":245,"context_line":"    for chassis in chassis_list:"},{"line_number":246,"context_line":"        chassis_uuid \u003d create_single_handler(create_single_chassis, errors,"},{"line_number":247,"context_line":"                                             client, **chassis)"}],"source_content_type":"text/x-python","patch_set":8,"id":"3aaa91ec_eb9ef152","line":244,"updated":"2016-06-29 01:41:46.000000000","message":"what does this return?\n\nI\u0027m not sure I like that the errors array is being passed as a parameter, vs the methods returning a list of errors. But I\u0027ll think about it.","commit_id":"3dc8b78c5b30e0c59916558cc807a7a4967608c1"},{"author":{"_account_id":12356,"name":"Vladyslav Drok","email":"vdrok@mirantis.com","username":"vdrok"},"change_message_id":"4800db2230f224af19a8b5be269897201e78614a","unresolved":false,"context_lines":[{"line_number":241,"context_line":"        endpoint, if some of them contain \"nodes\" key, its content is POSTed"},{"line_number":242,"context_line":"        separately to /nodes endpoint;"},{"line_number":243,"context_line":"    :param errors: list of encountered exceptions."},{"line_number":244,"context_line":"    \"\"\""},{"line_number":245,"context_line":"    for chassis in chassis_list:"},{"line_number":246,"context_line":"        chassis_uuid \u003d create_single_handler(create_single_chassis, errors,"},{"line_number":247,"context_line":"                                             client, **chassis)"}],"source_content_type":"text/x-python","patch_set":8,"id":"3aaa91ec_4d6a60ee","line":244,"in_reply_to":"3aaa91ec_eb9ef152","updated":"2016-06-30 12:08:13.000000000","message":"Done","commit_id":"3dc8b78c5b30e0c59916558cc807a7a4967608c1"},{"author":{"_account_id":6618,"name":"Ruby Loo","email":"opensrloo@gmail.com","username":"rloo"},"change_message_id":"1479a7f93538ef96313ed8c32671ae84c1886b80","unresolved":false,"context_lines":[{"line_number":243,"context_line":"    :param errors: list of encountered exceptions."},{"line_number":244,"context_line":"    \"\"\""},{"line_number":245,"context_line":"    for chassis in chassis_list:"},{"line_number":246,"context_line":"        chassis_uuid \u003d create_single_handler(create_single_chassis, errors,"},{"line_number":247,"context_line":"                                             client, **chassis)"},{"line_number":248,"context_line":"        nodes \u003d chassis.get(\u0027nodes\u0027)"},{"line_number":249,"context_line":"        # Chassis UUID \u003d\u003d None means that chassis creation failed, don\u0027t"}],"source_content_type":"text/x-python","patch_set":8,"id":"3aaa91ec_0b5ffd41","line":246,"updated":"2016-06-29 01:41:46.000000000","message":"I wonder whether having a decorator instead of create_single_handler() might be easier to read/understand.","commit_id":"3dc8b78c5b30e0c59916558cc807a7a4967608c1"},{"author":{"_account_id":12356,"name":"Vladyslav Drok","email":"vdrok@mirantis.com","username":"vdrok"},"change_message_id":"4800db2230f224af19a8b5be269897201e78614a","unresolved":false,"context_lines":[{"line_number":243,"context_line":"    :param errors: list of encountered exceptions."},{"line_number":244,"context_line":"    \"\"\""},{"line_number":245,"context_line":"    for chassis in chassis_list:"},{"line_number":246,"context_line":"        chassis_uuid \u003d create_single_handler(create_single_chassis, errors,"},{"line_number":247,"context_line":"                                             client, **chassis)"},{"line_number":248,"context_line":"        nodes \u003d chassis.get(\u0027nodes\u0027)"},{"line_number":249,"context_line":"        # Chassis UUID \u003d\u003d None means that chassis creation failed, don\u0027t"}],"source_content_type":"text/x-python","patch_set":8,"id":"3aaa91ec_8d78c8c5","line":246,"in_reply_to":"3aaa91ec_0b5ffd41","updated":"2016-06-30 12:08:13.000000000","message":"Done","commit_id":"3dc8b78c5b30e0c59916558cc807a7a4967608c1"},{"author":{"_account_id":6618,"name":"Ruby Loo","email":"opensrloo@gmail.com","username":"rloo"},"change_message_id":"c38368d2b7fe83eb17143282ea343d9216424991","unresolved":false,"context_lines":[{"line_number":63,"context_line":"        except (exc.ClientException, jsonschema.ValidationError) as e:"},{"line_number":64,"context_line":"            errors.append(e)"},{"line_number":65,"context_line":"    if errors:"},{"line_number":66,"context_line":"        raise exc.ClientException(\u0027During resources files validation, the \u0027"},{"line_number":67,"context_line":"                                  \u0027following error(s) were encountered:\\n%s\u0027 %"},{"line_number":68,"context_line":"                                  \u0027\\n\u0027.join(six.text_type(e) for e in errors))"},{"line_number":69,"context_line":"    for r in resources:"}],"source_content_type":"text/x-python","patch_set":10,"id":"3aaa91ec_d0cb6770","line":66,"updated":"2016-06-30 21:04:19.000000000","message":"\u0027resources files\u0027 isn\u0027t quite right.\n\nif you want this, then \u0027During file validation\u0027 or \u0027During resource file validation\u0027. Or \u0027While validating the resource file(s)\u0027.","commit_id":"412a40d19a0b3a998288d33640f25136db7166a6"},{"author":{"_account_id":12356,"name":"Vladyslav Drok","email":"vdrok@mirantis.com","username":"vdrok"},"change_message_id":"986173cd02dff587e708a08c41943248b22b98f6","unresolved":false,"context_lines":[{"line_number":63,"context_line":"        except (exc.ClientException, jsonschema.ValidationError) as e:"},{"line_number":64,"context_line":"            errors.append(e)"},{"line_number":65,"context_line":"    if errors:"},{"line_number":66,"context_line":"        raise exc.ClientException(\u0027During resources files validation, the \u0027"},{"line_number":67,"context_line":"                                  \u0027following error(s) were encountered:\\n%s\u0027 %"},{"line_number":68,"context_line":"                                  \u0027\\n\u0027.join(six.text_type(e) for e in errors))"},{"line_number":69,"context_line":"    for r in resources:"}],"source_content_type":"text/x-python","patch_set":10,"id":"3aaa91ec_e27f8767","line":66,"in_reply_to":"3aaa91ec_d0cb6770","updated":"2016-07-01 17:41:44.000000000","message":"Done","commit_id":"412a40d19a0b3a998288d33640f25136db7166a6"},{"author":{"_account_id":6618,"name":"Ruby Loo","email":"opensrloo@gmail.com","username":"rloo"},"change_message_id":"c38368d2b7fe83eb17143282ea343d9216424991","unresolved":false,"context_lines":[{"line_number":121,"context_line":"    except exc.InvalidAttribute as e:"},{"line_number":122,"context_line":"        raise exc.InvalidAttribute("},{"line_number":123,"context_line":"            \u0027Some of the attributes (%(params)s) provided to the client to \u0027"},{"line_number":124,"context_line":"            \u0027create an ironic %(resource)s are invalid, the error is: \u0027"},{"line_number":125,"context_line":"            \u0027%(err)s\u0027 % {\u0027params\u0027: params, \u0027resource\u0027: resource_type, \u0027err\u0027: e}"},{"line_number":126,"context_line":"        )"},{"line_number":127,"context_line":"    except Exception as e:"}],"source_content_type":"text/x-python","patch_set":10,"id":"3aaa91ec_d0d887f1","line":124,"updated":"2016-06-30 21:04:19.000000000","message":"how about \u0027Cannot create the \u003cresource\u003e with attributes \u003cparams\u003e. One or more attributes are invalid: \u003cerr\u003e\u0027.","commit_id":"412a40d19a0b3a998288d33640f25136db7166a6"},{"author":{"_account_id":12356,"name":"Vladyslav Drok","email":"vdrok@mirantis.com","username":"vdrok"},"change_message_id":"986173cd02dff587e708a08c41943248b22b98f6","unresolved":false,"context_lines":[{"line_number":121,"context_line":"    except exc.InvalidAttribute as e:"},{"line_number":122,"context_line":"        raise exc.InvalidAttribute("},{"line_number":123,"context_line":"            \u0027Some of the attributes (%(params)s) provided to the client to \u0027"},{"line_number":124,"context_line":"            \u0027create an ironic %(resource)s are invalid, the error is: \u0027"},{"line_number":125,"context_line":"            \u0027%(err)s\u0027 % {\u0027params\u0027: params, \u0027resource\u0027: resource_type, \u0027err\u0027: e}"},{"line_number":126,"context_line":"        )"},{"line_number":127,"context_line":"    except Exception as e:"}],"source_content_type":"text/x-python","patch_set":10,"id":"3aaa91ec_2256afce","line":124,"in_reply_to":"3aaa91ec_d0d887f1","updated":"2016-07-01 17:41:44.000000000","message":"Done","commit_id":"412a40d19a0b3a998288d33640f25136db7166a6"},{"author":{"_account_id":6618,"name":"Ruby Loo","email":"opensrloo@gmail.com","username":"rloo"},"change_message_id":"c38368d2b7fe83eb17143282ea343d9216424991","unresolved":false,"context_lines":[{"line_number":126,"context_line":"        )"},{"line_number":127,"context_line":"    except Exception as e:"},{"line_number":128,"context_line":"        raise exc.ClientException("},{"line_number":129,"context_line":"            \u0027Unable to create the ironic %(resource)s with the specified \u0027"},{"line_number":130,"context_line":"            \u0027parameters (%(params)s), the error is: %(error)s\u0027 %"},{"line_number":131,"context_line":"            {\u0027error\u0027: e, \u0027resource\u0027: resource_type, \u0027params\u0027: params})"},{"line_number":132,"context_line":""}],"source_content_type":"text/x-python","patch_set":10,"id":"3aaa91ec_7065531c","line":129,"updated":"2016-06-30 21:04:19.000000000","message":"s/ironic //","commit_id":"412a40d19a0b3a998288d33640f25136db7166a6"},{"author":{"_account_id":12356,"name":"Vladyslav Drok","email":"vdrok@mirantis.com","username":"vdrok"},"change_message_id":"986173cd02dff587e708a08c41943248b22b98f6","unresolved":false,"context_lines":[{"line_number":126,"context_line":"        )"},{"line_number":127,"context_line":"    except Exception as e:"},{"line_number":128,"context_line":"        raise exc.ClientException("},{"line_number":129,"context_line":"            \u0027Unable to create the ironic %(resource)s with the specified \u0027"},{"line_number":130,"context_line":"            \u0027parameters (%(params)s), the error is: %(error)s\u0027 %"},{"line_number":131,"context_line":"            {\u0027error\u0027: e, \u0027resource\u0027: resource_type, \u0027params\u0027: params})"},{"line_number":132,"context_line":""}],"source_content_type":"text/x-python","patch_set":10,"id":"3aaa91ec_8267a3b6","line":129,"in_reply_to":"3aaa91ec_7065531c","updated":"2016-07-01 17:41:44.000000000","message":"Done","commit_id":"412a40d19a0b3a998288d33640f25136db7166a6"},{"author":{"_account_id":6618,"name":"Ruby Loo","email":"opensrloo@gmail.com","username":"rloo"},"change_message_id":"c38368d2b7fe83eb17143282ea343d9216424991","unresolved":false,"context_lines":[{"line_number":127,"context_line":"    except Exception as e:"},{"line_number":128,"context_line":"        raise exc.ClientException("},{"line_number":129,"context_line":"            \u0027Unable to create the ironic %(resource)s with the specified \u0027"},{"line_number":130,"context_line":"            \u0027parameters (%(params)s), the error is: %(error)s\u0027 %"},{"line_number":131,"context_line":"            {\u0027error\u0027: e, \u0027resource\u0027: resource_type, \u0027params\u0027: params})"},{"line_number":132,"context_line":""},{"line_number":133,"context_line":""}],"source_content_type":"text/x-python","patch_set":10,"id":"3aaa91ec_906efffd","line":130,"updated":"2016-06-30 21:04:19.000000000","message":"we should be consistent. Are they parameters or attributes (line 124).","commit_id":"412a40d19a0b3a998288d33640f25136db7166a6"},{"author":{"_account_id":12356,"name":"Vladyslav Drok","email":"vdrok@mirantis.com","username":"vdrok"},"change_message_id":"986173cd02dff587e708a08c41943248b22b98f6","unresolved":false,"context_lines":[{"line_number":127,"context_line":"    except Exception as e:"},{"line_number":128,"context_line":"        raise exc.ClientException("},{"line_number":129,"context_line":"            \u0027Unable to create the ironic %(resource)s with the specified \u0027"},{"line_number":130,"context_line":"            \u0027parameters (%(params)s), the error is: %(error)s\u0027 %"},{"line_number":131,"context_line":"            {\u0027error\u0027: e, \u0027resource\u0027: resource_type, \u0027params\u0027: params})"},{"line_number":132,"context_line":""},{"line_number":133,"context_line":""}],"source_content_type":"text/x-python","patch_set":10,"id":"3aaa91ec_02129309","line":130,"in_reply_to":"3aaa91ec_906efffd","updated":"2016-07-01 17:41:44.000000000","message":"Done","commit_id":"412a40d19a0b3a998288d33640f25136db7166a6"},{"author":{"_account_id":6618,"name":"Ruby Loo","email":"opensrloo@gmail.com","username":"rloo"},"change_message_id":"c38368d2b7fe83eb17143282ea343d9216424991","unresolved":false,"context_lines":[{"line_number":212,"context_line":"    :param port_list: list of dictionaries to be POSTed to /ports"},{"line_number":213,"context_line":"        endpoint."},{"line_number":214,"context_line":"    :param node_uuid: UUID of a node the ports should be associated with."},{"line_number":215,"context_line":"    :returns: array of exceptions happened during creation."},{"line_number":216,"context_line":"    \"\"\""},{"line_number":217,"context_line":"    errors \u003d []"},{"line_number":218,"context_line":"    for port in port_list:"}],"source_content_type":"text/x-python","patch_set":10,"id":"3aaa91ec_c33e03b7","line":215,"updated":"2016-06-30 21:04:19.000000000","message":"s/happened/encountered/","commit_id":"412a40d19a0b3a998288d33640f25136db7166a6"},{"author":{"_account_id":12356,"name":"Vladyslav Drok","email":"vdrok@mirantis.com","username":"vdrok"},"change_message_id":"986173cd02dff587e708a08c41943248b22b98f6","unresolved":false,"context_lines":[{"line_number":212,"context_line":"    :param port_list: list of dictionaries to be POSTed to /ports"},{"line_number":213,"context_line":"        endpoint."},{"line_number":214,"context_line":"    :param node_uuid: UUID of a node the ports should be associated with."},{"line_number":215,"context_line":"    :returns: array of exceptions happened during creation."},{"line_number":216,"context_line":"    \"\"\""},{"line_number":217,"context_line":"    errors \u003d []"},{"line_number":218,"context_line":"    for port in port_list:"}],"source_content_type":"text/x-python","patch_set":10,"id":"3aaa91ec_62f717d5","line":215,"in_reply_to":"3aaa91ec_c33e03b7","updated":"2016-07-01 17:41:44.000000000","message":"Done","commit_id":"412a40d19a0b3a998288d33640f25136db7166a6"},{"author":{"_account_id":12356,"name":"Vladyslav Drok","email":"vdrok@mirantis.com","username":"vdrok"},"change_message_id":"2908c3f5d3a408fb837e8009197e13a343550da3","unresolved":false,"context_lines":[{"line_number":219,"context_line":"        port_node_uuid \u003d port.get(\u0027node_uuid\u0027)"},{"line_number":220,"context_line":"        if port_node_uuid and port_node_uuid !\u003d node_uuid:"},{"line_number":221,"context_line":"            errors.append(exc.ClientException("},{"line_number":222,"context_line":"                \u0027Cannot create a port as part of node %(node_uuid)s \u0027"},{"line_number":223,"context_line":"                \u0027because the port has a different node \u0027"},{"line_number":224,"context_line":"                \u0027(%(port_node_uuid)s) specified.\u0027 %"},{"line_number":225,"context_line":"                {\u0027node_uuid\u0027: node_uuid,"}],"source_content_type":"text/x-python","patch_set":10,"id":"3aaa91ec_c55bb584","line":222,"range":{"start_line":222,"start_character":56,"end_line":222,"end_character":65},"updated":"2016-06-30 16:44:49.000000000","message":"After looking at it in real life - it feels strange - I create a node from\n\n {\n   \u0027driver\u0027: \u0027pxe_ssh\u0027,\n   \u0027name\u0027: \u0027my-node\u0027,\n   \u0027ports\u0027: [\n     {\n       \u0027address\u0027: \u002700:00:00:00:00:00\u0027,\n       \u0027node_uuid\u0027: \u0027550e8400-e29b-41d4-a716-446655440000\u0027\n     }\n   ]\n }\n\nand get the error:\n\n Cannot create a port as part of node 7ff0abb6-0d15-4eca-adc5-3c21e429d742\n because the port has a different node (550e8400-e29b-41d4-a716-446655440000)\n specified.\n\nIt is unclear which port it is, might be worth including the port dictionary here too.","commit_id":"412a40d19a0b3a998288d33640f25136db7166a6"},{"author":{"_account_id":12356,"name":"Vladyslav Drok","email":"vdrok@mirantis.com","username":"vdrok"},"change_message_id":"986173cd02dff587e708a08c41943248b22b98f6","unresolved":false,"context_lines":[{"line_number":219,"context_line":"        port_node_uuid \u003d port.get(\u0027node_uuid\u0027)"},{"line_number":220,"context_line":"        if port_node_uuid and port_node_uuid !\u003d node_uuid:"},{"line_number":221,"context_line":"            errors.append(exc.ClientException("},{"line_number":222,"context_line":"                \u0027Cannot create a port as part of node %(node_uuid)s \u0027"},{"line_number":223,"context_line":"                \u0027because the port has a different node \u0027"},{"line_number":224,"context_line":"                \u0027(%(port_node_uuid)s) specified.\u0027 %"},{"line_number":225,"context_line":"                {\u0027node_uuid\u0027: node_uuid,"}],"source_content_type":"text/x-python","patch_set":10,"id":"3aaa91ec_62cf1758","line":222,"range":{"start_line":222,"start_character":56,"end_line":222,"end_character":65},"in_reply_to":"3aaa91ec_63846f5d","updated":"2016-07-01 17:41:44.000000000","message":"Done","commit_id":"412a40d19a0b3a998288d33640f25136db7166a6"},{"author":{"_account_id":6618,"name":"Ruby Loo","email":"opensrloo@gmail.com","username":"rloo"},"change_message_id":"c38368d2b7fe83eb17143282ea343d9216424991","unresolved":false,"context_lines":[{"line_number":219,"context_line":"        port_node_uuid \u003d port.get(\u0027node_uuid\u0027)"},{"line_number":220,"context_line":"        if port_node_uuid and port_node_uuid !\u003d node_uuid:"},{"line_number":221,"context_line":"            errors.append(exc.ClientException("},{"line_number":222,"context_line":"                \u0027Cannot create a port as part of node %(node_uuid)s \u0027"},{"line_number":223,"context_line":"                \u0027because the port has a different node \u0027"},{"line_number":224,"context_line":"                \u0027(%(port_node_uuid)s) specified.\u0027 %"},{"line_number":225,"context_line":"                {\u0027node_uuid\u0027: node_uuid,"}],"source_content_type":"text/x-python","patch_set":10,"id":"3aaa91ec_63846f5d","line":222,"range":{"start_line":222,"start_character":56,"end_line":222,"end_character":65},"in_reply_to":"3aaa91ec_c55bb584","updated":"2016-06-30 21:04:19.000000000","message":"Yes, that makes sense. (Although with the node UUID, someone could just look through their ports and find the ones that are bad, but might as well make it easier for them.) If you include the port dictionary, you can reword it like \u0027because the port (\u003cdictionary\u003e) has a different node UUID specified.\u0027","commit_id":"412a40d19a0b3a998288d33640f25136db7166a6"},{"author":{"_account_id":6618,"name":"Ruby Loo","email":"opensrloo@gmail.com","username":"rloo"},"change_message_id":"c38368d2b7fe83eb17143282ea343d9216424991","unresolved":false,"context_lines":[{"line_number":250,"context_line":"                errors.append(exc.ClientException("},{"line_number":251,"context_line":"                    \u0027Cannot create a node as part of chassis %(chassis_uuid)s \u0027"},{"line_number":252,"context_line":"                    \u0027because the node has a different chassis \u0027"},{"line_number":253,"context_line":"                    \u0027(%(node_chassis_uuid)s) specified.\u0027 %"},{"line_number":254,"context_line":"                    {\u0027chassis_uuid\u0027: chassis_uuid,"},{"line_number":255,"context_line":"                     \u0027node_chassis_uuid\u0027: node_chassis_uuid}))"},{"line_number":256,"context_line":"                continue"}],"source_content_type":"text/x-python","patch_set":10,"id":"3aaa91ec_c3c1e381","line":253,"updated":"2016-06-30 21:04:19.000000000","message":"Does this one also look weird? Should the node dictionary be included here, so you know which node it is?","commit_id":"412a40d19a0b3a998288d33640f25136db7166a6"},{"author":{"_account_id":12356,"name":"Vladyslav Drok","email":"vdrok@mirantis.com","username":"vdrok"},"change_message_id":"986173cd02dff587e708a08c41943248b22b98f6","unresolved":false,"context_lines":[{"line_number":250,"context_line":"                errors.append(exc.ClientException("},{"line_number":251,"context_line":"                    \u0027Cannot create a node as part of chassis %(chassis_uuid)s \u0027"},{"line_number":252,"context_line":"                    \u0027because the node has a different chassis \u0027"},{"line_number":253,"context_line":"                    \u0027(%(node_chassis_uuid)s) specified.\u0027 %"},{"line_number":254,"context_line":"                    {\u0027chassis_uuid\u0027: chassis_uuid,"},{"line_number":255,"context_line":"                     \u0027node_chassis_uuid\u0027: node_chassis_uuid}))"},{"line_number":256,"context_line":"                continue"}],"source_content_type":"text/x-python","patch_set":10,"id":"3aaa91ec_42cc9b61","line":253,"in_reply_to":"3aaa91ec_c3c1e381","updated":"2016-07-01 17:41:44.000000000","message":"Done","commit_id":"412a40d19a0b3a998288d33640f25136db7166a6"},{"author":{"_account_id":12356,"name":"Vladyslav Drok","email":"vdrok@mirantis.com","username":"vdrok"},"change_message_id":"be34101f407bdcc680e03b833f3ced0b4dd5f121","unresolved":false,"context_lines":[{"line_number":14,"context_line":"from ironicclient.v1 import create_resources"},{"line_number":15,"context_line":""},{"line_number":16,"context_line":""},{"line_number":17,"context_line":"@cliutils.arg(\u0027resources_files\u0027, nargs\u003d\u0027+\u0027, metavar\u003d\u0027\u003cfile\u003e\u0027, action\u003d\u0027append\u0027,"},{"line_number":18,"context_line":"              default\u003d[], help\u003d\u0027File (.yaml or .json) containing descriptions \u0027"},{"line_number":19,"context_line":"                               \u0027of the resources to create. Can be specified \u0027"},{"line_number":20,"context_line":"                               \u0027multiple times.\u0027)"}],"source_content_type":"text/x-python","patch_set":11,"id":"3aaa91ec_1d8154c4","line":17,"updated":"2016-07-01 17:47:08.000000000","message":"action\u003d\u0027append\u0027 is not needed as these are positional arguments.","commit_id":"24fa7f5565d90c755035493c908baa3513f7aeed"},{"author":{"_account_id":12356,"name":"Vladyslav Drok","email":"vdrok@mirantis.com","username":"vdrok"},"change_message_id":"6b254eb500a8a9e9989c6cd0ef1d741b1988532a","unresolved":false,"context_lines":[{"line_number":14,"context_line":"from ironicclient.v1 import create_resources"},{"line_number":15,"context_line":""},{"line_number":16,"context_line":""},{"line_number":17,"context_line":"@cliutils.arg(\u0027resources_files\u0027, nargs\u003d\u0027+\u0027, metavar\u003d\u0027\u003cfile\u003e\u0027, action\u003d\u0027append\u0027,"},{"line_number":18,"context_line":"              default\u003d[], help\u003d\u0027File (.yaml or .json) containing descriptions \u0027"},{"line_number":19,"context_line":"                               \u0027of the resources to create. Can be specified \u0027"},{"line_number":20,"context_line":"                               \u0027multiple times.\u0027)"}],"source_content_type":"text/x-python","patch_set":11,"id":"1aa78d24_aa637119","line":17,"in_reply_to":"3aaa91ec_1d8154c4","updated":"2016-07-04 16:37:07.000000000","message":"Done","commit_id":"24fa7f5565d90c755035493c908baa3513f7aeed"},{"author":{"_account_id":6618,"name":"Ruby Loo","email":"opensrloo@gmail.com","username":"rloo"},"change_message_id":"f87e79e85f96c7ea669ff59ad216b6533d909ba2","unresolved":false,"context_lines":[{"line_number":18,"context_line":"              help\u003d\u0027File (.yaml or .json) containing descriptions of the \u0027"},{"line_number":19,"context_line":"                   \u0027resources to create. Can be specified multiple times.\u0027)"},{"line_number":20,"context_line":"def do_create(cc, args):"},{"line_number":21,"context_line":"    \"\"\"Create resources using their JSON or YAML descriptions."},{"line_number":22,"context_line":""},{"line_number":23,"context_line":"    This command tries to create all the resources it can, printing all the"},{"line_number":24,"context_line":"    errors. If any of the files fail to validate against the schema, resource"}],"source_content_type":"text/x-python","patch_set":13,"id":"1aa78d24_97129e55","line":21,"updated":"2016-07-06 17:47:29.000000000","message":"How about \u0027Create baremetal resources (chassis, nodes, and ports).\u0027","commit_id":"dc667add6327de0cf912e87f70f2b1ba76897acd"},{"author":{"_account_id":12356,"name":"Vladyslav Drok","email":"vdrok@mirantis.com","username":"vdrok"},"change_message_id":"4dd7c6e39b91060ba669c6cbfa0ab0771e9a9a57","unresolved":false,"context_lines":[{"line_number":18,"context_line":"              help\u003d\u0027File (.yaml or .json) containing descriptions of the \u0027"},{"line_number":19,"context_line":"                   \u0027resources to create. Can be specified multiple times.\u0027)"},{"line_number":20,"context_line":"def do_create(cc, args):"},{"line_number":21,"context_line":"    \"\"\"Create resources using their JSON or YAML descriptions."},{"line_number":22,"context_line":""},{"line_number":23,"context_line":"    This command tries to create all the resources it can, printing all the"},{"line_number":24,"context_line":"    errors. If any of the files fail to validate against the schema, resource"}],"source_content_type":"text/x-python","patch_set":13,"id":"1aa78d24_6fc1e07f","line":21,"in_reply_to":"1aa78d24_97129e55","updated":"2016-07-13 13:00:21.000000000","message":"Done","commit_id":"dc667add6327de0cf912e87f70f2b1ba76897acd"},{"author":{"_account_id":6618,"name":"Ruby Loo","email":"opensrloo@gmail.com","username":"rloo"},"change_message_id":"f87e79e85f96c7ea669ff59ad216b6533d909ba2","unresolved":false,"context_lines":[{"line_number":22,"context_line":""},{"line_number":23,"context_line":"    This command tries to create all the resources it can, printing all the"},{"line_number":24,"context_line":"    errors. If any of the files fail to validate against the schema, resource"},{"line_number":25,"context_line":"    creation does not happen."},{"line_number":26,"context_line":"    \"\"\""},{"line_number":27,"context_line":"    create_resources.create_resources(cc, args.resource_files[0])"}],"source_content_type":"text/x-python","patch_set":13,"id":"1aa78d24_0855faf8","line":25,"updated":"2016-07-06 17:47:29.000000000","message":"How about: The resources may be described in one or more JSON or YAML files. If any file cannot be validated, no resources are created. An attempt is made to create all the resources; those that could not be created are skipped (with a corresponding error message).","commit_id":"dc667add6327de0cf912e87f70f2b1ba76897acd"},{"author":{"_account_id":12356,"name":"Vladyslav Drok","email":"vdrok@mirantis.com","username":"vdrok"},"change_message_id":"4dd7c6e39b91060ba669c6cbfa0ab0771e9a9a57","unresolved":false,"context_lines":[{"line_number":22,"context_line":""},{"line_number":23,"context_line":"    This command tries to create all the resources it can, printing all the"},{"line_number":24,"context_line":"    errors. If any of the files fail to validate against the schema, resource"},{"line_number":25,"context_line":"    creation does not happen."},{"line_number":26,"context_line":"    \"\"\""},{"line_number":27,"context_line":"    create_resources.create_resources(cc, args.resource_files[0])"}],"source_content_type":"text/x-python","patch_set":13,"id":"1aa78d24_8fc6cc97","line":25,"in_reply_to":"1aa78d24_0855faf8","updated":"2016-07-13 13:00:21.000000000","message":"All good suggestions as always :)","commit_id":"dc667add6327de0cf912e87f70f2b1ba76897acd"}],"releasenotes/notes/add-create-command-3df5efbbecc33276.yaml":[{"author":{"_account_id":6618,"name":"Ruby Loo","email":"opensrloo@gmail.com","username":"rloo"},"change_message_id":"1479a7f93538ef96313ed8c32671ae84c1886b80","unresolved":false,"context_lines":[{"line_number":1,"context_line":"---"},{"line_number":2,"context_line":"features:"},{"line_number":3,"context_line":"  - Added a new ``ironic create`` command that allows creating resources"},{"line_number":4,"context_line":"    specified in a JSON or YAML file(s) passed to it. ``*.yaml`` files are"},{"line_number":5,"context_line":"    considered to contain YAML syntax, ``*.json`` are considered to contain"},{"line_number":6,"context_line":"    JSON, other extensions are unsupported."}],"source_content_type":"text/x-yaml","patch_set":8,"id":"3aaa91ec_6f4de671","line":3,"updated":"2016-06-29 01:41:46.000000000","message":"s/allows creating/creates/\n\ndo we need to clarify what a resource is? eg s/resources/resources (chassis, nodes, ports)/ ?","commit_id":"3dc8b78c5b30e0c59916558cc807a7a4967608c1"},{"author":{"_account_id":12356,"name":"Vladyslav Drok","email":"vdrok@mirantis.com","username":"vdrok"},"change_message_id":"4800db2230f224af19a8b5be269897201e78614a","unresolved":false,"context_lines":[{"line_number":1,"context_line":"---"},{"line_number":2,"context_line":"features:"},{"line_number":3,"context_line":"  - Added a new ``ironic create`` command that allows creating resources"},{"line_number":4,"context_line":"    specified in a JSON or YAML file(s) passed to it. ``*.yaml`` files are"},{"line_number":5,"context_line":"    considered to contain YAML syntax, ``*.json`` are considered to contain"},{"line_number":6,"context_line":"    JSON, other extensions are unsupported."}],"source_content_type":"text/x-yaml","patch_set":8,"id":"3aaa91ec_e8633aaf","line":3,"in_reply_to":"3aaa91ec_6f4de671","updated":"2016-06-30 12:08:13.000000000","message":"Done","commit_id":"3dc8b78c5b30e0c59916558cc807a7a4967608c1"},{"author":{"_account_id":6618,"name":"Ruby Loo","email":"opensrloo@gmail.com","username":"rloo"},"change_message_id":"1479a7f93538ef96313ed8c32671ae84c1886b80","unresolved":false,"context_lines":[{"line_number":1,"context_line":"---"},{"line_number":2,"context_line":"features:"},{"line_number":3,"context_line":"  - Added a new ``ironic create`` command that allows creating resources"},{"line_number":4,"context_line":"    specified in a JSON or YAML file(s) passed to it. ``*.yaml`` files are"},{"line_number":5,"context_line":"    considered to contain YAML syntax, ``*.json`` are considered to contain"},{"line_number":6,"context_line":"    JSON, other extensions are unsupported."}],"source_content_type":"text/x-yaml","patch_set":8,"id":"3aaa91ec_2f63dedd","line":4,"updated":"2016-06-29 01:41:46.000000000","message":"s/a/one or more/\n\nHow about \u0027specified in one or more JSON (``*.json``) or YAML (``*.yaml``) files\u0027.\n\nDon\u0027t think we need to mention that other extensions are unsupported?","commit_id":"3dc8b78c5b30e0c59916558cc807a7a4967608c1"},{"author":{"_account_id":12356,"name":"Vladyslav Drok","email":"vdrok@mirantis.com","username":"vdrok"},"change_message_id":"4800db2230f224af19a8b5be269897201e78614a","unresolved":false,"context_lines":[{"line_number":1,"context_line":"---"},{"line_number":2,"context_line":"features:"},{"line_number":3,"context_line":"  - Added a new ``ironic create`` command that allows creating resources"},{"line_number":4,"context_line":"    specified in a JSON or YAML file(s) passed to it. ``*.yaml`` files are"},{"line_number":5,"context_line":"    considered to contain YAML syntax, ``*.json`` are considered to contain"},{"line_number":6,"context_line":"    JSON, other extensions are unsupported."}],"source_content_type":"text/x-yaml","patch_set":8,"id":"3aaa91ec_48552ec0","line":4,"in_reply_to":"3aaa91ec_2f63dedd","updated":"2016-06-30 12:08:13.000000000","message":"Done","commit_id":"3dc8b78c5b30e0c59916558cc807a7a4967608c1"},{"author":{"_account_id":6618,"name":"Ruby Loo","email":"opensrloo@gmail.com","username":"rloo"},"change_message_id":"c38368d2b7fe83eb17143282ea343d9216424991","unresolved":false,"context_lines":[{"line_number":1,"context_line":"---"},{"line_number":2,"context_line":"features:"},{"line_number":3,"context_line":"  - Added a new ``ironic create`` command that allows creating resources"},{"line_number":4,"context_line":"    (chassis, nodes, ports) specified in one or more JSON (``*.json``) or YAML"},{"line_number":5,"context_line":"    (``*.yaml``) files."}],"source_content_type":"text/x-yaml","patch_set":10,"id":"3aaa91ec_433173a1","line":3,"updated":"2016-06-30 21:04:19.000000000","message":"s/allows creating/creates/","commit_id":"412a40d19a0b3a998288d33640f25136db7166a6"},{"author":{"_account_id":12356,"name":"Vladyslav Drok","email":"vdrok@mirantis.com","username":"vdrok"},"change_message_id":"986173cd02dff587e708a08c41943248b22b98f6","unresolved":false,"context_lines":[{"line_number":1,"context_line":"---"},{"line_number":2,"context_line":"features:"},{"line_number":3,"context_line":"  - Added a new ``ironic create`` command that allows creating resources"},{"line_number":4,"context_line":"    (chassis, nodes, ports) specified in one or more JSON (``*.json``) or YAML"},{"line_number":5,"context_line":"    (``*.yaml``) files."}],"source_content_type":"text/x-yaml","patch_set":10,"id":"3aaa91ec_0271f3a8","line":3,"in_reply_to":"3aaa91ec_433173a1","updated":"2016-07-01 17:41:44.000000000","message":"Done","commit_id":"412a40d19a0b3a998288d33640f25136db7166a6"},{"author":{"_account_id":6618,"name":"Ruby Loo","email":"opensrloo@gmail.com","username":"rloo"},"change_message_id":"f87e79e85f96c7ea669ff59ad216b6533d909ba2","unresolved":false,"context_lines":[{"line_number":4,"context_line":"    nodes, ports) specified in one or more JSON (``*.json``) or YAML"},{"line_number":5,"context_line":"    (``*.yaml``) files. ``openstack baremetal create`` now also supports"},{"line_number":6,"context_line":"    providing a list of resource files instead of node creation attributes,"},{"line_number":7,"context_line":"    it will be its only function after creating nodes with it is deprecated."}],"source_content_type":"text/x-yaml","patch_set":13,"id":"1aa78d24_94a58648","line":7,"updated":"2016-07-06 17:47:29.000000000","message":"creating nodes with it IS deprecated. You mean when it is removed?\n\nHow about something like:\n\nSimilar to the \u0027ironic create\u0027 command, the \u0027openstack baremetal create\u0027 command creates resources specified in one or more files. (Note that \u0027openstack baremetal create\u0027 can also be used to create a node via specified node attributes. However this feature is deprecated.)","commit_id":"dc667add6327de0cf912e87f70f2b1ba76897acd"},{"author":{"_account_id":12356,"name":"Vladyslav Drok","email":"vdrok@mirantis.com","username":"vdrok"},"change_message_id":"4dd7c6e39b91060ba669c6cbfa0ab0771e9a9a57","unresolved":false,"context_lines":[{"line_number":4,"context_line":"    nodes, ports) specified in one or more JSON (``*.json``) or YAML"},{"line_number":5,"context_line":"    (``*.yaml``) files. ``openstack baremetal create`` now also supports"},{"line_number":6,"context_line":"    providing a list of resource files instead of node creation attributes,"},{"line_number":7,"context_line":"    it will be its only function after creating nodes with it is deprecated."}],"source_content_type":"text/x-yaml","patch_set":13,"id":"1aa78d24_4f3984f1","line":7,"in_reply_to":"1aa78d24_94a58648","updated":"2016-07-13 13:00:21.000000000","message":"Done","commit_id":"dc667add6327de0cf912e87f70f2b1ba76897acd"}]}
