)]}'
{"ironic/common/utils.py":[{"author":{"_account_id":6773,"name":"Lucas Alvares Gomes","email":"lucasagomes@gmail.com","username":"lucasagomes"},"change_message_id":"f181f8e2c2e3667fc8e96b737cb933e91f25a655","unresolved":false,"context_lines":[{"line_number":307,"context_line":"    :returns: True if the hash of reference content is the same as"},{"line_number":308,"context_line":"        the hash of file\u0027s content, False otherwise"},{"line_number":309,"context_line":"    \"\"\""},{"line_number":310,"context_line":"    algo \u003d \u0027md5\u0027"},{"line_number":311,"context_line":"    with open(path) as existing:"},{"line_number":312,"context_line":"        file_hash_hex \u003d hash_file(existing, hash_algo\u003dalgo)"},{"line_number":313,"context_line":"    ref_hash \u003d _get_hash_object(algo)"}],"source_content_type":"text/x-python","patch_set":1,"id":"9a629dbe_ba83b7cb","line":310,"range":{"start_line":310,"start_character":4,"end_line":310,"end_character":16},"updated":"2016-11-08 10:03:41.000000000","message":"We already have a \"hash_algo\" parameter, we should use it instead of this variable","commit_id":"7d074acc5250da153944d4913a1646f8b5f0d818"},{"author":{"_account_id":9542,"name":"Pavlo Shchelokovskyy","email":"pshchelokovskyy@mirantis.com","username":"pshchelo"},"change_message_id":"08fe2778aa083b546c31615d9479d39329f5db57","unresolved":false,"context_lines":[{"line_number":307,"context_line":"    :returns: True if the hash of reference content is the same as"},{"line_number":308,"context_line":"        the hash of file\u0027s content, False otherwise"},{"line_number":309,"context_line":"    \"\"\""},{"line_number":310,"context_line":"    algo \u003d \u0027md5\u0027"},{"line_number":311,"context_line":"    with open(path) as existing:"},{"line_number":312,"context_line":"        file_hash_hex \u003d hash_file(existing, hash_algo\u003dalgo)"},{"line_number":313,"context_line":"    ref_hash \u003d _get_hash_object(algo)"}],"source_content_type":"text/x-python","patch_set":1,"id":"9a629dbe_5910dba8","line":310,"range":{"start_line":310,"start_character":4,"end_line":310,"end_character":16},"in_reply_to":"9a629dbe_ba83b7cb","updated":"2016-11-08 14:34:32.000000000","message":"Done","commit_id":"7d074acc5250da153944d4913a1646f8b5f0d818"},{"author":{"_account_id":14525,"name":"Vasyl Saienko","email":"vsaienko@mirantis.com","username":"vsaienko"},"change_message_id":"872cbd40836d100c6aa73ff141e78ff929e0b86f","unresolved":false,"context_lines":[{"line_number":541,"context_line":"    :param is_file: whether template is file or string with template itself"},{"line_number":542,"context_line":"    :returns: the rendered template as a string"},{"line_number":543,"context_line":"    \"\"\""},{"line_number":544,"context_line":"    if is_file:"},{"line_number":545,"context_line":"        tmpl_path, tmpl_name \u003d os.path.split(template)"},{"line_number":546,"context_line":"        loader \u003d jinja2.FileSystemLoader(tmpl_path)"},{"line_number":547,"context_line":"    else:"}],"source_content_type":"text/x-python","patch_set":3,"id":"9a629dbe_3c192789","line":544,"updated":"2016-11-09 12:12:24.000000000","message":"might be use os.path.is_file() here instead of having is_fule option?","commit_id":"96c966b894a80d59dcd4dd4bb55b0ba1f52ce45c"},{"author":{"_account_id":9542,"name":"Pavlo Shchelokovskyy","email":"pshchelokovskyy@mirantis.com","username":"pshchelo"},"change_message_id":"9a4b46392cd9885d23a114169e77fd7ca134bcc7","unresolved":false,"context_lines":[{"line_number":541,"context_line":"    :param is_file: whether template is file or string with template itself"},{"line_number":542,"context_line":"    :returns: the rendered template as a string"},{"line_number":543,"context_line":"    \"\"\""},{"line_number":544,"context_line":"    if is_file:"},{"line_number":545,"context_line":"        tmpl_path, tmpl_name \u003d os.path.split(template)"},{"line_number":546,"context_line":"        loader \u003d jinja2.FileSystemLoader(tmpl_path)"},{"line_number":547,"context_line":"    else:"}],"source_content_type":"text/x-python","patch_set":3,"id":"9a629dbe_d6f48788","line":544,"in_reply_to":"9a629dbe_3c192789","updated":"2016-11-09 13:34:06.000000000","message":"I was actually thinking about that, and that\u0027d work in almost all cases and simplify the code.\n\nHowever there\u0027ll be no guarantee that a particular template as string will not somehow evaluate to a valid path on file system...\n\nWould be happy to change back though if we decide that such probability is negligible.","commit_id":"96c966b894a80d59dcd4dd4bb55b0ba1f52ce45c"}],"ironic/drivers/modules/pxe.py":[{"author":{"_account_id":14525,"name":"Vasyl Saienko","email":"vsaienko@mirantis.com","username":"vsaienko"},"change_message_id":"872cbd40836d100c6aa73ff141e78ff929e0b86f","unresolved":false,"context_lines":[{"line_number":378,"context_line":"        if CONF.pxe.ipxe_enabled:"},{"line_number":379,"context_line":"            # Render the iPXE boot script template and save it"},{"line_number":380,"context_line":"            # to HTTP root directory"},{"line_number":381,"context_line":"            boot_script \u003d utils.render_template("},{"line_number":382,"context_line":"                CONF.pxe.ipxe_boot_script,"},{"line_number":383,"context_line":"                {\u0027ipxe_for_mac_uri\u0027: pxe_utils.PXE_CFG_DIR_NAME + \u0027/\u0027})"},{"line_number":384,"context_line":"            bootfile_path \u003d os.path.join("}],"source_content_type":"text/x-python","patch_set":3,"id":"9a629dbe_679f8cb4","line":381,"updated":"2016-11-09 12:12:24.000000000","message":"Should we check that file with jinja template exists and fail with propper message if it doesn\u0027t?","commit_id":"96c966b894a80d59dcd4dd4bb55b0ba1f52ce45c"},{"author":{"_account_id":9542,"name":"Pavlo Shchelokovskyy","email":"pshchelokovskyy@mirantis.com","username":"pshchelo"},"change_message_id":"9a4b46392cd9885d23a114169e77fd7ca134bcc7","unresolved":false,"context_lines":[{"line_number":378,"context_line":"        if CONF.pxe.ipxe_enabled:"},{"line_number":379,"context_line":"            # Render the iPXE boot script template and save it"},{"line_number":380,"context_line":"            # to HTTP root directory"},{"line_number":381,"context_line":"            boot_script \u003d utils.render_template("},{"line_number":382,"context_line":"                CONF.pxe.ipxe_boot_script,"},{"line_number":383,"context_line":"                {\u0027ipxe_for_mac_uri\u0027: pxe_utils.PXE_CFG_DIR_NAME + \u0027/\u0027})"},{"line_number":384,"context_line":"            bootfile_path \u003d os.path.join("}],"source_content_type":"text/x-python","patch_set":3,"id":"9a629dbe_d978382e","line":381,"in_reply_to":"9a629dbe_679f8cb4","updated":"2016-11-09 13:34:06.000000000","message":"In this case the error raised would be TemplateNotFound: \u003cname-of-file\u003e from Jinja which IMO is pretty self-explanatory.\n\nI\u0027m not sure if we ought to handle this exception here and raise smth more Ironic specific - non existing file configured in config is a severe misconfiguration and I\u0027d let this bubble up as scary as it can be. For example currently we do not handle any Jinja exceptions specifically and such possibility of misconfiguration already exist.","commit_id":"96c966b894a80d59dcd4dd4bb55b0ba1f52ce45c"},{"author":{"_account_id":12356,"name":"Vladyslav Drok","email":"vdrok@mirantis.com","username":"vdrok"},"change_message_id":"821c18c628257afcce7df260eb6640d930803505","unresolved":false,"context_lines":[{"line_number":384,"context_line":"            bootfile_path \u003d os.path.join("},{"line_number":385,"context_line":"                CONF.deploy.http_root,"},{"line_number":386,"context_line":"                os.path.basename(CONF.pxe.ipxe_boot_script))"},{"line_number":387,"context_line":"            # NOTE(pas-ha) to prevent possible concurrent writes,"},{"line_number":388,"context_line":"            # only write to file if its content is different from required,"},{"line_number":389,"context_line":"            # which should be rather rare"},{"line_number":390,"context_line":"            if (not os.path.isfile(bootfile_path) or"}],"source_content_type":"text/x-python","patch_set":3,"id":"9a629dbe_4719a887","line":387,"updated":"2016-11-09 12:34:05.000000000","message":"Are you sure that it prevents races? OTOH we shouldn\u0027t switch greenthread in the middle of the writing to file...","commit_id":"96c966b894a80d59dcd4dd4bb55b0ba1f52ce45c"},{"author":{"_account_id":9542,"name":"Pavlo Shchelokovskyy","email":"pshchelokovskyy@mirantis.com","username":"pshchelo"},"change_message_id":"b0c0e56ddca8f58a0e333a883a28433fc971fd16","unresolved":false,"context_lines":[{"line_number":384,"context_line":"            bootfile_path \u003d os.path.join("},{"line_number":385,"context_line":"                CONF.deploy.http_root,"},{"line_number":386,"context_line":"                os.path.basename(CONF.pxe.ipxe_boot_script))"},{"line_number":387,"context_line":"            # NOTE(pas-ha) to prevent possible concurrent writes,"},{"line_number":388,"context_line":"            # only write to file if its content is different from required,"},{"line_number":389,"context_line":"            # which should be rather rare"},{"line_number":390,"context_line":"            if (not os.path.isfile(bootfile_path) or"}],"source_content_type":"text/x-python","patch_set":3,"id":"7a77a97e_8a2109a2","line":387,"in_reply_to":"9a629dbe_364b0389","updated":"2016-11-16 20:01:41.000000000","message":"Done","commit_id":"96c966b894a80d59dcd4dd4bb55b0ba1f52ce45c"},{"author":{"_account_id":9542,"name":"Pavlo Shchelokovskyy","email":"pshchelokovskyy@mirantis.com","username":"pshchelo"},"change_message_id":"9a4b46392cd9885d23a114169e77fd7ca134bcc7","unresolved":false,"context_lines":[{"line_number":384,"context_line":"            bootfile_path \u003d os.path.join("},{"line_number":385,"context_line":"                CONF.deploy.http_root,"},{"line_number":386,"context_line":"                os.path.basename(CONF.pxe.ipxe_boot_script))"},{"line_number":387,"context_line":"            # NOTE(pas-ha) to prevent possible concurrent writes,"},{"line_number":388,"context_line":"            # only write to file if its content is different from required,"},{"line_number":389,"context_line":"            # which should be rather rare"},{"line_number":390,"context_line":"            if (not os.path.isfile(bootfile_path) or"}],"source_content_type":"text/x-python","patch_set":3,"id":"9a629dbe_364b0389","line":387,"in_reply_to":"9a629dbe_4719a887","updated":"2016-11-09 13:34:06.000000000","message":"not relevant currently, sure, but I was thinking more on future containerized case where multiple conductors could write to the same HTTP root. for pxe configs they always will write to different per-conductor files, but this single place is the same.\n\ns/concurrent/unneeded","commit_id":"96c966b894a80d59dcd4dd4bb55b0ba1f52ce45c"}],"ironic/tests/unit/common/test_utils.py":[{"author":{"_account_id":6773,"name":"Lucas Alvares Gomes","email":"lucasagomes@gmail.com","username":"lucasagomes"},"change_message_id":"3e2f8389def9a708cf8317b0d1954acce6d9b98f","unresolved":false,"context_lines":[{"line_number":249,"context_line":"                          file_like_object, \u0027hickory-dickory-dock\u0027)"},{"line_number":250,"context_line":""},{"line_number":251,"context_line":"    def test_file_has_content_equal(self):"},{"line_number":252,"context_line":"        data \u003d b\u0027Mary had a little lamb, its fleece as white as snow\u0027"},{"line_number":253,"context_line":"        ref \u003d data"},{"line_number":254,"context_line":"        with mock.patch(\u0027ironic.common.utils.open\u0027,"},{"line_number":255,"context_line":"                        mock.mock_open(read_data\u003ddata)):"}],"source_content_type":"text/x-python","patch_set":3,"id":"9a629dbe_0dfef736","line":252,"updated":"2016-11-09 10:16:56.000000000","message":"lol gotta love ironic!","commit_id":"96c966b894a80d59dcd4dd4bb55b0ba1f52ce45c"},{"author":{"_account_id":9542,"name":"Pavlo Shchelokovskyy","email":"pshchelokovskyy@mirantis.com","username":"pshchelo"},"change_message_id":"a60acddf729741e395dc2b103dbfec69be6ccd8a","unresolved":false,"context_lines":[{"line_number":249,"context_line":"                          file_like_object, \u0027hickory-dickory-dock\u0027)"},{"line_number":250,"context_line":""},{"line_number":251,"context_line":"    def test_file_has_content_equal(self):"},{"line_number":252,"context_line":"        data \u003d b\u0027Mary had a little lamb, its fleece as white as snow\u0027"},{"line_number":253,"context_line":"        ref \u003d data"},{"line_number":254,"context_line":"        with mock.patch(\u0027ironic.common.utils.open\u0027,"},{"line_number":255,"context_line":"                        mock.mock_open(read_data\u003ddata)):"}],"source_content_type":"text/x-python","patch_set":3,"id":"9a629dbe_bc96174a","line":252,"in_reply_to":"9a629dbe_0dfef736","updated":"2016-11-09 11:52:33.000000000","message":"Copy/Paste is all we have :)","commit_id":"96c966b894a80d59dcd4dd4bb55b0ba1f52ce45c"},{"author":{"_account_id":12356,"name":"Vladyslav Drok","email":"vdrok@mirantis.com","username":"vdrok"},"change_message_id":"821c18c628257afcce7df260eb6640d930803505","unresolved":false,"context_lines":[{"line_number":251,"context_line":"    def test_file_has_content_equal(self):"},{"line_number":252,"context_line":"        data \u003d b\u0027Mary had a little lamb, its fleece as white as snow\u0027"},{"line_number":253,"context_line":"        ref \u003d data"},{"line_number":254,"context_line":"        with mock.patch(\u0027ironic.common.utils.open\u0027,"},{"line_number":255,"context_line":"                        mock.mock_open(read_data\u003ddata)):"},{"line_number":256,"context_line":"            self.assertTrue(utils.file_has_content(\u0027foo\u0027, ref))"},{"line_number":257,"context_line":""}],"source_content_type":"text/x-python","patch_set":3,"id":"9a629dbe_225f420f","line":254,"updated":"2016-11-09 12:34:05.000000000","message":"Heh, interesting way of mocking open :)","commit_id":"96c966b894a80d59dcd4dd4bb55b0ba1f52ce45c"},{"author":{"_account_id":9542,"name":"Pavlo Shchelokovskyy","email":"pshchelokovskyy@mirantis.com","username":"pshchelo"},"change_message_id":"9a4b46392cd9885d23a114169e77fd7ca134bcc7","unresolved":false,"context_lines":[{"line_number":251,"context_line":"    def test_file_has_content_equal(self):"},{"line_number":252,"context_line":"        data \u003d b\u0027Mary had a little lamb, its fleece as white as snow\u0027"},{"line_number":253,"context_line":"        ref \u003d data"},{"line_number":254,"context_line":"        with mock.patch(\u0027ironic.common.utils.open\u0027,"},{"line_number":255,"context_line":"                        mock.mock_open(read_data\u003ddata)):"},{"line_number":256,"context_line":"            self.assertTrue(utils.file_has_content(\u0027foo\u0027, ref))"},{"line_number":257,"context_line":""}],"source_content_type":"text/x-python","patch_set":3,"id":"9a629dbe_8c24c0af","line":254,"in_reply_to":"9a629dbe_225f420f","updated":"2016-11-09 13:34:06.000000000","message":"Yep, patching in the right place can make all the difference :) https://docs.python.org/3/library/unittest.mock.html#where-to-patch","commit_id":"96c966b894a80d59dcd4dd4bb55b0ba1f52ce45c"}]}
