)]}'
{"/COMMIT_MSG":[{"author":{"_account_id":6849,"name":"Roman Podoliaka","email":"roman.podoliaka@gmail.com","username":"rpodolyaka"},"change_message_id":"418164e9a7026eed039d02a4d68af2562cf3b8bf","unresolved":false,"context_lines":[{"line_number":6,"context_line":""},{"line_number":7,"context_line":"Cleanup ssh touch, ssh mkdir, ssh rm system commands"},{"line_number":8,"context_line":""},{"line_number":9,"context_line":"ssh touch, ssh mkdir, ssh rm system commands were replaced"},{"line_number":10,"context_line":"with rsync command"},{"line_number":11,"context_line":""},{"line_number":12,"context_line":"Change-Id: I586a9faa2a7afa3f195239df305898b6da4fb583"}],"source_content_type":"text/x-gerrit-commit-message","patch_set":3,"id":"3a961159_3547c41e","line":9,"updated":"2015-01-15 16:02:55.000000000","message":"Please provide reasoning for this change\n\n(https://wiki.openstack.org/wiki/GitCommitMessages)\n\n+ we could probably file a bug to track this","commit_id":"d3f41d678dad14eaaf3782a3e502c95f578af690"},{"author":{"_account_id":6849,"name":"Roman Podoliaka","email":"roman.podoliaka@gmail.com","username":"rpodolyaka"},"change_message_id":"5614e359fec1721906e0a792427cfc28c91091dd","unresolved":false,"context_lines":[{"line_number":10,"context_line":"ssh rm system commands were replaced with rsync command which"},{"line_number":11,"context_line":"allows to perform any file operations on the remote host."},{"line_number":12,"context_line":"These changes allow to use rssh shell for compute nodes for"},{"line_number":13,"context_line":"interacting, and as result allows to improve security."},{"line_number":14,"context_line":""},{"line_number":15,"context_line":"Change-Id: I586a9faa2a7afa3f195239df305898b6da4fb583"}],"source_content_type":"text/x-gerrit-commit-message","patch_set":5,"id":"3a961159_96366950","line":13,"updated":"2015-01-19 14:42:30.000000000","message":"let\u0027s file a bug to track this\n\n+  provide info on:\n\nwhether it will continue to work with existing  shell configuration or the operator need to perform some changes\n\n+ we might need DocImpact here\n\n(https://wiki.openstack.org/wiki/Documentation/DocImpact)","commit_id":"b3b1d71dea4c8c63bf5b9ab04d28e65d2208e64e"},{"author":{"_account_id":1653,"name":"garyk","email":"gkotton@vmware.com","username":"garyk"},"change_message_id":"550ae47a21b2d2bf9ac4dd14a691544153125108","unresolved":false,"context_lines":[{"line_number":4,"context_line":"Commit:     Marian Horban \u003cmhorban@mirantis.com\u003e"},{"line_number":5,"context_line":"CommitDate: 2015-02-25 08:39:54 -0500"},{"line_number":6,"context_line":""},{"line_number":7,"context_line":"Rsync remote FS driver was added"},{"line_number":8,"context_line":""},{"line_number":9,"context_line":"Added ability to use SSH or RSYNC interface between compute nodes."},{"line_number":10,"context_line":"It can be configured by remote_fs_transport config option."}],"source_content_type":"text/x-gerrit-commit-message","patch_set":11,"id":"ba7be1f8_f6703e42","line":7,"updated":"2015-03-01 14:12:21.000000000","message":"please prefix this with libvirt:","commit_id":"624d5e7d2d8f470bc0dbcf2d737b2fc79b31599a"},{"author":{"_account_id":14358,"name":"Marian Horban","email":"m.horban@gmail.com","username":"mhorban"},"change_message_id":"b6aac004550deda09c0a34e21a008eb8e8f91288","unresolved":false,"context_lines":[{"line_number":4,"context_line":"Commit:     Marian Horban \u003cmhorban@mirantis.com\u003e"},{"line_number":5,"context_line":"CommitDate: 2015-02-25 08:39:54 -0500"},{"line_number":6,"context_line":""},{"line_number":7,"context_line":"Rsync remote FS driver was added"},{"line_number":8,"context_line":""},{"line_number":9,"context_line":"Added ability to use SSH or RSYNC interface between compute nodes."},{"line_number":10,"context_line":"It can be configured by remote_fs_transport config option."}],"source_content_type":"text/x-gerrit-commit-message","patch_set":11,"id":"9a80dd14_8e5204dc","line":7,"in_reply_to":"ba7be1f8_f6703e42","updated":"2015-03-20 17:11:07.000000000","message":"Done","commit_id":"624d5e7d2d8f470bc0dbcf2d737b2fc79b31599a"},{"author":{"_account_id":1653,"name":"garyk","email":"gkotton@vmware.com","username":"garyk"},"change_message_id":"f549bb69eff14903141f872b618c2ad9f459f3d4","unresolved":false,"context_lines":[{"line_number":14,"context_line":"rsync with version 2.6.7 is present in Ubuntu 8.04.4 LTS,"},{"line_number":15,"context_line":"CentOS-5, Red Hat Enterprise Linux 5, Fedora 7 and above versions"},{"line_number":16,"context_line":"of these distributives."},{"line_number":17,"context_line":"DocImpact: remote_filesystem_transport config option was added."},{"line_number":18,"context_line":"blueprint: Implementation of remote FS driver based on `rsync`"},{"line_number":19,"context_line":"for libvirt"},{"line_number":20,"context_line":""}],"source_content_type":"text/x-gerrit-commit-message","patch_set":15,"id":"ba3cc151_71ee17b6","line":17,"updated":"2015-07-05 05:40:40.000000000","message":"Can you please add the values here so whoever is documenting can have a better understanding about what should be added","commit_id":"e8c61b56d395c605a2788fe0db905c54eef9f692"},{"author":{"_account_id":14358,"name":"Marian Horban","email":"m.horban@gmail.com","username":"mhorban"},"change_message_id":"f9c74748266abc9a26a5eda79ec51a48e3990fca","unresolved":false,"context_lines":[{"line_number":14,"context_line":"rsync with version 2.6.7 is present in Ubuntu 8.04.4 LTS,"},{"line_number":15,"context_line":"CentOS-5, Red Hat Enterprise Linux 5, Fedora 7 and above versions"},{"line_number":16,"context_line":"of these distributives."},{"line_number":17,"context_line":"DocImpact: remote_filesystem_transport config option was added."},{"line_number":18,"context_line":"blueprint: Implementation of remote FS driver based on `rsync`"},{"line_number":19,"context_line":"for libvirt"},{"line_number":20,"context_line":""}],"source_content_type":"text/x-gerrit-commit-message","patch_set":15,"id":"ba3cc151_18e9bd1a","line":17,"in_reply_to":"ba3cc151_71ee17b6","updated":"2015-07-06 21:02:05.000000000","message":"Done","commit_id":"e8c61b56d395c605a2788fe0db905c54eef9f692"},{"author":{"_account_id":1653,"name":"garyk","email":"gkotton@vmware.com","username":"garyk"},"change_message_id":"f6219e71489946e7d76edac31650298567153b69","unresolved":false,"context_lines":[{"line_number":13,"context_line":"DocImpact: current implementation requires rsync version 2.6.7."},{"line_number":14,"context_line":"rsync with version 2.6.7 is present in Ubuntu 8.04.4 LTS,"},{"line_number":15,"context_line":"CentOS-5, Red Hat Enterprise Linux 5, Fedora 7 and above versions"},{"line_number":16,"context_line":"of these distributives."},{"line_number":17,"context_line":"DocImpact: remote_filesystem_transport config option was added."},{"line_number":18,"context_line":"This option can accept values \u0027ssh\u0027, \u0027rsync\u0027. Default value is \u0027ssh\u0027."},{"line_number":19,"context_line":""}],"source_content_type":"text/x-gerrit-commit-message","patch_set":21,"id":"9a41bdd9_c6946144","line":16,"updated":"2015-07-15 11:26:19.000000000","message":"distributives \u003d\u003e distributions","commit_id":"61edfb6254734ee53bfa8054164c3cb8fe0e4750"},{"author":{"_account_id":14358,"name":"Marian Horban","email":"m.horban@gmail.com","username":"mhorban"},"change_message_id":"443955d7ce00b38ca600002e54019f76a44ddb67","unresolved":false,"context_lines":[{"line_number":13,"context_line":"DocImpact: current implementation requires rsync version 2.6.7."},{"line_number":14,"context_line":"rsync with version 2.6.7 is present in Ubuntu 8.04.4 LTS,"},{"line_number":15,"context_line":"CentOS-5, Red Hat Enterprise Linux 5, Fedora 7 and above versions"},{"line_number":16,"context_line":"of these distributives."},{"line_number":17,"context_line":"DocImpact: remote_filesystem_transport config option was added."},{"line_number":18,"context_line":"This option can accept values \u0027ssh\u0027, \u0027rsync\u0027. Default value is \u0027ssh\u0027."},{"line_number":19,"context_line":""}],"source_content_type":"text/x-gerrit-commit-message","patch_set":21,"id":"3a50d1a3_431faab6","line":16,"in_reply_to":"9a41bdd9_c6946144","updated":"2015-07-24 09:06:57.000000000","message":"Done","commit_id":"61edfb6254734ee53bfa8054164c3cb8fe0e4750"}],"nova/tests/unit/virt/libvirt/test_driver.py":[{"author":{"_account_id":1653,"name":"garyk","email":"gkotton@vmware.com","username":"garyk"},"change_message_id":"f6219e71489946e7d76edac31650298567153b69","unresolved":false,"context_lines":[{"line_number":9910,"context_line":"                                       mock_exists, mock_unlink):"},{"line_number":9911,"context_line":"        drvr \u003d libvirt_driver.LibvirtDriver(fake.FakeVirtAPI(), True)"},{"line_number":9912,"context_line":"        drvr.get_host_ip_addr \u003d mock.MagicMock(return_value\u003d\u0027bar\u0027)"},{"line_number":9913,"context_line":"        mock_exists.return_value \u003d is_same"},{"line_number":9914,"context_line":"        with mock.patch.object(drvr._remote_filesystem_driver,"},{"line_number":9915,"context_line":"                               \u0027create_file\u0027) as mock_rem_fs_create:"},{"line_number":9916,"context_line":"            with mock.patch.object(drvr._remote_filesystem_driver,"}],"source_content_type":"text/x-python","patch_set":21,"id":"9a41bdd9_668eb57a","line":9913,"updated":"2015-07-15 11:26:19.000000000","message":"you can do:\nwith contextlib.nested(\n    mock.patch.object(drvr._remote_filesystem_driver,\n                      \u0027create_file\u0027),\n    mock.patch.object(drvr._remote_filesystem_driver,\n                                   \u0027remove_file\u0027))\n) as (mock_rem_fs_create, mock_rem_fs_remove):\n\nThen you do not need the nested mocks","commit_id":"61edfb6254734ee53bfa8054164c3cb8fe0e4750"},{"author":{"_account_id":14358,"name":"Marian Horban","email":"m.horban@gmail.com","username":"mhorban"},"change_message_id":"443955d7ce00b38ca600002e54019f76a44ddb67","unresolved":false,"context_lines":[{"line_number":9910,"context_line":"                                       mock_exists, mock_unlink):"},{"line_number":9911,"context_line":"        drvr \u003d libvirt_driver.LibvirtDriver(fake.FakeVirtAPI(), True)"},{"line_number":9912,"context_line":"        drvr.get_host_ip_addr \u003d mock.MagicMock(return_value\u003d\u0027bar\u0027)"},{"line_number":9913,"context_line":"        mock_exists.return_value \u003d is_same"},{"line_number":9914,"context_line":"        with mock.patch.object(drvr._remote_filesystem_driver,"},{"line_number":9915,"context_line":"                               \u0027create_file\u0027) as mock_rem_fs_create:"},{"line_number":9916,"context_line":"            with mock.patch.object(drvr._remote_filesystem_driver,"}],"source_content_type":"text/x-python","patch_set":21,"id":"3a50d1a3_69a647af","line":9913,"in_reply_to":"9a41bdd9_668eb57a","updated":"2015-07-24 09:06:57.000000000","message":"Thank you, done","commit_id":"61edfb6254734ee53bfa8054164c3cb8fe0e4750"},{"author":{"_account_id":1653,"name":"garyk","email":"gkotton@vmware.com","username":"garyk"},"change_message_id":"f6219e71489946e7d76edac31650298567153b69","unresolved":false,"context_lines":[{"line_number":9918,"context_line":"                result \u003d drvr._is_storage_shared_with(\u0027host\u0027, \u0027/path\u0027)"},{"line_number":9919,"context_line":"        mock_rem_fs_create.assert_any_call(\u0027host\u0027, mock.ANY)"},{"line_number":9920,"context_line":"        if is_same:"},{"line_number":9921,"context_line":"            mock_unlink.assert_called_once_with(mock.ANY)"},{"line_number":9922,"context_line":"        else:"},{"line_number":9923,"context_line":"            mock_rem_fs_remove.assert_called_with(\u0027host\u0027, mock.ANY)"},{"line_number":9924,"context_line":"        return result"}],"source_content_type":"text/x-python","patch_set":21,"id":"9a41bdd9_26d2ed5c","line":9921,"updated":"2015-07-15 11:26:19.000000000","message":"do we not want to check the path here in some way or another?","commit_id":"61edfb6254734ee53bfa8054164c3cb8fe0e4750"},{"author":{"_account_id":14358,"name":"Marian Horban","email":"m.horban@gmail.com","username":"mhorban"},"change_message_id":"443955d7ce00b38ca600002e54019f76a44ddb67","unresolved":false,"context_lines":[{"line_number":9918,"context_line":"                result \u003d drvr._is_storage_shared_with(\u0027host\u0027, \u0027/path\u0027)"},{"line_number":9919,"context_line":"        mock_rem_fs_create.assert_any_call(\u0027host\u0027, mock.ANY)"},{"line_number":9920,"context_line":"        if is_same:"},{"line_number":9921,"context_line":"            mock_unlink.assert_called_once_with(mock.ANY)"},{"line_number":9922,"context_line":"        else:"},{"line_number":9923,"context_line":"            mock_rem_fs_remove.assert_called_with(\u0027host\u0027, mock.ANY)"},{"line_number":9924,"context_line":"        return result"}],"source_content_type":"text/x-python","patch_set":21,"id":"3a50d1a3_432f86f6","line":9921,"in_reply_to":"9a41bdd9_26d2ed5c","updated":"2015-07-24 09:06:57.000000000","message":"Done","commit_id":"61edfb6254734ee53bfa8054164c3cb8fe0e4750"},{"author":{"_account_id":1653,"name":"garyk","email":"gkotton@vmware.com","username":"garyk"},"change_message_id":"f6219e71489946e7d76edac31650298567153b69","unresolved":false,"context_lines":[{"line_number":9920,"context_line":"        if is_same:"},{"line_number":9921,"context_line":"            mock_unlink.assert_called_once_with(mock.ANY)"},{"line_number":9922,"context_line":"        else:"},{"line_number":9923,"context_line":"            mock_rem_fs_remove.assert_called_with(\u0027host\u0027, mock.ANY)"},{"line_number":9924,"context_line":"        return result"},{"line_number":9925,"context_line":""},{"line_number":9926,"context_line":"    def test_shared_storage_detection_same_host(self):"}],"source_content_type":"text/x-python","patch_set":21,"id":"9a41bdd9_a6c6fd97","line":9923,"updated":"2015-07-15 11:26:19.000000000","message":"dittoo","commit_id":"61edfb6254734ee53bfa8054164c3cb8fe0e4750"},{"author":{"_account_id":14358,"name":"Marian Horban","email":"m.horban@gmail.com","username":"mhorban"},"change_message_id":"443955d7ce00b38ca600002e54019f76a44ddb67","unresolved":false,"context_lines":[{"line_number":9920,"context_line":"        if is_same:"},{"line_number":9921,"context_line":"            mock_unlink.assert_called_once_with(mock.ANY)"},{"line_number":9922,"context_line":"        else:"},{"line_number":9923,"context_line":"            mock_rem_fs_remove.assert_called_with(\u0027host\u0027, mock.ANY)"},{"line_number":9924,"context_line":"        return result"},{"line_number":9925,"context_line":""},{"line_number":9926,"context_line":"    def test_shared_storage_detection_same_host(self):"}],"source_content_type":"text/x-python","patch_set":21,"id":"3a50d1a3_03397e41","line":9923,"in_reply_to":"9a41bdd9_a6c6fd97","updated":"2015-07-24 09:06:57.000000000","message":"Done","commit_id":"61edfb6254734ee53bfa8054164c3cb8fe0e4750"},{"author":{"_account_id":7,"name":"Jay Pipes","email":"jaypipes@gmail.com","username":"jaypipes"},"change_message_id":"6efdf9e16febd8d836dc85bfdedd31d16657cd30","unresolved":false,"context_lines":[{"line_number":9917,"context_line":"            mock.patch.object(drvr._remotefs, \u0027create_file\u0027),"},{"line_number":9918,"context_line":"            mock.patch.object(drvr._remotefs, \u0027remove_file\u0027)"},{"line_number":9919,"context_line":"        ) as (mock_rem_fs_create, mock_rem_fs_remove):"},{"line_number":9920,"context_line":"                result \u003d drvr._is_storage_shared_with(\u0027host\u0027, \u0027/path\u0027)"},{"line_number":9921,"context_line":"        mock_rem_fs_create.assert_any_call(\u0027host\u0027, mock.ANY)"},{"line_number":9922,"context_line":"        create_args, create_kwargs \u003d mock_rem_fs_create.call_args"},{"line_number":9923,"context_line":"        self.assertTrue(create_args[1].startswith(\u0027/path\u0027))"}],"source_content_type":"text/x-python","patch_set":25,"id":"3a50d1a3_f18763b4","line":9920,"updated":"2015-07-30 19:06:53.000000000","message":"nit: this is indented one level too many.","commit_id":"ea6d312c22bd214e34d5122133cea15b26dd3099"},{"author":{"_account_id":14358,"name":"Marian Horban","email":"m.horban@gmail.com","username":"mhorban"},"change_message_id":"36f3b8ade560fca46b19f80c5ce6fc7f340db122","unresolved":false,"context_lines":[{"line_number":9917,"context_line":"            mock.patch.object(drvr._remotefs, \u0027create_file\u0027),"},{"line_number":9918,"context_line":"            mock.patch.object(drvr._remotefs, \u0027remove_file\u0027)"},{"line_number":9919,"context_line":"        ) as (mock_rem_fs_create, mock_rem_fs_remove):"},{"line_number":9920,"context_line":"                result \u003d drvr._is_storage_shared_with(\u0027host\u0027, \u0027/path\u0027)"},{"line_number":9921,"context_line":"        mock_rem_fs_create.assert_any_call(\u0027host\u0027, mock.ANY)"},{"line_number":9922,"context_line":"        create_args, create_kwargs \u003d mock_rem_fs_create.call_args"},{"line_number":9923,"context_line":"        self.assertTrue(create_args[1].startswith(\u0027/path\u0027))"}],"source_content_type":"text/x-python","patch_set":25,"id":"3a50d1a3_68ad3ee8","line":9920,"in_reply_to":"3a50d1a3_f18763b4","updated":"2015-08-03 20:04:06.000000000","message":"Done","commit_id":"ea6d312c22bd214e34d5122133cea15b26dd3099"}],"nova/tests/unit/virt/libvirt/test_remotefs.py":[{"author":{"_account_id":1779,"name":"Daniel Berrange","email":"berrange@redhat.com","username":"berrange"},"change_message_id":"ce9703e799421b6e0a37814af9908efa1c16146f","unresolved":false,"context_lines":[{"line_number":161,"context_line":"                                                \u0027/home/favourite\u0027)"},{"line_number":162,"context_line":"        mock_execute.assert_called_once_with(\u0027scp\u0027,"},{"line_number":163,"context_line":"                                             \u00271.2.3.4:/home/SpaceOdyssey\u0027,"},{"line_number":164,"context_line":"                                             \u0027/home/favourite\u0027)"}],"source_content_type":"text/x-python","patch_set":23,"id":"3a50d1a3_e2d954f4","line":164,"updated":"2015-07-28 15:44:56.000000000","message":"You should have two tests which call self.assertPublicAPISignatures, one for RsyncRemoteFilesystem and one for SshRemoteFilesystem. This validates that the subclasses implement the exact same API contract as the base class.","commit_id":"6dabea7a5b373155f345a29dc2eb0df493bbc7b3"},{"author":{"_account_id":1779,"name":"Daniel Berrange","email":"berrange@redhat.com","username":"berrange"},"change_message_id":"fddfd35b7adba10fefd8b732c5980a0a11ae16fa","unresolved":false,"context_lines":[{"line_number":161,"context_line":"                                                \u0027/home/favourite\u0027)"},{"line_number":162,"context_line":"        mock_execute.assert_called_once_with(\u0027scp\u0027,"},{"line_number":163,"context_line":"                                             \u00271.2.3.4:/home/SpaceOdyssey\u0027,"},{"line_number":164,"context_line":"                                             \u0027/home/favourite\u0027)"}],"source_content_type":"text/x-python","patch_set":23,"id":"3a50d1a3_119b6867","line":164,"in_reply_to":"3a50d1a3_680a058c","updated":"2015-07-28 17:05:49.000000000","message":"Looking at the assertPublicAPISignatures I think it should be possible to change it so that it accepts either a class or object instance as the inspect.getmembers() call accepts either a class or object IIUC.","commit_id":"6dabea7a5b373155f345a29dc2eb0df493bbc7b3"},{"author":{"_account_id":14358,"name":"Marian Horban","email":"m.horban@gmail.com","username":"mhorban"},"change_message_id":"2fcb6885614c2a850c90e715e6d6d279c19989ca","unresolved":false,"context_lines":[{"line_number":161,"context_line":"                                                \u0027/home/favourite\u0027)"},{"line_number":162,"context_line":"        mock_execute.assert_called_once_with(\u0027scp\u0027,"},{"line_number":163,"context_line":"                                             \u00271.2.3.4:/home/SpaceOdyssey\u0027,"},{"line_number":164,"context_line":"                                             \u0027/home/favourite\u0027)"}],"source_content_type":"text/x-python","patch_set":23,"id":"3a50d1a3_680a058c","line":164,"in_reply_to":"3a50d1a3_e2d954f4","updated":"2015-07-28 16:58:23.000000000","message":"I\u0027ve used abc.ABCMeta as metaclass and added @abc.abstractmethod decorator for base class methods. So if there are not implemented methods in derived classes we will get NotImplemented exception during instance creation.\nI can not use self.assertPublicAPISignatures because it takes instances of base and derived class...but creation of base class instance causes exception","commit_id":"6dabea7a5b373155f345a29dc2eb0df493bbc7b3"}],"nova/tests/unit/virt/libvirt/test_utils.py":[{"author":{"_account_id":6849,"name":"Roman Podoliaka","email":"roman.podoliaka@gmail.com","username":"rpodolyaka"},"change_message_id":"e592833dcdad8aff5436d86b3a42d5b252eb91b0","unresolved":false,"context_lines":[{"line_number":57,"context_line":"    @mock.patch(\u0027nova.utils.execute\u0027)"},{"line_number":58,"context_line":"    def test_remove_remote_file(self, mock_execute, mock_mkdtemp):"},{"line_number":59,"context_line":"        libvirt_utils.remove_remote_file(\u0027host\u0027, \u0027dest\u0027)"},{"line_number":60,"context_line":"        self.assertEqual(2, mock_execute.call_count)"},{"line_number":61,"context_line":"        self.assertEqual(1, mock_mkdtemp.call_count)"},{"line_number":62,"context_line":""},{"line_number":63,"context_line":"    @mock.patch(\u0027tempfile.mkdtemp\u0027)"}],"source_content_type":"text/x-python","patch_set":6,"id":"1a930d6b_40d53be3","line":60,"updated":"2015-01-27 17:08:50.000000000","message":"can we check exact calls here? (at least for execute()), not call counts","commit_id":"b0d8bf2f3ffdced8510b287a08b693fadb46de0e"},{"author":{"_account_id":14358,"name":"Marian Horban","email":"m.horban@gmail.com","username":"mhorban"},"change_message_id":"ce5e578b800432dfa0bcfc8370b96f4ddc247aa8","unresolved":false,"context_lines":[{"line_number":57,"context_line":"    @mock.patch(\u0027nova.utils.execute\u0027)"},{"line_number":58,"context_line":"    def test_remove_remote_file(self, mock_execute, mock_mkdtemp):"},{"line_number":59,"context_line":"        libvirt_utils.remove_remote_file(\u0027host\u0027, \u0027dest\u0027)"},{"line_number":60,"context_line":"        self.assertEqual(2, mock_execute.call_count)"},{"line_number":61,"context_line":"        self.assertEqual(1, mock_mkdtemp.call_count)"},{"line_number":62,"context_line":""},{"line_number":63,"context_line":"    @mock.patch(\u0027tempfile.mkdtemp\u0027)"}],"source_content_type":"text/x-python","patch_set":6,"id":"da86d52c_62f82a7d","line":60,"in_reply_to":"1a930d6b_40d53be3","updated":"2015-02-02 15:12:49.000000000","message":"Done","commit_id":"b0d8bf2f3ffdced8510b287a08b693fadb46de0e"},{"author":{"_account_id":1653,"name":"garyk","email":"gkotton@vmware.com","username":"garyk"},"change_message_id":"f549bb69eff14903141f872b618c2ad9f459f3d4","unresolved":false,"context_lines":[{"line_number":63,"context_line":"        mock_execute.assert_called_once_with(\u0027cp\u0027, \u0027src\u0027, \u0027dest\u0027)"},{"line_number":64,"context_line":""},{"line_number":65,"context_line":"    def test_copy_image_remote_ssh(self):"},{"line_number":66,"context_line":"        with mock.patch("},{"line_number":67,"context_line":"            \u0027nova.virt.libvirt.remotefs.SshRemoteFilesystem.copy_file\u0027) \\"},{"line_number":68,"context_line":"            as mock_rem_fs_remove:"},{"line_number":69,"context_line":"            CONF.libvirt.remote_filesystem_transport \u003d \u0027Ssh\u0027"}],"source_content_type":"text/x-python","patch_set":15,"id":"ba3cc151_d1fcc374","line":66,"updated":"2015-07-05 05:40:40.000000000","message":"any reason not to use the mock outside of the method as a decorator here?\n\n@mock.patch(\u0027nova.virt.libvirt.remotefs.SshRemoteFilesystem.copy_file\u0027)\ndef test_copy_image_remote_ssh(self, mock_rem_fs_remove):","commit_id":"e8c61b56d395c605a2788fe0db905c54eef9f692"},{"author":{"_account_id":14358,"name":"Marian Horban","email":"m.horban@gmail.com","username":"mhorban"},"change_message_id":"f9c74748266abc9a26a5eda79ec51a48e3990fca","unresolved":false,"context_lines":[{"line_number":63,"context_line":"        mock_execute.assert_called_once_with(\u0027cp\u0027, \u0027src\u0027, \u0027dest\u0027)"},{"line_number":64,"context_line":""},{"line_number":65,"context_line":"    def test_copy_image_remote_ssh(self):"},{"line_number":66,"context_line":"        with mock.patch("},{"line_number":67,"context_line":"            \u0027nova.virt.libvirt.remotefs.SshRemoteFilesystem.copy_file\u0027) \\"},{"line_number":68,"context_line":"            as mock_rem_fs_remove:"},{"line_number":69,"context_line":"            CONF.libvirt.remote_filesystem_transport \u003d \u0027Ssh\u0027"}],"source_content_type":"text/x-python","patch_set":15,"id":"ba3cc151_f8289935","line":66,"in_reply_to":"ba3cc151_d1fcc374","updated":"2015-07-06 21:02:05.000000000","message":"Done","commit_id":"e8c61b56d395c605a2788fe0db905c54eef9f692"},{"author":{"_account_id":1653,"name":"garyk","email":"gkotton@vmware.com","username":"garyk"},"change_message_id":"f549bb69eff14903141f872b618c2ad9f459f3d4","unresolved":false,"context_lines":[{"line_number":66,"context_line":"        with mock.patch("},{"line_number":67,"context_line":"            \u0027nova.virt.libvirt.remotefs.SshRemoteFilesystem.copy_file\u0027) \\"},{"line_number":68,"context_line":"            as mock_rem_fs_remove:"},{"line_number":69,"context_line":"            CONF.libvirt.remote_filesystem_transport \u003d \u0027Ssh\u0027"},{"line_number":70,"context_line":"            libvirt_utils.copy_image(\u0027src\u0027, \u0027dest\u0027, host\u003d\u0027host\u0027)"},{"line_number":71,"context_line":""},{"line_number":72,"context_line":"        mock_rem_fs_remove.assert_called_once_with(\u0027src\u0027, \u0027host:dest\u0027)"}],"source_content_type":"text/x-python","patch_set":15,"id":"ba3cc151_11030b78","line":69,"updated":"2015-07-05 05:40:40.000000000","message":"please use self.flags(remote_filesystem_transport\u003d\u0027Ssh\u0027, group\u003d\u0027libvirt\u0027)","commit_id":"e8c61b56d395c605a2788fe0db905c54eef9f692"},{"author":{"_account_id":14358,"name":"Marian Horban","email":"m.horban@gmail.com","username":"mhorban"},"change_message_id":"f9c74748266abc9a26a5eda79ec51a48e3990fca","unresolved":false,"context_lines":[{"line_number":66,"context_line":"        with mock.patch("},{"line_number":67,"context_line":"            \u0027nova.virt.libvirt.remotefs.SshRemoteFilesystem.copy_file\u0027) \\"},{"line_number":68,"context_line":"            as mock_rem_fs_remove:"},{"line_number":69,"context_line":"            CONF.libvirt.remote_filesystem_transport \u003d \u0027Ssh\u0027"},{"line_number":70,"context_line":"            libvirt_utils.copy_image(\u0027src\u0027, \u0027dest\u0027, host\u003d\u0027host\u0027)"},{"line_number":71,"context_line":""},{"line_number":72,"context_line":"        mock_rem_fs_remove.assert_called_once_with(\u0027src\u0027, \u0027host:dest\u0027)"}],"source_content_type":"text/x-python","patch_set":15,"id":"ba3cc151_98206d4b","line":69,"in_reply_to":"ba3cc151_11030b78","updated":"2015-07-06 21:02:05.000000000","message":"Done","commit_id":"e8c61b56d395c605a2788fe0db905c54eef9f692"},{"author":{"_account_id":1653,"name":"garyk","email":"gkotton@vmware.com","username":"garyk"},"change_message_id":"f549bb69eff14903141f872b618c2ad9f459f3d4","unresolved":false,"context_lines":[{"line_number":71,"context_line":""},{"line_number":72,"context_line":"        mock_rem_fs_remove.assert_called_once_with(\u0027src\u0027, \u0027host:dest\u0027)"},{"line_number":73,"context_line":""},{"line_number":74,"context_line":"    def test_copy_image_remote_rsync(self):"},{"line_number":75,"context_line":"        with mock.patch("},{"line_number":76,"context_line":"            \u0027nova.virt.libvirt.remotefs.RsyncRemoteFilesystem.copy_file\u0027) \\"},{"line_number":77,"context_line":"            as mock_rem_fs_remove:"}],"source_content_type":"text/x-python","patch_set":15,"id":"ba3cc151_f101c76b","line":74,"updated":"2015-07-05 05:40:40.000000000","message":"same as above for the decorator","commit_id":"e8c61b56d395c605a2788fe0db905c54eef9f692"},{"author":{"_account_id":14358,"name":"Marian Horban","email":"m.horban@gmail.com","username":"mhorban"},"change_message_id":"f9c74748266abc9a26a5eda79ec51a48e3990fca","unresolved":false,"context_lines":[{"line_number":71,"context_line":""},{"line_number":72,"context_line":"        mock_rem_fs_remove.assert_called_once_with(\u0027src\u0027, \u0027host:dest\u0027)"},{"line_number":73,"context_line":""},{"line_number":74,"context_line":"    def test_copy_image_remote_rsync(self):"},{"line_number":75,"context_line":"        with mock.patch("},{"line_number":76,"context_line":"            \u0027nova.virt.libvirt.remotefs.RsyncRemoteFilesystem.copy_file\u0027) \\"},{"line_number":77,"context_line":"            as mock_rem_fs_remove:"}],"source_content_type":"text/x-python","patch_set":15,"id":"ba3cc151_3815a19a","line":74,"in_reply_to":"ba3cc151_f101c76b","updated":"2015-07-06 21:02:05.000000000","message":"Done","commit_id":"e8c61b56d395c605a2788fe0db905c54eef9f692"},{"author":{"_account_id":1653,"name":"garyk","email":"gkotton@vmware.com","username":"garyk"},"change_message_id":"f549bb69eff14903141f872b618c2ad9f459f3d4","unresolved":false,"context_lines":[{"line_number":75,"context_line":"        with mock.patch("},{"line_number":76,"context_line":"            \u0027nova.virt.libvirt.remotefs.RsyncRemoteFilesystem.copy_file\u0027) \\"},{"line_number":77,"context_line":"            as mock_rem_fs_remove:"},{"line_number":78,"context_line":"            CONF.libvirt.remote_filesystem_transport \u003d \u0027Rsync\u0027"},{"line_number":79,"context_line":"            libvirt_utils.copy_image(\u0027src\u0027, \u0027dest\u0027, host\u003d\u0027host\u0027)"},{"line_number":80,"context_line":""},{"line_number":81,"context_line":"        mock_rem_fs_remove.assert_called_once_with(\u0027src\u0027, \u0027host:dest\u0027)"}],"source_content_type":"text/x-python","patch_set":15,"id":"ba3cc151_31088f91","line":78,"updated":"2015-07-05 05:40:40.000000000","message":"ditto","commit_id":"e8c61b56d395c605a2788fe0db905c54eef9f692"},{"author":{"_account_id":14358,"name":"Marian Horban","email":"m.horban@gmail.com","username":"mhorban"},"change_message_id":"f9c74748266abc9a26a5eda79ec51a48e3990fca","unresolved":false,"context_lines":[{"line_number":75,"context_line":"        with mock.patch("},{"line_number":76,"context_line":"            \u0027nova.virt.libvirt.remotefs.RsyncRemoteFilesystem.copy_file\u0027) \\"},{"line_number":77,"context_line":"            as mock_rem_fs_remove:"},{"line_number":78,"context_line":"            CONF.libvirt.remote_filesystem_transport \u003d \u0027Rsync\u0027"},{"line_number":79,"context_line":"            libvirt_utils.copy_image(\u0027src\u0027, \u0027dest\u0027, host\u003d\u0027host\u0027)"},{"line_number":80,"context_line":""},{"line_number":81,"context_line":"        mock_rem_fs_remove.assert_called_once_with(\u0027src\u0027, \u0027host:dest\u0027)"}],"source_content_type":"text/x-python","patch_set":15,"id":"ba3cc151_d80b557c","line":78,"in_reply_to":"ba3cc151_31088f91","updated":"2015-07-06 21:02:05.000000000","message":"Done","commit_id":"e8c61b56d395c605a2788fe0db905c54eef9f692"}],"nova/virt/libvirt/driver.py":[{"author":{"_account_id":6849,"name":"Roman Podoliaka","email":"roman.podoliaka@gmail.com","username":"rpodolyaka"},"change_message_id":"418164e9a7026eed039d02a4d68af2562cf3b8bf","unresolved":false,"context_lines":[{"line_number":5810,"context_line":"                    shared_storage \u003d True"},{"line_number":5811,"context_line":"                    os.unlink(tmp_path)"},{"line_number":5812,"context_line":"                else:"},{"line_number":5813,"context_line":"                    libvirt_utils.remove_remote_dir(dest, inst_base)"},{"line_number":5814,"context_line":"            except Exception:"},{"line_number":5815,"context_line":"                pass"},{"line_number":5816,"context_line":"        return shared_storage"}],"source_content_type":"text/x-python","patch_set":3,"id":"3a961159_bbf2c56c","line":5813,"updated":"2015-01-15 16:02:55.000000000","message":"why do you remove the whole dir here? it actually contains instance data :)","commit_id":"d3f41d678dad14eaaf3782a3e502c95f578af690"},{"author":{"_account_id":14358,"name":"Marian Horban","email":"m.horban@gmail.com","username":"mhorban"},"change_message_id":"c852449ee8649dc01278c740d80a80268cce19bd","unresolved":false,"context_lines":[{"line_number":5810,"context_line":"                    shared_storage \u003d True"},{"line_number":5811,"context_line":"                    os.unlink(tmp_path)"},{"line_number":5812,"context_line":"                else:"},{"line_number":5813,"context_line":"                    libvirt_utils.remove_remote_dir(dest, inst_base)"},{"line_number":5814,"context_line":"            except Exception:"},{"line_number":5815,"context_line":"                pass"},{"line_number":5816,"context_line":"        return shared_storage"}],"source_content_type":"text/x-python","patch_set":3,"id":"3a961159_d053ae69","line":5813,"in_reply_to":"3a961159_bbf2c56c","updated":"2015-01-19 13:28:45.000000000","message":"You are right. I\u0027ll fix it.","commit_id":"d3f41d678dad14eaaf3782a3e502c95f578af690"},{"author":{"_account_id":1779,"name":"Daniel Berrange","email":"berrange@redhat.com","username":"berrange"},"change_message_id":"3d4d3e807c254fdf406102e001e23c9cadac6701","unresolved":false,"context_lines":[{"line_number":255,"context_line":"    cfg.BoolOpt(\u0027use_ssh\u0027,"},{"line_number":256,"context_line":"                default\u003dTrue,"},{"line_number":257,"context_line":"                help\u003d\u0027Use ssh for creating, copying, removing files \u0027"},{"line_number":258,"context_line":"                     \u0027on the remote host.\u0027)"},{"line_number":259,"context_line":"    ]"},{"line_number":260,"context_line":""},{"line_number":261,"context_line":"CONF \u003d cfg.CONF"}],"source_content_type":"text/x-python","patch_set":8,"id":"da86d52c_c6696ef9","line":258,"updated":"2015-02-18 18:07:51.000000000","message":"More future proof to call this   \u0027remotefs_transport\u0027 and have it accept either None, \u0027ssh\u0027 or \u0027rsync\u0027 as values, and make None be equivalent to ssh for now. Also declare this in the remotefs.py file instead of driver.py","commit_id":"8ee64f7d4eeada6e8b2a29ce6bbb31230bb60732"},{"author":{"_account_id":14358,"name":"Marian Horban","email":"m.horban@gmail.com","username":"mhorban"},"change_message_id":"0b81ebb38fc653916eb7796ac8782a330df0da32","unresolved":false,"context_lines":[{"line_number":255,"context_line":"    cfg.BoolOpt(\u0027use_ssh\u0027,"},{"line_number":256,"context_line":"                default\u003dTrue,"},{"line_number":257,"context_line":"                help\u003d\u0027Use ssh for creating, copying, removing files \u0027"},{"line_number":258,"context_line":"                     \u0027on the remote host.\u0027)"},{"line_number":259,"context_line":"    ]"},{"line_number":260,"context_line":""},{"line_number":261,"context_line":"CONF \u003d cfg.CONF"}],"source_content_type":"text/x-python","patch_set":8,"id":"9a80dd14_bef0d1fd","line":258,"in_reply_to":"da86d52c_c6696ef9","updated":"2015-03-20 17:15:22.000000000","message":"Done","commit_id":"8ee64f7d4eeada6e8b2a29ce6bbb31230bb60732"},{"author":{"_account_id":14358,"name":"Marian Horban","email":"m.horban@gmail.com","username":"mhorban"},"change_message_id":"a06e93ede89a8ab4d761837354c84dd55daea205","unresolved":false,"context_lines":[{"line_number":257,"context_line":"                help\u003d\u0027Use Ssh or Rsync transport for creating, copying,\u0027"},{"line_number":258,"context_line":"                     \u0027removing files on the remote host.\u0027)"},{"line_number":259,"context_line":"    ]"},{"line_number":260,"context_line":""},{"line_number":261,"context_line":""},{"line_number":262,"context_line":"CONF \u003d cfg.CONF"},{"line_number":263,"context_line":"CONF.register_opts(libvirt_opts, \u0027libvirt\u0027)"}],"source_content_type":"text/x-python","patch_set":9,"id":"da86d52c_3d2cebab","line":260,"updated":"2015-02-19 17:35:37.000000000","message":"To remove...","commit_id":"f06141aacc2babca16116b7458f44d54e3976122"},{"author":{"_account_id":14358,"name":"Marian Horban","email":"m.horban@gmail.com","username":"mhorban"},"change_message_id":"d3eed960102c694ff2331ba7a176bc93fcf88458","unresolved":false,"context_lines":[{"line_number":257,"context_line":"                help\u003d\u0027Use Ssh or Rsync transport for creating, copying,\u0027"},{"line_number":258,"context_line":"                     \u0027removing files on the remote host.\u0027)"},{"line_number":259,"context_line":"    ]"},{"line_number":260,"context_line":""},{"line_number":261,"context_line":""},{"line_number":262,"context_line":"CONF \u003d cfg.CONF"},{"line_number":263,"context_line":"CONF.register_opts(libvirt_opts, \u0027libvirt\u0027)"}],"source_content_type":"text/x-python","patch_set":9,"id":"9a80dd14_5e88b56a","line":260,"in_reply_to":"da86d52c_3d2cebab","updated":"2015-03-20 17:15:30.000000000","message":"Done","commit_id":"f06141aacc2babca16116b7458f44d54e3976122"},{"author":{"_account_id":1653,"name":"garyk","email":"gkotton@vmware.com","username":"garyk"},"change_message_id":"550ae47a21b2d2bf9ac4dd14a691544153125108","unresolved":false,"context_lines":[{"line_number":253,"context_line":"                     \u0027Syntax is guest-gid:host-gid:count\u0027"},{"line_number":254,"context_line":"                     \u0027Maximum of 5 allowed.\u0027),"},{"line_number":255,"context_line":"    cfg.StrOpt(\u0027remote_fs_transport\u0027,"},{"line_number":256,"context_line":"                default\u003d\u0027Ssh\u0027,"},{"line_number":257,"context_line":"                help\u003d\u0027Use Ssh or Rsync transport for creating, copying,\u0027"},{"line_number":258,"context_line":"                     \u0027removing files on the remote host.\u0027)"},{"line_number":259,"context_line":"    ]"}],"source_content_type":"text/x-python","patch_set":11,"id":"ba7be1f8_168f9224","line":256,"updated":"2015-03-01 14:12:21.000000000","message":"Why Ssh and not ssh?","commit_id":"624d5e7d2d8f470bc0dbcf2d737b2fc79b31599a"},{"author":{"_account_id":14358,"name":"Marian Horban","email":"m.horban@gmail.com","username":"mhorban"},"change_message_id":"b6aac004550deda09c0a34e21a008eb8e8f91288","unresolved":false,"context_lines":[{"line_number":253,"context_line":"                     \u0027Syntax is guest-gid:host-gid:count\u0027"},{"line_number":254,"context_line":"                     \u0027Maximum of 5 allowed.\u0027),"},{"line_number":255,"context_line":"    cfg.StrOpt(\u0027remote_fs_transport\u0027,"},{"line_number":256,"context_line":"                default\u003d\u0027Ssh\u0027,"},{"line_number":257,"context_line":"                help\u003d\u0027Use Ssh or Rsync transport for creating, copying,\u0027"},{"line_number":258,"context_line":"                     \u0027removing files on the remote host.\u0027)"},{"line_number":259,"context_line":"    ]"}],"source_content_type":"text/x-python","patch_set":11,"id":"9a80dd14_8e0044ac","line":256,"in_reply_to":"ba7be1f8_168f9224","updated":"2015-03-20 17:11:07.000000000","message":"Done","commit_id":"624d5e7d2d8f470bc0dbcf2d737b2fc79b31599a"},{"author":{"_account_id":1653,"name":"garyk","email":"gkotton@vmware.com","username":"garyk"},"change_message_id":"550ae47a21b2d2bf9ac4dd14a691544153125108","unresolved":false,"context_lines":[{"line_number":255,"context_line":"    cfg.StrOpt(\u0027remote_fs_transport\u0027,"},{"line_number":256,"context_line":"                default\u003d\u0027Ssh\u0027,"},{"line_number":257,"context_line":"                help\u003d\u0027Use Ssh or Rsync transport for creating, copying,\u0027"},{"line_number":258,"context_line":"                     \u0027removing files on the remote host.\u0027)"},{"line_number":259,"context_line":"    ]"},{"line_number":260,"context_line":""},{"line_number":261,"context_line":"CONF \u003d cfg.CONF"}],"source_content_type":"text/x-python","patch_set":11,"id":"ba7be1f8_769c4e5e","line":258,"updated":"2015-03-01 14:12:21.000000000","message":"please add: choices\u003d(\u0027ssh\u0027, \u0027rsync\u0027)","commit_id":"624d5e7d2d8f470bc0dbcf2d737b2fc79b31599a"},{"author":{"_account_id":14358,"name":"Marian Horban","email":"m.horban@gmail.com","username":"mhorban"},"change_message_id":"b6aac004550deda09c0a34e21a008eb8e8f91288","unresolved":false,"context_lines":[{"line_number":255,"context_line":"    cfg.StrOpt(\u0027remote_fs_transport\u0027,"},{"line_number":256,"context_line":"                default\u003d\u0027Ssh\u0027,"},{"line_number":257,"context_line":"                help\u003d\u0027Use Ssh or Rsync transport for creating, copying,\u0027"},{"line_number":258,"context_line":"                     \u0027removing files on the remote host.\u0027)"},{"line_number":259,"context_line":"    ]"},{"line_number":260,"context_line":""},{"line_number":261,"context_line":"CONF \u003d cfg.CONF"}],"source_content_type":"text/x-python","patch_set":11,"id":"9a80dd14_aefb48bc","line":258,"in_reply_to":"ba7be1f8_769c4e5e","updated":"2015-03-20 17:11:07.000000000","message":"Done","commit_id":"624d5e7d2d8f470bc0dbcf2d737b2fc79b31599a"},{"author":{"_account_id":1653,"name":"garyk","email":"gkotton@vmware.com","username":"garyk"},"change_message_id":"550ae47a21b2d2bf9ac4dd14a691544153125108","unresolved":false,"context_lines":[{"line_number":474,"context_line":"                   \u0027expect\u0027: \u0027, \u0027.join(\"\u0027%s\u0027\" % k for k in"},{"line_number":475,"context_line":"                                       sysinfo_serial_funcs.keys())})"},{"line_number":476,"context_line":""},{"line_number":477,"context_line":"        if (CONF.libvirt.remote_fs_transport not in"},{"line_number":478,"context_line":"                self.available_transport_drivers):"},{"line_number":479,"context_line":"            raise exception.NovaException("},{"line_number":480,"context_line":"                _(\"Unexpected remote_fs_transport setting \u0027%(actual)s\u0027. \""}],"source_content_type":"text/x-python","patch_set":11,"id":"ba7be1f8_b69de659","line":477,"updated":"2015-03-01 14:12:21.000000000","message":"i do not think that you need this if the the choices is used as requested above","commit_id":"624d5e7d2d8f470bc0dbcf2d737b2fc79b31599a"},{"author":{"_account_id":14358,"name":"Marian Horban","email":"m.horban@gmail.com","username":"mhorban"},"change_message_id":"b6aac004550deda09c0a34e21a008eb8e8f91288","unresolved":false,"context_lines":[{"line_number":474,"context_line":"                   \u0027expect\u0027: \u0027, \u0027.join(\"\u0027%s\u0027\" % k for k in"},{"line_number":475,"context_line":"                                       sysinfo_serial_funcs.keys())})"},{"line_number":476,"context_line":""},{"line_number":477,"context_line":"        if (CONF.libvirt.remote_fs_transport not in"},{"line_number":478,"context_line":"                self.available_transport_drivers):"},{"line_number":479,"context_line":"            raise exception.NovaException("},{"line_number":480,"context_line":"                _(\"Unexpected remote_fs_transport setting \u0027%(actual)s\u0027. \""}],"source_content_type":"text/x-python","patch_set":11,"id":"9a80dd14_ce2ddc47","line":477,"in_reply_to":"ba7be1f8_b69de659","updated":"2015-03-20 17:11:07.000000000","message":"Done","commit_id":"624d5e7d2d8f470bc0dbcf2d737b2fc79b31599a"},{"author":{"_account_id":6849,"name":"Roman Podoliaka","email":"roman.podoliaka@gmail.com","username":"rpodolyaka"},"change_message_id":"43b3b6429fd952b08434a7dfe113a7e0437a5ff1","unresolved":false,"context_lines":[{"line_number":468,"context_line":"                   \u0027expect\u0027: \u0027, \u0027.join(\"\u0027%s\u0027\" % k for k in"},{"line_number":469,"context_line":"                                       sysinfo_serial_funcs.keys())})"},{"line_number":470,"context_line":""},{"line_number":471,"context_line":"        self._remote_filesystem_driver \u003d getattr("},{"line_number":472,"context_line":"            remotefs, CONF.libvirt.remote_filesystem_transport +"},{"line_number":473,"context_line":"            \u0027RemoteFilesystem\u0027)()"},{"line_number":474,"context_line":""}],"source_content_type":"text/x-python","patch_set":17,"id":"9a41bdd9_c2d7a9eb","line":471,"updated":"2015-07-14 12:44:37.000000000","message":"nit: perhaps using of oslo.utils helper (https://github.com/openstack/oslo.utils/blob/master/oslo_utils/importutils.py#L36) would make this cleaner","commit_id":"e3bffd1b5723c6e63f437d651ddad23833099c8a"},{"author":{"_account_id":10618,"name":"Pavel Kholkin","email":"p.v.holkin@mail.ru","username":"pkholkin"},"change_message_id":"05a8d8fc843275c051df3d7dba3900f21a51bad3","unresolved":false,"context_lines":[{"line_number":468,"context_line":"                   \u0027expect\u0027: \u0027, \u0027.join(\"\u0027%s\u0027\" % k for k in"},{"line_number":469,"context_line":"                                       sysinfo_serial_funcs.keys())})"},{"line_number":470,"context_line":""},{"line_number":471,"context_line":"        self._remote_filesystem_driver \u003d getattr("},{"line_number":472,"context_line":"            remotefs, CONF.libvirt.remote_filesystem_transport +"},{"line_number":473,"context_line":"            \u0027RemoteFilesystem\u0027)()"},{"line_number":474,"context_line":""}],"source_content_type":"text/x-python","patch_set":17,"id":"9a41bdd9_2f01996a","line":471,"in_reply_to":"9a41bdd9_c2d7a9eb","updated":"2015-07-14 13:56:10.000000000","message":"Done","commit_id":"e3bffd1b5723c6e63f437d651ddad23833099c8a"},{"author":{"_account_id":6849,"name":"Roman Podoliaka","email":"roman.podoliaka@gmail.com","username":"rpodolyaka"},"change_message_id":"b263008878fae9c42877b2c4624b1b943ee050e1","unresolved":false,"context_lines":[{"line_number":467,"context_line":"                   \u0027expect\u0027: \u0027, \u0027.join(\"\u0027%s\u0027\" % k for k in"},{"line_number":468,"context_line":"                                       sysinfo_serial_funcs.keys())})"},{"line_number":469,"context_line":""},{"line_number":470,"context_line":"        self._remote_filesystem_driver \u003d importutils.import_object("},{"line_number":471,"context_line":"            \u0027nova.virt.libvirt.remotefs.\u0027 +"},{"line_number":472,"context_line":"            CONF.libvirt.remote_filesystem_transport.capitalize()"},{"line_number":473,"context_line":"            + \u0027RemoteFilesystem\u0027)"}],"source_content_type":"text/x-python","patch_set":18,"id":"9a41bdd9_642ee044","line":470,"updated":"2015-07-14 15:38:03.000000000","message":"how about we put this into a factory function within remotefs.py?\n\n\nSomething like:\n\ndef get_driver(backend\u003dNone):\n    if backend is None:\n        backend \u003d CONF.libvirt.remove_filesystem_transport\n\n     return importutils.import_object(...)","commit_id":"9bf12dfb37d7a316061e96d74d9c09257153cbcf"},{"author":{"_account_id":10618,"name":"Pavel Kholkin","email":"p.v.holkin@mail.ru","username":"pkholkin"},"change_message_id":"c30c8397b4734d84cbcc7ed8c30efd67c0ac2dcf","unresolved":false,"context_lines":[{"line_number":467,"context_line":"                   \u0027expect\u0027: \u0027, \u0027.join(\"\u0027%s\u0027\" % k for k in"},{"line_number":468,"context_line":"                                       sysinfo_serial_funcs.keys())})"},{"line_number":469,"context_line":""},{"line_number":470,"context_line":"        self._remote_filesystem_driver \u003d importutils.import_object("},{"line_number":471,"context_line":"            \u0027nova.virt.libvirt.remotefs.\u0027 +"},{"line_number":472,"context_line":"            CONF.libvirt.remote_filesystem_transport.capitalize()"},{"line_number":473,"context_line":"            + \u0027RemoteFilesystem\u0027)"}],"source_content_type":"text/x-python","patch_set":18,"id":"9a41bdd9_4cc89ea8","line":470,"in_reply_to":"9a41bdd9_642ee044","updated":"2015-07-14 17:20:25.000000000","message":"yes, looks better","commit_id":"9bf12dfb37d7a316061e96d74d9c09257153cbcf"},{"author":{"_account_id":1653,"name":"garyk","email":"gkotton@vmware.com","username":"garyk"},"change_message_id":"f6219e71489946e7d76edac31650298567153b69","unresolved":false,"context_lines":[{"line_number":6262,"context_line":"                utils.execute(\u0027rm\u0027, \u0027-rf\u0027, inst_base)"},{"line_number":6263,"context_line":"                utils.execute(\u0027mv\u0027, inst_base_resize, inst_base)"},{"line_number":6264,"context_line":"                if not shared_storage:"},{"line_number":6265,"context_line":"                    self._remote_filesystem_driver.remove_dir(dest, inst_base)"},{"line_number":6266,"context_line":"        except Exception:"},{"line_number":6267,"context_line":"            pass"},{"line_number":6268,"context_line":""}],"source_content_type":"text/x-python","patch_set":21,"id":"9a41bdd9_c6e6a114","line":6265,"updated":"2015-07-15 11:26:19.000000000","message":"is it possible that this is called from more than one host at the same time? do we need locking?","commit_id":"61edfb6254734ee53bfa8054164c3cb8fe0e4750"},{"author":{"_account_id":14358,"name":"Marian Horban","email":"m.horban@gmail.com","username":"mhorban"},"change_message_id":"443955d7ce00b38ca600002e54019f76a44ddb67","unresolved":false,"context_lines":[{"line_number":6262,"context_line":"                utils.execute(\u0027rm\u0027, \u0027-rf\u0027, inst_base)"},{"line_number":6263,"context_line":"                utils.execute(\u0027mv\u0027, inst_base_resize, inst_base)"},{"line_number":6264,"context_line":"                if not shared_storage:"},{"line_number":6265,"context_line":"                    self._remote_filesystem_driver.remove_dir(dest, inst_base)"},{"line_number":6266,"context_line":"        except Exception:"},{"line_number":6267,"context_line":"            pass"},{"line_number":6268,"context_line":""}],"source_content_type":"text/x-python","patch_set":21,"id":"3a50d1a3_e339f2f3","line":6265,"in_reply_to":"9a41bdd9_c6e6a114","updated":"2015-07-24 09:06:57.000000000","message":"My understanding is that at the same time only one host could remove specific dir on remote host. That\u0027s why we don\u0027t need locking.","commit_id":"61edfb6254734ee53bfa8054164c3cb8fe0e4750"},{"author":{"_account_id":1779,"name":"Daniel Berrange","email":"berrange@redhat.com","username":"berrange"},"change_message_id":"ce9703e799421b6e0a37814af9908efa1c16146f","unresolved":false,"context_lines":[{"line_number":466,"context_line":"                   \u0027expect\u0027: \u0027, \u0027.join(\"\u0027%s\u0027\" % k for k in"},{"line_number":467,"context_line":"                                       sysinfo_serial_funcs.keys())})"},{"line_number":468,"context_line":""},{"line_number":469,"context_line":"        self._remote_filesystem_driver \u003d remotefs.get_driver()"},{"line_number":470,"context_line":""},{"line_number":471,"context_line":"    def _get_volume_drivers(self):"},{"line_number":472,"context_line":"        return libvirt_volume_drivers"}],"source_content_type":"text/x-python","patch_set":23,"id":"3a50d1a3_a2c26c51","line":469,"updated":"2015-07-28 15:44:56.000000000","message":"This variable name is waaay to verbose. Just call it   self._remotefs","commit_id":"6dabea7a5b373155f345a29dc2eb0df493bbc7b3"},{"author":{"_account_id":14358,"name":"Marian Horban","email":"m.horban@gmail.com","username":"mhorban"},"change_message_id":"2fcb6885614c2a850c90e715e6d6d279c19989ca","unresolved":false,"context_lines":[{"line_number":466,"context_line":"                   \u0027expect\u0027: \u0027, \u0027.join(\"\u0027%s\u0027\" % k for k in"},{"line_number":467,"context_line":"                                       sysinfo_serial_funcs.keys())})"},{"line_number":468,"context_line":""},{"line_number":469,"context_line":"        self._remote_filesystem_driver \u003d remotefs.get_driver()"},{"line_number":470,"context_line":""},{"line_number":471,"context_line":"    def _get_volume_drivers(self):"},{"line_number":472,"context_line":"        return libvirt_volume_drivers"}],"source_content_type":"text/x-python","patch_set":23,"id":"3a50d1a3_ebc84f57","line":469,"in_reply_to":"3a50d1a3_a2c26c51","updated":"2015-07-28 16:58:23.000000000","message":"Done","commit_id":"6dabea7a5b373155f345a29dc2eb0df493bbc7b3"}],"nova/virt/libvirt/remotefs.py":[{"author":{"_account_id":1779,"name":"Daniel Berrange","email":"berrange@redhat.com","username":"berrange"},"change_message_id":"3d4d3e807c254fdf406102e001e23c9cadac6701","unresolved":false,"context_lines":[{"line_number":105,"context_line":""},{"line_number":106,"context_line":""},{"line_number":107,"context_line":"@create_tmp_dir"},{"line_number":108,"context_line":"def remove_remote_file_rsync(host, dst, **kwargs):"},{"line_number":109,"context_line":"    \"\"\"Removes a file on a remote host."},{"line_number":110,"context_line":""},{"line_number":111,"context_line":"    :param host: Remote host"}],"source_content_type":"text/x-python","patch_set":8,"id":"da86d52c_49302fe9","line":108,"updated":"2015-02-18 18:07:51.000000000","message":"Since this isn\u0027t intended for direct use, perhaps prefix a \u0027_\u0027 on the name - likewise for the _ssh \u0026 _rsync helpers which follow.","commit_id":"8ee64f7d4eeada6e8b2a29ce6bbb31230bb60732"},{"author":{"_account_id":6849,"name":"Roman Podoliaka","email":"roman.podoliaka@gmail.com","username":"rpodolyaka"},"change_message_id":"f46c62280071c52d7da1c122653d75459534fc8e","unresolved":false,"context_lines":[{"line_number":202,"context_line":"    utils.execute(\u0027ssh\u0027, host, \u0027rm\u0027, \u0027-rf\u0027, dst)"},{"line_number":203,"context_line":""},{"line_number":204,"context_line":""},{"line_number":205,"context_line":"def remove_remote_dir(host, dst):"},{"line_number":206,"context_line":"    if CONF.libvirt.use_ssh:"},{"line_number":207,"context_line":"        remove_remote_ssh(host, dst)"},{"line_number":208,"context_line":"    else:"}],"source_content_type":"text/x-python","patch_set":8,"id":"da86d52c_265b2a55","line":205,"updated":"2015-02-18 18:03:51.000000000","message":"Can we put this into two different classes and create an instance based on the config option value in the driver code? (so that we\u0027d use polymorphism to dispatch these calls)","commit_id":"8ee64f7d4eeada6e8b2a29ce6bbb31230bb60732"},{"author":{"_account_id":1779,"name":"Daniel Berrange","email":"berrange@redhat.com","username":"berrange"},"change_message_id":"3d4d3e807c254fdf406102e001e23c9cadac6701","unresolved":false,"context_lines":[{"line_number":202,"context_line":"    utils.execute(\u0027ssh\u0027, host, \u0027rm\u0027, \u0027-rf\u0027, dst)"},{"line_number":203,"context_line":""},{"line_number":204,"context_line":""},{"line_number":205,"context_line":"def remove_remote_dir(host, dst):"},{"line_number":206,"context_line":"    if CONF.libvirt.use_ssh:"},{"line_number":207,"context_line":"        remove_remote_ssh(host, dst)"},{"line_number":208,"context_line":"    else:"}],"source_content_type":"text/x-python","patch_set":8,"id":"da86d52c_c96a5fb4","line":205,"in_reply_to":"da86d52c_265b2a55","updated":"2015-02-18 18:07:51.000000000","message":"If we take my suggestion of using a  CONF variable  remotefs_transport, then we don\u0027t need classes. we can just build the method name to invoke programatically  \"remove_remote_dir_\" + CONF.libvirt.remotefs_transport.","commit_id":"8ee64f7d4eeada6e8b2a29ce6bbb31230bb60732"},{"author":{"_account_id":6849,"name":"Roman Podoliaka","email":"roman.podoliaka@gmail.com","username":"rpodolyaka"},"change_message_id":"83a46b0efa89edd52a7b7f6813d51b2cd7db82ea","unresolved":false,"context_lines":[{"line_number":202,"context_line":"    utils.execute(\u0027ssh\u0027, host, \u0027rm\u0027, \u0027-rf\u0027, dst)"},{"line_number":203,"context_line":""},{"line_number":204,"context_line":""},{"line_number":205,"context_line":"def remove_remote_dir(host, dst):"},{"line_number":206,"context_line":"    if CONF.libvirt.use_ssh:"},{"line_number":207,"context_line":"        remove_remote_ssh(host, dst)"},{"line_number":208,"context_line":"    else:"}],"source_content_type":"text/x-python","patch_set":8,"id":"da86d52c_cfaa4470","line":205,"in_reply_to":"da86d52c_c96a5fb4","updated":"2015-02-19 10:48:24.000000000","message":"I\u0027m not really a \u0027use OOP for everything\u0027 person, but IMO, inheritance and polymorphism is a much cleaner way to solve this problem...","commit_id":"8ee64f7d4eeada6e8b2a29ce6bbb31230bb60732"},{"author":{"_account_id":1779,"name":"Daniel Berrange","email":"berrange@redhat.com","username":"berrange"},"change_message_id":"c592a0327d84d24d0e120d637af29c37363278fd","unresolved":false,"context_lines":[{"line_number":202,"context_line":"    utils.execute(\u0027ssh\u0027, host, \u0027rm\u0027, \u0027-rf\u0027, dst)"},{"line_number":203,"context_line":""},{"line_number":204,"context_line":""},{"line_number":205,"context_line":"def remove_remote_dir(host, dst):"},{"line_number":206,"context_line":"    if CONF.libvirt.use_ssh:"},{"line_number":207,"context_line":"        remove_remote_ssh(host, dst)"},{"line_number":208,"context_line":"    else:"}],"source_content_type":"text/x-python","patch_set":8,"id":"da86d52c_2f7e80e4","line":205,"in_reply_to":"da86d52c_cfaa4470","updated":"2015-02-19 10:54:04.000000000","message":"Its just way overkill IMHO","commit_id":"8ee64f7d4eeada6e8b2a29ce6bbb31230bb60732"},{"author":{"_account_id":8412,"name":"Mike Durnosvistov","email":"glacierr.dev@gmail.com","username":"mdurnosvistov"},"change_message_id":"9f1f04d6b9ed3609b3d55553bf65cb417122cf7e","unresolved":false,"context_lines":[{"line_number":68,"context_line":"                          export_path)"},{"line_number":69,"context_line":""},{"line_number":70,"context_line":""},{"line_number":71,"context_line":"class SshRemoteFs(object):"},{"line_number":72,"context_line":""},{"line_number":73,"context_line":"    @staticmethod"},{"line_number":74,"context_line":"    def create_file(host, dst_path):"}],"source_content_type":"text/x-python","patch_set":12,"id":"9a80dd14_907ea3ad","line":71,"range":{"start_line":71,"start_character":6,"end_line":71,"end_character":17},"updated":"2015-03-20 14:51:52.000000000","message":"Maybe class name SSHRemoteFS is more appropriate?","commit_id":"2559539fb88e481ba703985b4b0d0469a7219238"},{"author":{"_account_id":14358,"name":"Marian Horban","email":"m.horban@gmail.com","username":"mhorban"},"change_message_id":"6d1260b59cdcc78f252d7936814183a08935f937","unresolved":false,"context_lines":[{"line_number":68,"context_line":"                          export_path)"},{"line_number":69,"context_line":""},{"line_number":70,"context_line":""},{"line_number":71,"context_line":"class SshRemoteFs(object):"},{"line_number":72,"context_line":""},{"line_number":73,"context_line":"    @staticmethod"},{"line_number":74,"context_line":"    def create_file(host, dst_path):"}],"source_content_type":"text/x-python","patch_set":12,"id":"9a80dd14_4ec56c8c","line":71,"in_reply_to":"9a80dd14_907ea3ad","updated":"2015-03-20 17:11:21.000000000","message":"1.SshRemoreFs\n2.SSHRemoteFS\nand\n1.RsyncRemoteFs\n2.RSYNCRemoteFS\nAs for me first variant is better.","commit_id":"2559539fb88e481ba703985b4b0d0469a7219238"},{"author":{"_account_id":1653,"name":"garyk","email":"gkotton@vmware.com","username":"garyk"},"change_message_id":"f549bb69eff14903141f872b618c2ad9f459f3d4","unresolved":false,"context_lines":[{"line_number":32,"context_line":"    cfg.StrOpt(\u0027remote_filesystem_transport\u0027,"},{"line_number":33,"context_line":"               default\u003d\u0027Ssh\u0027,"},{"line_number":34,"context_line":"               choices\u003d(\u0027Ssh\u0027, \u0027Rsync\u0027),"},{"line_number":35,"context_line":"               help\u003d\u0027Use ssh or rsync transport for creating, copying,\u0027"},{"line_number":36,"context_line":"                    \u0027removing files on the remote host.\u0027),"},{"line_number":37,"context_line":"    ]"},{"line_number":38,"context_line":""}],"source_content_type":"text/x-python","patch_set":15,"id":"ba3cc151_b1f49f87","line":35,"updated":"2015-07-05 05:40:40.000000000","message":"missing space at the end of the line","commit_id":"e8c61b56d395c605a2788fe0db905c54eef9f692"},{"author":{"_account_id":14358,"name":"Marian Horban","email":"m.horban@gmail.com","username":"mhorban"},"change_message_id":"f9c74748266abc9a26a5eda79ec51a48e3990fca","unresolved":false,"context_lines":[{"line_number":32,"context_line":"    cfg.StrOpt(\u0027remote_filesystem_transport\u0027,"},{"line_number":33,"context_line":"               default\u003d\u0027Ssh\u0027,"},{"line_number":34,"context_line":"               choices\u003d(\u0027Ssh\u0027, \u0027Rsync\u0027),"},{"line_number":35,"context_line":"               help\u003d\u0027Use ssh or rsync transport for creating, copying,\u0027"},{"line_number":36,"context_line":"                    \u0027removing files on the remote host.\u0027),"},{"line_number":37,"context_line":"    ]"},{"line_number":38,"context_line":""}],"source_content_type":"text/x-python","patch_set":15,"id":"ba3cc151_f8cc19bd","line":35,"in_reply_to":"ba3cc151_b1f49f87","updated":"2015-07-06 21:02:05.000000000","message":"Done","commit_id":"e8c61b56d395c605a2788fe0db905c54eef9f692"},{"author":{"_account_id":6849,"name":"Roman Podoliaka","email":"roman.podoliaka@gmail.com","username":"rpodolyaka"},"change_message_id":"43b3b6429fd952b08434a7dfe113a7e0437a5ff1","unresolved":false,"context_lines":[{"line_number":31,"context_line":"libvirt_opts \u003d ["},{"line_number":32,"context_line":"    cfg.StrOpt(\u0027remote_filesystem_transport\u0027,"},{"line_number":33,"context_line":"               default\u003d\u0027Ssh\u0027,"},{"line_number":34,"context_line":"               choices\u003d(\u0027Ssh\u0027, \u0027Rsync\u0027),"},{"line_number":35,"context_line":"               help\u003d\u0027Use ssh or rsync transport for creating, copying, \u0027"},{"line_number":36,"context_line":"                    \u0027removing files on the remote host.\u0027),"},{"line_number":37,"context_line":"    ]"}],"source_content_type":"text/x-python","patch_set":17,"id":"9a41bdd9_c24569b3","line":34,"updated":"2015-07-14 12:44:37.000000000","message":"nit: those are usually mentioned in lower-case (as well as config options values)","commit_id":"e3bffd1b5723c6e63f437d651ddad23833099c8a"},{"author":{"_account_id":10618,"name":"Pavel Kholkin","email":"p.v.holkin@mail.ru","username":"pkholkin"},"change_message_id":"05a8d8fc843275c051df3d7dba3900f21a51bad3","unresolved":false,"context_lines":[{"line_number":31,"context_line":"libvirt_opts \u003d ["},{"line_number":32,"context_line":"    cfg.StrOpt(\u0027remote_filesystem_transport\u0027,"},{"line_number":33,"context_line":"               default\u003d\u0027Ssh\u0027,"},{"line_number":34,"context_line":"               choices\u003d(\u0027Ssh\u0027, \u0027Rsync\u0027),"},{"line_number":35,"context_line":"               help\u003d\u0027Use ssh or rsync transport for creating, copying, \u0027"},{"line_number":36,"context_line":"                    \u0027removing files on the remote host.\u0027),"},{"line_number":37,"context_line":"    ]"}],"source_content_type":"text/x-python","patch_set":17,"id":"9a41bdd9_4f2dfdfc","line":34,"in_reply_to":"9a41bdd9_c24569b3","updated":"2015-07-14 13:56:10.000000000","message":"Done","commit_id":"e3bffd1b5723c6e63f437d651ddad23833099c8a"},{"author":{"_account_id":6849,"name":"Roman Podoliaka","email":"roman.podoliaka@gmail.com","username":"rpodolyaka"},"change_message_id":"43b3b6429fd952b08434a7dfe113a7e0437a5ff1","unresolved":false,"context_lines":[{"line_number":82,"context_line":"                          export_path)"},{"line_number":83,"context_line":""},{"line_number":84,"context_line":""},{"line_number":85,"context_line":"class AbstarctSingleton(abc.ABCMeta):"},{"line_number":86,"context_line":"    _instances \u003d {}"},{"line_number":87,"context_line":""},{"line_number":88,"context_line":"    def __call__(cls, *args, **kwargs):"}],"source_content_type":"text/x-python","patch_set":17,"id":"9a41bdd9_62133db9","line":85,"updated":"2015-07-14 12:44:37.000000000","message":"type: Abstract","commit_id":"e3bffd1b5723c6e63f437d651ddad23833099c8a"},{"author":{"_account_id":10618,"name":"Pavel Kholkin","email":"p.v.holkin@mail.ru","username":"pkholkin"},"change_message_id":"05a8d8fc843275c051df3d7dba3900f21a51bad3","unresolved":false,"context_lines":[{"line_number":82,"context_line":"                          export_path)"},{"line_number":83,"context_line":""},{"line_number":84,"context_line":""},{"line_number":85,"context_line":"class AbstarctSingleton(abc.ABCMeta):"},{"line_number":86,"context_line":"    _instances \u003d {}"},{"line_number":87,"context_line":""},{"line_number":88,"context_line":"    def __call__(cls, *args, **kwargs):"}],"source_content_type":"text/x-python","patch_set":17,"id":"9a41bdd9_0f337563","line":85,"in_reply_to":"9a41bdd9_62133db9","updated":"2015-07-14 13:56:10.000000000","message":"Done","commit_id":"e3bffd1b5723c6e63f437d651ddad23833099c8a"},{"author":{"_account_id":6849,"name":"Roman Podoliaka","email":"roman.podoliaka@gmail.com","username":"rpodolyaka"},"change_message_id":"43b3b6429fd952b08434a7dfe113a7e0437a5ff1","unresolved":false,"context_lines":[{"line_number":86,"context_line":"    _instances \u003d {}"},{"line_number":87,"context_line":""},{"line_number":88,"context_line":"    def __call__(cls, *args, **kwargs):"},{"line_number":89,"context_line":"        if cls not in cls._instances:"},{"line_number":90,"context_line":"            cls._instances[cls] \u003d super(AbstarctSingleton, cls).__call__("},{"line_number":91,"context_line":"                *args, **kwargs)"},{"line_number":92,"context_line":"        return cls._instances[cls]"}],"source_content_type":"text/x-python","patch_set":17,"id":"9a41bdd9_627a5df3","line":89,"updated":"2015-07-14 12:44:37.000000000","message":"not a big deal, but this is not thread-safe. Can we add an explicit lock here?","commit_id":"e3bffd1b5723c6e63f437d651ddad23833099c8a"},{"author":{"_account_id":10618,"name":"Pavel Kholkin","email":"p.v.holkin@mail.ru","username":"pkholkin"},"change_message_id":"05a8d8fc843275c051df3d7dba3900f21a51bad3","unresolved":false,"context_lines":[{"line_number":86,"context_line":"    _instances \u003d {}"},{"line_number":87,"context_line":""},{"line_number":88,"context_line":"    def __call__(cls, *args, **kwargs):"},{"line_number":89,"context_line":"        if cls not in cls._instances:"},{"line_number":90,"context_line":"            cls._instances[cls] \u003d super(AbstarctSingleton, cls).__call__("},{"line_number":91,"context_line":"                *args, **kwargs)"},{"line_number":92,"context_line":"        return cls._instances[cls]"}],"source_content_type":"text/x-python","patch_set":17,"id":"9a41bdd9_2f38b93c","line":89,"in_reply_to":"9a41bdd9_627a5df3","updated":"2015-07-14 13:56:10.000000000","message":"Done","commit_id":"e3bffd1b5723c6e63f437d651ddad23833099c8a"},{"author":{"_account_id":6849,"name":"Roman Podoliaka","email":"roman.podoliaka@gmail.com","username":"rpodolyaka"},"change_message_id":"90a38624a01f92f5be00c0e38f3c8231ac71115b","unresolved":false,"context_lines":[{"line_number":88,"context_line":"    _instances \u003d {}"},{"line_number":89,"context_line":""},{"line_number":90,"context_line":"    def __call__(cls, *args, **kwargs):"},{"line_number":91,"context_line":"        global _LOCK"},{"line_number":92,"context_line":"        if cls not in cls._instances:"},{"line_number":93,"context_line":"            with _LOCK:"},{"line_number":94,"context_line":"                cls._instances[cls] \u003d super(AbstractSingleton, cls).__call__("}],"source_content_type":"text/x-python","patch_set":18,"id":"9a41bdd9_e4d3d002","line":91,"updated":"2015-07-14 15:40:59.000000000","message":"hmm, I took a look at https://github.com/openstack/oslo.concurrency/blob/master/oslo_concurrency/lockutils.py#L163 - it seems we could avoid using an explicit global variable here and just use the context manager","commit_id":"9bf12dfb37d7a316061e96d74d9c09257153cbcf"},{"author":{"_account_id":10618,"name":"Pavel Kholkin","email":"p.v.holkin@mail.ru","username":"pkholkin"},"change_message_id":"c30c8397b4734d84cbcc7ed8c30efd67c0ac2dcf","unresolved":false,"context_lines":[{"line_number":88,"context_line":"    _instances \u003d {}"},{"line_number":89,"context_line":""},{"line_number":90,"context_line":"    def __call__(cls, *args, **kwargs):"},{"line_number":91,"context_line":"        global _LOCK"},{"line_number":92,"context_line":"        if cls not in cls._instances:"},{"line_number":93,"context_line":"            with _LOCK:"},{"line_number":94,"context_line":"                cls._instances[cls] \u003d super(AbstractSingleton, cls).__call__("}],"source_content_type":"text/x-python","patch_set":18,"id":"9a41bdd9_6c44821a","line":91,"in_reply_to":"9a41bdd9_e4d3d002","updated":"2015-07-14 17:20:25.000000000","message":"Done","commit_id":"9bf12dfb37d7a316061e96d74d9c09257153cbcf"},{"author":{"_account_id":1653,"name":"garyk","email":"gkotton@vmware.com","username":"garyk"},"change_message_id":"f6219e71489946e7d76edac31650298567153b69","unresolved":false,"context_lines":[{"line_number":84,"context_line":"                          export_path)"},{"line_number":85,"context_line":""},{"line_number":86,"context_line":""},{"line_number":87,"context_line":"def get_driver(backend\u003dNone):"},{"line_number":88,"context_line":"    if not backend:"},{"line_number":89,"context_line":"        backend \u003d CONF.libvirt.remote_filesystem_transport"},{"line_number":90,"context_line":""}],"source_content_type":"text/x-python","patch_set":21,"id":"9a41bdd9_e696453d","line":87,"updated":"2015-07-15 11:26:19.000000000","message":"Can you please add a docstring here explaining what backend is.","commit_id":"61edfb6254734ee53bfa8054164c3cb8fe0e4750"},{"author":{"_account_id":14358,"name":"Marian Horban","email":"m.horban@gmail.com","username":"mhorban"},"change_message_id":"443955d7ce00b38ca600002e54019f76a44ddb67","unresolved":false,"context_lines":[{"line_number":84,"context_line":"                          export_path)"},{"line_number":85,"context_line":""},{"line_number":86,"context_line":""},{"line_number":87,"context_line":"def get_driver(backend\u003dNone):"},{"line_number":88,"context_line":"    if not backend:"},{"line_number":89,"context_line":"        backend \u003d CONF.libvirt.remote_filesystem_transport"},{"line_number":90,"context_line":""}],"source_content_type":"text/x-python","patch_set":21,"id":"3a50d1a3_559419e7","line":87,"in_reply_to":"9a41bdd9_e696453d","updated":"2015-07-24 09:06:57.000000000","message":"Done","commit_id":"61edfb6254734ee53bfa8054164c3cb8fe0e4750"},{"author":{"_account_id":1653,"name":"garyk","email":"gkotton@vmware.com","username":"garyk"},"change_message_id":"f6219e71489946e7d76edac31650298567153b69","unresolved":false,"context_lines":[{"line_number":89,"context_line":"        backend \u003d CONF.libvirt.remote_filesystem_transport"},{"line_number":90,"context_line":""},{"line_number":91,"context_line":"    return importutils.import_object(\u0027nova.virt.libvirt.remotefs.\u0027 +"},{"line_number":92,"context_line":"                                     backend.capitalize() + \u0027RemoteFilesystem\u0027)"},{"line_number":93,"context_line":""},{"line_number":94,"context_line":""},{"line_number":95,"context_line":"class AbstractSingleton(abc.ABCMeta):"}],"source_content_type":"text/x-python","patch_set":21,"id":"9a41bdd9_a6a59da2","line":92,"updated":"2015-07-15 11:26:19.000000000","message":"not 100% sure wht we need the capitalize here - can you please explain","commit_id":"61edfb6254734ee53bfa8054164c3cb8fe0e4750"},{"author":{"_account_id":14358,"name":"Marian Horban","email":"m.horban@gmail.com","username":"mhorban"},"change_message_id":"443955d7ce00b38ca600002e54019f76a44ddb67","unresolved":false,"context_lines":[{"line_number":89,"context_line":"        backend \u003d CONF.libvirt.remote_filesystem_transport"},{"line_number":90,"context_line":""},{"line_number":91,"context_line":"    return importutils.import_object(\u0027nova.virt.libvirt.remotefs.\u0027 +"},{"line_number":92,"context_line":"                                     backend.capitalize() + \u0027RemoteFilesystem\u0027)"},{"line_number":93,"context_line":""},{"line_number":94,"context_line":""},{"line_number":95,"context_line":"class AbstractSingleton(abc.ABCMeta):"}],"source_content_type":"text/x-python","patch_set":21,"id":"3a50d1a3_5562d917","line":92,"in_reply_to":"9a41bdd9_a6a59da2","updated":"2015-07-24 09:06:57.000000000","message":"Capitalization removed.\nI don\u0027t like it too.\nIt was used because uppercase of class name: SshRemoteFilesystem, RsyncRemoteFilesystem.","commit_id":"61edfb6254734ee53bfa8054164c3cb8fe0e4750"},{"author":{"_account_id":1653,"name":"garyk","email":"gkotton@vmware.com","username":"garyk"},"change_message_id":"f6219e71489946e7d76edac31650298567153b69","unresolved":false,"context_lines":[{"line_number":210,"context_line":"        local_tmp_file \u003d os.path.join(local_tmp_dir, file_name)"},{"line_number":211,"context_line":"        utils.execute(\u0027touch\u0027, local_tmp_file)"},{"line_number":212,"context_line":"        RsyncRemoteFilesystem._synchronize_object(kwargs[\u0027tmp_dir_path\u0027],"},{"line_number":213,"context_line":"                                          host, dst_path)"},{"line_number":214,"context_line":""},{"line_number":215,"context_line":"    @staticmethod"},{"line_number":216,"context_line":"    @create_tmp_dir"}],"source_content_type":"text/x-python","patch_set":21,"id":"9a41bdd9_86bf39a9","line":213,"updated":"2015-07-15 11:26:19.000000000","message":"indentation here is a little dodgy\nif possible can you please have the h under the k","commit_id":"61edfb6254734ee53bfa8054164c3cb8fe0e4750"},{"author":{"_account_id":14358,"name":"Marian Horban","email":"m.horban@gmail.com","username":"mhorban"},"change_message_id":"443955d7ce00b38ca600002e54019f76a44ddb67","unresolved":false,"context_lines":[{"line_number":210,"context_line":"        local_tmp_file \u003d os.path.join(local_tmp_dir, file_name)"},{"line_number":211,"context_line":"        utils.execute(\u0027touch\u0027, local_tmp_file)"},{"line_number":212,"context_line":"        RsyncRemoteFilesystem._synchronize_object(kwargs[\u0027tmp_dir_path\u0027],"},{"line_number":213,"context_line":"                                          host, dst_path)"},{"line_number":214,"context_line":""},{"line_number":215,"context_line":"    @staticmethod"},{"line_number":216,"context_line":"    @create_tmp_dir"}],"source_content_type":"text/x-python","patch_set":21,"id":"3a50d1a3_58e8d016","line":213,"in_reply_to":"9a41bdd9_86bf39a9","updated":"2015-07-24 09:06:57.000000000","message":"Done","commit_id":"61edfb6254734ee53bfa8054164c3cb8fe0e4750"},{"author":{"_account_id":1653,"name":"garyk","email":"gkotton@vmware.com","username":"garyk"},"change_message_id":"f6219e71489946e7d76edac31650298567153b69","unresolved":false,"context_lines":[{"line_number":228,"context_line":"                                 dir_path.strip(os.path.sep))"},{"line_number":229,"context_line":"        utils.execute(\u0027mkdir\u0027, \u0027-p\u0027, local_tmp_dir)"},{"line_number":230,"context_line":"        RsyncRemoteFilesystem._synchronize_object(kwargs[\u0027tmp_dir_path\u0027],"},{"line_number":231,"context_line":"                                          host, dst_path)"},{"line_number":232,"context_line":""},{"line_number":233,"context_line":"    @staticmethod"},{"line_number":234,"context_line":"    @create_tmp_dir"}],"source_content_type":"text/x-python","patch_set":21,"id":"9a41bdd9_e6fba579","line":231,"updated":"2015-07-15 11:26:19.000000000","message":"ditto","commit_id":"61edfb6254734ee53bfa8054164c3cb8fe0e4750"},{"author":{"_account_id":14358,"name":"Marian Horban","email":"m.horban@gmail.com","username":"mhorban"},"change_message_id":"443955d7ce00b38ca600002e54019f76a44ddb67","unresolved":false,"context_lines":[{"line_number":228,"context_line":"                                 dir_path.strip(os.path.sep))"},{"line_number":229,"context_line":"        utils.execute(\u0027mkdir\u0027, \u0027-p\u0027, local_tmp_dir)"},{"line_number":230,"context_line":"        RsyncRemoteFilesystem._synchronize_object(kwargs[\u0027tmp_dir_path\u0027],"},{"line_number":231,"context_line":"                                          host, dst_path)"},{"line_number":232,"context_line":""},{"line_number":233,"context_line":"    @staticmethod"},{"line_number":234,"context_line":"    @create_tmp_dir"}],"source_content_type":"text/x-python","patch_set":21,"id":"3a50d1a3_78ed8c24","line":231,"in_reply_to":"9a41bdd9_e6fba579","updated":"2015-07-24 09:06:57.000000000","message":"Done","commit_id":"61edfb6254734ee53bfa8054164c3cb8fe0e4750"},{"author":{"_account_id":1653,"name":"garyk","email":"gkotton@vmware.com","username":"garyk"},"change_message_id":"f6219e71489946e7d76edac31650298567153b69","unresolved":false,"context_lines":[{"line_number":278,"context_line":""},{"line_number":279,"context_line":"        # Do relative rsync local directory with remote root directory"},{"line_number":280,"context_line":"        utils.execute(\u0027rsync\u0027, \u0027--archive\u0027, \u0027--relative\u0027, \u0027--no-implied-dirs\u0027,"},{"line_number":281,"context_line":"                relative_tmp_file_path, \u0027%s:%s\u0027 % (host, os.path.sep))"},{"line_number":282,"context_line":""},{"line_number":283,"context_line":"    @staticmethod"},{"line_number":284,"context_line":"    def copy_file(src, dst):"}],"source_content_type":"text/x-python","patch_set":21,"id":"9a41bdd9_262d0dfe","line":281,"updated":"2015-07-15 11:26:19.000000000","message":"please fix indentation here","commit_id":"61edfb6254734ee53bfa8054164c3cb8fe0e4750"},{"author":{"_account_id":14358,"name":"Marian Horban","email":"m.horban@gmail.com","username":"mhorban"},"change_message_id":"443955d7ce00b38ca600002e54019f76a44ddb67","unresolved":false,"context_lines":[{"line_number":278,"context_line":""},{"line_number":279,"context_line":"        # Do relative rsync local directory with remote root directory"},{"line_number":280,"context_line":"        utils.execute(\u0027rsync\u0027, \u0027--archive\u0027, \u0027--relative\u0027, \u0027--no-implied-dirs\u0027,"},{"line_number":281,"context_line":"                relative_tmp_file_path, \u0027%s:%s\u0027 % (host, os.path.sep))"},{"line_number":282,"context_line":""},{"line_number":283,"context_line":"    @staticmethod"},{"line_number":284,"context_line":"    def copy_file(src, dst):"}],"source_content_type":"text/x-python","patch_set":21,"id":"3a50d1a3_d8dce076","line":281,"in_reply_to":"9a41bdd9_262d0dfe","updated":"2015-07-24 09:06:57.000000000","message":"Done","commit_id":"61edfb6254734ee53bfa8054164c3cb8fe0e4750"},{"author":{"_account_id":6849,"name":"Roman Podoliaka","email":"roman.podoliaka@gmail.com","username":"rpodolyaka"},"change_message_id":"ca4a913de9afbdf61e8ba78a472378881f8b5fec","unresolved":false,"context_lines":[{"line_number":94,"context_line":"        transport \u003d CONF.libvirt.remote_filesystem_transport"},{"line_number":95,"context_line":""},{"line_number":96,"context_line":"    return importutils.import_object("},{"line_number":97,"context_line":"        \u0027.\u0027.join([__name__, transport + \u0027RemoteFilesystem\u0027]))"},{"line_number":98,"context_line":""},{"line_number":99,"context_line":""},{"line_number":100,"context_line":"class AbstractSingleton(abc.ABCMeta):"}],"source_content_type":"text/x-python","patch_set":22,"id":"3a50d1a3_8f5da5ee","line":97,"updated":"2015-07-24 13:11:28.000000000","message":"nit: let\u0027s do transport.capitalize() here to have class names starting with a capital letter","commit_id":"5cdcdbd18a7c11cc4be9f8daa5802e3a96041489"},{"author":{"_account_id":14358,"name":"Marian Horban","email":"m.horban@gmail.com","username":"mhorban"},"change_message_id":"3fb676df5f5c0f78b1c73a0cf84e169d68acc77c","unresolved":false,"context_lines":[{"line_number":94,"context_line":"        transport \u003d CONF.libvirt.remote_filesystem_transport"},{"line_number":95,"context_line":""},{"line_number":96,"context_line":"    return importutils.import_object("},{"line_number":97,"context_line":"        \u0027.\u0027.join([__name__, transport + \u0027RemoteFilesystem\u0027]))"},{"line_number":98,"context_line":""},{"line_number":99,"context_line":""},{"line_number":100,"context_line":"class AbstractSingleton(abc.ABCMeta):"}],"source_content_type":"text/x-python","patch_set":22,"id":"3a50d1a3_f87b5fbc","line":97,"in_reply_to":"3a50d1a3_8f5da5ee","updated":"2015-07-28 08:07:43.000000000","message":"Done","commit_id":"5cdcdbd18a7c11cc4be9f8daa5802e3a96041489"},{"author":{"_account_id":6849,"name":"Roman Podoliaka","email":"roman.podoliaka@gmail.com","username":"rpodolyaka"},"change_message_id":"ca4a913de9afbdf61e8ba78a472378881f8b5fec","unresolved":false,"context_lines":[{"line_number":155,"context_line":"        \"\"\""},{"line_number":156,"context_line":""},{"line_number":157,"context_line":""},{"line_number":158,"context_line":"class sshRemoteFilesystem(RemoteFilesystem):"},{"line_number":159,"context_line":""},{"line_number":160,"context_line":"    @staticmethod"},{"line_number":161,"context_line":"    def create_file(host, dst_path):"}],"source_content_type":"text/x-python","patch_set":22,"id":"3a50d1a3_efe30932","line":158,"updated":"2015-07-24 13:11:28.000000000","message":"nit: let\u0027s stick to our existing convention for class naming and start this name with a capital letter","commit_id":"5cdcdbd18a7c11cc4be9f8daa5802e3a96041489"},{"author":{"_account_id":14358,"name":"Marian Horban","email":"m.horban@gmail.com","username":"mhorban"},"change_message_id":"3fb676df5f5c0f78b1c73a0cf84e169d68acc77c","unresolved":false,"context_lines":[{"line_number":155,"context_line":"        \"\"\""},{"line_number":156,"context_line":""},{"line_number":157,"context_line":""},{"line_number":158,"context_line":"class sshRemoteFilesystem(RemoteFilesystem):"},{"line_number":159,"context_line":""},{"line_number":160,"context_line":"    @staticmethod"},{"line_number":161,"context_line":"    def create_file(host, dst_path):"}],"source_content_type":"text/x-python","patch_set":22,"id":"3a50d1a3_b8507733","line":158,"in_reply_to":"3a50d1a3_efe30932","updated":"2015-07-28 08:07:43.000000000","message":"Done","commit_id":"5cdcdbd18a7c11cc4be9f8daa5802e3a96041489"},{"author":{"_account_id":6849,"name":"Roman Podoliaka","email":"roman.podoliaka@gmail.com","username":"rpodolyaka"},"change_message_id":"ca4a913de9afbdf61e8ba78a472378881f8b5fec","unresolved":false,"context_lines":[{"line_number":198,"context_line":"    return decorated_function"},{"line_number":199,"context_line":""},{"line_number":200,"context_line":""},{"line_number":201,"context_line":"class rsyncRemoteFilesystem(RemoteFilesystem):"},{"line_number":202,"context_line":""},{"line_number":203,"context_line":"    @staticmethod"},{"line_number":204,"context_line":"    @create_tmp_dir"}],"source_content_type":"text/x-python","patch_set":22,"id":"3a50d1a3_af3bc19b","line":201,"updated":"2015-07-24 13:11:28.000000000","message":"ditto","commit_id":"5cdcdbd18a7c11cc4be9f8daa5802e3a96041489"},{"author":{"_account_id":14358,"name":"Marian Horban","email":"m.horban@gmail.com","username":"mhorban"},"change_message_id":"3fb676df5f5c0f78b1c73a0cf84e169d68acc77c","unresolved":false,"context_lines":[{"line_number":198,"context_line":"    return decorated_function"},{"line_number":199,"context_line":""},{"line_number":200,"context_line":""},{"line_number":201,"context_line":"class rsyncRemoteFilesystem(RemoteFilesystem):"},{"line_number":202,"context_line":""},{"line_number":203,"context_line":"    @staticmethod"},{"line_number":204,"context_line":"    @create_tmp_dir"}],"source_content_type":"text/x-python","patch_set":22,"id":"3a50d1a3_18608b00","line":201,"in_reply_to":"3a50d1a3_af3bc19b","updated":"2015-07-28 08:07:43.000000000","message":"Done","commit_id":"5cdcdbd18a7c11cc4be9f8daa5802e3a96041489"},{"author":{"_account_id":6849,"name":"Roman Podoliaka","email":"roman.podoliaka@gmail.com","username":"rpodolyaka"},"change_message_id":"b82ad7cc58e2c4876cbec47374f8ddc9b61713cb","unresolved":false,"context_lines":[{"line_number":111,"context_line":"@six.add_metaclass(AbstractSingleton)"},{"line_number":112,"context_line":"class RemoteFilesystem(object):"},{"line_number":113,"context_line":"    @abc.abstractmethod"},{"line_number":114,"context_line":"    def create_file(self, host, dst_path):"},{"line_number":115,"context_line":"        \"\"\"Create file on the remote system."},{"line_number":116,"context_line":""},{"line_number":117,"context_line":"        :param host: Remote host"}],"source_content_type":"text/x-python","patch_set":23,"id":"3a50d1a3_b3face75","line":114,"updated":"2015-07-28 11:44:58.000000000","message":"This looks a bit confusing, given the fact those methods are overridden as static by subclasses, but there seems to be no clean and easy way to make static method abstract in Python 2.x, so I don\u0027t think it\u0027s a big deal","commit_id":"6dabea7a5b373155f345a29dc2eb0df493bbc7b3"},{"author":{"_account_id":14358,"name":"Marian Horban","email":"m.horban@gmail.com","username":"mhorban"},"change_message_id":"f482a15d2b3a735392fe81a62c79c622fa318dc6","unresolved":false,"context_lines":[{"line_number":111,"context_line":"@six.add_metaclass(AbstractSingleton)"},{"line_number":112,"context_line":"class RemoteFilesystem(object):"},{"line_number":113,"context_line":"    @abc.abstractmethod"},{"line_number":114,"context_line":"    def create_file(self, host, dst_path):"},{"line_number":115,"context_line":"        \"\"\"Create file on the remote system."},{"line_number":116,"context_line":""},{"line_number":117,"context_line":"        :param host: Remote host"}],"source_content_type":"text/x-python","patch_set":23,"id":"3a50d1a3_76eb9b13","line":114,"in_reply_to":"3a50d1a3_16d35ed6","updated":"2015-07-29 10:36:56.000000000","message":"and finally... done (in 25 patch set)","commit_id":"6dabea7a5b373155f345a29dc2eb0df493bbc7b3"},{"author":{"_account_id":14358,"name":"Marian Horban","email":"m.horban@gmail.com","username":"mhorban"},"change_message_id":"2fcb6885614c2a850c90e715e6d6d279c19989ca","unresolved":false,"context_lines":[{"line_number":111,"context_line":"@six.add_metaclass(AbstractSingleton)"},{"line_number":112,"context_line":"class RemoteFilesystem(object):"},{"line_number":113,"context_line":"    @abc.abstractmethod"},{"line_number":114,"context_line":"    def create_file(self, host, dst_path):"},{"line_number":115,"context_line":"        \"\"\"Create file on the remote system."},{"line_number":116,"context_line":""},{"line_number":117,"context_line":"        :param host: Remote host"}],"source_content_type":"text/x-python","patch_set":23,"id":"3a50d1a3_16d35ed6","line":114,"in_reply_to":"3a50d1a3_42904843","updated":"2015-07-28 16:58:23.000000000","message":"Could you please explain why it is confusing? Looks like Python handles it well. My point of view is that parent class(RemoteFilesystem) is interface class and it should not impose details of implementation. Interface class must ensure that derived classes implement all abstract methods and it doesn\u0027t matter if these methods are static or non-static. Maybe the next remote FS driver(some RPC remote FS driver with complicated initialization) will be non-static.","commit_id":"6dabea7a5b373155f345a29dc2eb0df493bbc7b3"},{"author":{"_account_id":1779,"name":"Daniel Berrange","email":"berrange@redhat.com","username":"berrange"},"change_message_id":"ce9703e799421b6e0a37814af9908efa1c16146f","unresolved":false,"context_lines":[{"line_number":111,"context_line":"@six.add_metaclass(AbstractSingleton)"},{"line_number":112,"context_line":"class RemoteFilesystem(object):"},{"line_number":113,"context_line":"    @abc.abstractmethod"},{"line_number":114,"context_line":"    def create_file(self, host, dst_path):"},{"line_number":115,"context_line":"        \"\"\"Create file on the remote system."},{"line_number":116,"context_line":""},{"line_number":117,"context_line":"        :param host: Remote host"}],"source_content_type":"text/x-python","patch_set":23,"id":"3a50d1a3_42904843","line":114,"in_reply_to":"3a50d1a3_b3face75","updated":"2015-07-28 15:44:56.000000000","message":"The subclass should simply not make them static. It causes confusion when a parent method is not static but an impl is static, or vica verca. We should pick one and be consistent.","commit_id":"6dabea7a5b373155f345a29dc2eb0df493bbc7b3"},{"author":{"_account_id":1779,"name":"Daniel Berrange","email":"berrange@redhat.com","username":"berrange"},"change_message_id":"ce9703e799421b6e0a37814af9908efa1c16146f","unresolved":false,"context_lines":[{"line_number":158,"context_line":"class SshRemoteFilesystem(RemoteFilesystem):"},{"line_number":159,"context_line":""},{"line_number":160,"context_line":"    @staticmethod"},{"line_number":161,"context_line":"    def create_file(host, dst_path):"},{"line_number":162,"context_line":"        utils.execute(\u0027ssh\u0027, host, \u0027touch\u0027, dst_path)"},{"line_number":163,"context_line":""},{"line_number":164,"context_line":"    @staticmethod"}],"source_content_type":"text/x-python","patch_set":23,"id":"3a50d1a3_82aad06f","line":161,"updated":"2015-07-28 15:44:56.000000000","message":"Don\u0027t mark these as static, as the parent class methods aren\u0027t declared static.","commit_id":"6dabea7a5b373155f345a29dc2eb0df493bbc7b3"},{"author":{"_account_id":14358,"name":"Marian Horban","email":"m.horban@gmail.com","username":"mhorban"},"change_message_id":"f482a15d2b3a735392fe81a62c79c622fa318dc6","unresolved":false,"context_lines":[{"line_number":158,"context_line":"class SshRemoteFilesystem(RemoteFilesystem):"},{"line_number":159,"context_line":""},{"line_number":160,"context_line":"    @staticmethod"},{"line_number":161,"context_line":"    def create_file(host, dst_path):"},{"line_number":162,"context_line":"        utils.execute(\u0027ssh\u0027, host, \u0027touch\u0027, dst_path)"},{"line_number":163,"context_line":""},{"line_number":164,"context_line":"    @staticmethod"}],"source_content_type":"text/x-python","patch_set":23,"id":"3a50d1a3_36f19301","line":161,"in_reply_to":"3a50d1a3_82aad06f","updated":"2015-07-29 10:36:56.000000000","message":"Done","commit_id":"6dabea7a5b373155f345a29dc2eb0df493bbc7b3"},{"author":{"_account_id":7,"name":"Jay Pipes","email":"jaypipes@gmail.com","username":"jaypipes"},"change_message_id":"6efdf9e16febd8d836dc85bfdedd31d16657cd30","unresolved":false,"context_lines":[{"line_number":16,"context_line":"import abc"},{"line_number":17,"context_line":"import functools"},{"line_number":18,"context_line":"import os"},{"line_number":19,"context_line":"import six"},{"line_number":20,"context_line":"import tempfile"},{"line_number":21,"context_line":""},{"line_number":22,"context_line":"from oslo_concurrency import lockutils"}],"source_content_type":"text/x-python","patch_set":25,"id":"3a50d1a3_517097dc","line":19,"updated":"2015-07-30 19:06:53.000000000","message":"nit: technically six is a 3rd part import and so should come below the from oslo_utils import importutils line below...","commit_id":"ea6d312c22bd214e34d5122133cea15b26dd3099"},{"author":{"_account_id":14358,"name":"Marian Horban","email":"m.horban@gmail.com","username":"mhorban"},"change_message_id":"36f3b8ade560fca46b19f80c5ce6fc7f340db122","unresolved":false,"context_lines":[{"line_number":16,"context_line":"import abc"},{"line_number":17,"context_line":"import functools"},{"line_number":18,"context_line":"import os"},{"line_number":19,"context_line":"import six"},{"line_number":20,"context_line":"import tempfile"},{"line_number":21,"context_line":""},{"line_number":22,"context_line":"from oslo_concurrency import lockutils"}],"source_content_type":"text/x-python","patch_set":25,"id":"1a4dcd0f_56c188e3","line":19,"in_reply_to":"3a50d1a3_517097dc","updated":"2015-08-03 20:04:06.000000000","message":"Done","commit_id":"ea6d312c22bd214e34d5122133cea15b26dd3099"},{"author":{"_account_id":7,"name":"Jay Pipes","email":"jaypipes@gmail.com","username":"jaypipes"},"change_message_id":"6efdf9e16febd8d836dc85bfdedd31d16657cd30","unresolved":false,"context_lines":[{"line_number":84,"context_line":"                          export_path)"},{"line_number":85,"context_line":""},{"line_number":86,"context_line":""},{"line_number":87,"context_line":"def get_driver(transport\u003dNone):"},{"line_number":88,"context_line":"    \"\"\"Get remote FS driver."},{"line_number":89,"context_line":""},{"line_number":90,"context_line":"    :param transport: remote file system transport."}],"source_content_type":"text/x-python","patch_set":25,"id":"3a50d1a3_6c5e1c7b","line":87,"updated":"2015-07-30 19:06:53.000000000","message":"If we used a driver composition pattern, we could entirely hide the driver implementation and configuration option behind a main RemoteFilesystem object constructor. That would remove the need to call this get_driver() method and instead allow the calling code to do something like this instead:\n\n from nova.virt.libvirt import remotefs\n ...\n\n fs \u003d remotefs.RemoteFilesystem()\n fs.copy_file(...)\n\nYou can use a driver composition pattern like so:\n\n class RemoteFilesystem(object):\n     \"\"\"Represents actions that can be taken on a remote host\u0027s filesystem.\"\"\"\n \n     def __init__(self):\n         transport \u003d CONF.libvirt.remote_filesystem_transport\n         cls_name \u003d \u0027.\u0027.join([__name__, transport.capitalize()])\n         cls_name +\u003d \u0027.RemoteFilesystemDriver\u0027\n         self.driver \u003d importutils.import_object(cls_name)\n\n    def create_file(self, host, dst_path):\n        LOG.debug(\"Creating file %s on remote host %s\", dst_path, host)\n        self.driver.create_file(host, dst_path)\n\n    ...","commit_id":"ea6d312c22bd214e34d5122133cea15b26dd3099"},{"author":{"_account_id":14358,"name":"Marian Horban","email":"m.horban@gmail.com","username":"mhorban"},"change_message_id":"36f3b8ade560fca46b19f80c5ce6fc7f340db122","unresolved":false,"context_lines":[{"line_number":84,"context_line":"                          export_path)"},{"line_number":85,"context_line":""},{"line_number":86,"context_line":""},{"line_number":87,"context_line":"def get_driver(transport\u003dNone):"},{"line_number":88,"context_line":"    \"\"\"Get remote FS driver."},{"line_number":89,"context_line":""},{"line_number":90,"context_line":"    :param transport: remote file system transport."}],"source_content_type":"text/x-python","patch_set":25,"id":"1a4dcd0f_3e8dc57b","line":87,"in_reply_to":"3a50d1a3_6c5e1c7b","updated":"2015-08-03 20:04:06.000000000","message":"Done","commit_id":"ea6d312c22bd214e34d5122133cea15b26dd3099"},{"author":{"_account_id":7,"name":"Jay Pipes","email":"jaypipes@gmail.com","username":"jaypipes"},"change_message_id":"6efdf9e16febd8d836dc85bfdedd31d16657cd30","unresolved":false,"context_lines":[{"line_number":105,"context_line":"            if cls not in cls._instances:"},{"line_number":106,"context_line":"                cls._instances[cls] \u003d super(AbstractSingleton, cls).__call__("},{"line_number":107,"context_line":"                    *args, **kwargs)"},{"line_number":108,"context_line":"        return cls._instances[cls]"},{"line_number":109,"context_line":""},{"line_number":110,"context_line":""},{"line_number":111,"context_line":"@six.add_metaclass(AbstractSingleton)"}],"source_content_type":"text/x-python","patch_set":25,"id":"3a50d1a3_2c3fb488","line":108,"updated":"2015-07-30 19:06:53.000000000","message":"Is this really necessary? Seems like premature optimization to me. It\u0027s not like these driver objects maintain any state at all, so creating driver objects is not expensive. The above singleton stuff just adds needless complexity to the code, IMHO.","commit_id":"ea6d312c22bd214e34d5122133cea15b26dd3099"},{"author":{"_account_id":14358,"name":"Marian Horban","email":"m.horban@gmail.com","username":"mhorban"},"change_message_id":"36f3b8ade560fca46b19f80c5ce6fc7f340db122","unresolved":false,"context_lines":[{"line_number":105,"context_line":"            if cls not in cls._instances:"},{"line_number":106,"context_line":"                cls._instances[cls] \u003d super(AbstractSingleton, cls).__call__("},{"line_number":107,"context_line":"                    *args, **kwargs)"},{"line_number":108,"context_line":"        return cls._instances[cls]"},{"line_number":109,"context_line":""},{"line_number":110,"context_line":""},{"line_number":111,"context_line":"@six.add_metaclass(AbstractSingleton)"}],"source_content_type":"text/x-python","patch_set":25,"id":"1a4dcd0f_3e69458c","line":108,"in_reply_to":"3a50d1a3_2c3fb488","updated":"2015-08-03 20:04:06.000000000","message":"It is not necessary. I\u0027m wondering who invented it? Removed.","commit_id":"ea6d312c22bd214e34d5122133cea15b26dd3099"},{"author":{"_account_id":7,"name":"Jay Pipes","email":"jaypipes@gmail.com","username":"jaypipes"},"change_message_id":"6efdf9e16febd8d836dc85bfdedd31d16657cd30","unresolved":false,"context_lines":[{"line_number":109,"context_line":""},{"line_number":110,"context_line":""},{"line_number":111,"context_line":"@six.add_metaclass(AbstractSingleton)"},{"line_number":112,"context_line":"class RemoteFilesystem(object):"},{"line_number":113,"context_line":"    @abc.abstractmethod"},{"line_number":114,"context_line":"    def create_file(self, host, dst_path):"},{"line_number":115,"context_line":"        \"\"\"Create file on the remote system."}],"source_content_type":"text/x-python","patch_set":25,"id":"3a50d1a3_8cca8819","line":112,"updated":"2015-07-30 19:06:53.000000000","message":"Add \"Driver\" at the end of this interface class (and the derived concrete classes that inherit from it below).","commit_id":"ea6d312c22bd214e34d5122133cea15b26dd3099"},{"author":{"_account_id":14358,"name":"Marian Horban","email":"m.horban@gmail.com","username":"mhorban"},"change_message_id":"36f3b8ade560fca46b19f80c5ce6fc7f340db122","unresolved":false,"context_lines":[{"line_number":109,"context_line":""},{"line_number":110,"context_line":""},{"line_number":111,"context_line":"@six.add_metaclass(AbstractSingleton)"},{"line_number":112,"context_line":"class RemoteFilesystem(object):"},{"line_number":113,"context_line":"    @abc.abstractmethod"},{"line_number":114,"context_line":"    def create_file(self, host, dst_path):"},{"line_number":115,"context_line":"        \"\"\"Create file on the remote system."}],"source_content_type":"text/x-python","patch_set":25,"id":"1a4dcd0f_fe099dde","line":112,"in_reply_to":"3a50d1a3_8cca8819","updated":"2015-08-03 20:04:06.000000000","message":"Done","commit_id":"ea6d312c22bd214e34d5122133cea15b26dd3099"}],"nova/virt/libvirt/utils.py":[{"author":{"_account_id":6849,"name":"Roman Podoliaka","email":"roman.podoliaka@gmail.com","username":"rpodolyaka"},"change_message_id":"418164e9a7026eed039d02a4d68af2562cf3b8bf","unresolved":false,"context_lines":[{"line_number":262,"context_line":"    return backing_file"},{"line_number":263,"context_line":""},{"line_number":264,"context_line":""},{"line_number":265,"context_line":"def create_tmp_dir(function):"},{"line_number":266,"context_line":"    \"\"\"Creates temporary directory in /tmp for rsync purposes."},{"line_number":267,"context_line":"    Removes created directory in the end."},{"line_number":268,"context_line":"    \"\"\""}],"source_content_type":"text/x-python","patch_set":3,"id":"3a961159_26d95c83","line":265,"updated":"2015-01-15 16:02:55.000000000","message":"nit: we could probably use https://docs.python.org/2/library/tempfile.html#tempfile.mkdtemp here","commit_id":"d3f41d678dad14eaaf3782a3e502c95f578af690"},{"author":{"_account_id":14358,"name":"Marian Horban","email":"m.horban@gmail.com","username":"mhorban"},"change_message_id":"c852449ee8649dc01278c740d80a80268cce19bd","unresolved":false,"context_lines":[{"line_number":262,"context_line":"    return backing_file"},{"line_number":263,"context_line":""},{"line_number":264,"context_line":""},{"line_number":265,"context_line":"def create_tmp_dir(function):"},{"line_number":266,"context_line":"    \"\"\"Creates temporary directory in /tmp for rsync purposes."},{"line_number":267,"context_line":"    Removes created directory in the end."},{"line_number":268,"context_line":"    \"\"\""}],"source_content_type":"text/x-python","patch_set":3,"id":"3a961159_104a96ac","line":265,"in_reply_to":"3a961159_26d95c83","updated":"2015-01-19 13:28:45.000000000","message":"Done","commit_id":"d3f41d678dad14eaaf3782a3e502c95f578af690"},{"author":{"_account_id":6849,"name":"Roman Podoliaka","email":"roman.podoliaka@gmail.com","username":"rpodolyaka"},"change_message_id":"418164e9a7026eed039d02a4d68af2562cf3b8bf","unresolved":false,"context_lines":[{"line_number":267,"context_line":"    Removes created directory in the end."},{"line_number":268,"context_line":"    \"\"\""},{"line_number":269,"context_line":""},{"line_number":270,"context_line":"    def decorated_function(*args, **kwargs):"},{"line_number":271,"context_line":"        # Create empty directory"},{"line_number":272,"context_line":"        tmp_dir \u003d uuid.uuid4().hex"},{"line_number":273,"context_line":"        tmp_dir_path \u003d os.path.join(\u0027/tmp\u0027, tmp_dir)"}],"source_content_type":"text/x-python","patch_set":3,"id":"3a961159_9b626914","line":270,"updated":"2015-01-15 16:02:55.000000000","message":"please use https://docs.python.org/2/library/functools.html#functools.wraps here to ensure all important function attributes are copied to the wrapper function","commit_id":"d3f41d678dad14eaaf3782a3e502c95f578af690"},{"author":{"_account_id":14358,"name":"Marian Horban","email":"m.horban@gmail.com","username":"mhorban"},"change_message_id":"c852449ee8649dc01278c740d80a80268cce19bd","unresolved":false,"context_lines":[{"line_number":267,"context_line":"    Removes created directory in the end."},{"line_number":268,"context_line":"    \"\"\""},{"line_number":269,"context_line":""},{"line_number":270,"context_line":"    def decorated_function(*args, **kwargs):"},{"line_number":271,"context_line":"        # Create empty directory"},{"line_number":272,"context_line":"        tmp_dir \u003d uuid.uuid4().hex"},{"line_number":273,"context_line":"        tmp_dir_path \u003d os.path.join(\u0027/tmp\u0027, tmp_dir)"}],"source_content_type":"text/x-python","patch_set":3,"id":"3a961159_70cafa1a","line":270,"in_reply_to":"3a961159_9b626914","updated":"2015-01-19 13:28:45.000000000","message":"Done","commit_id":"d3f41d678dad14eaaf3782a3e502c95f578af690"},{"author":{"_account_id":6849,"name":"Roman Podoliaka","email":"roman.podoliaka@gmail.com","username":"rpodolyaka"},"change_message_id":"418164e9a7026eed039d02a4d68af2562cf3b8bf","unresolved":false,"context_lines":[{"line_number":275,"context_line":"        kwargs[\u0027tmp_dir_path\u0027] \u003d tmp_dir_path"},{"line_number":276,"context_line":""},{"line_number":277,"context_line":"        try:"},{"line_number":278,"context_line":"            function(*args, **kwargs)"},{"line_number":279,"context_line":"        finally:"},{"line_number":280,"context_line":"            # Remove empty directory"},{"line_number":281,"context_line":"            utils.execute(\u0027rm\u0027, \u0027-rf\u0027, tmp_dir_path)"}],"source_content_type":"text/x-python","patch_set":3,"id":"3a961159_9b498990","line":278,"updated":"2015-01-15 16:02:55.000000000","message":"nit: to make it more general, we could probably add a \u0027return\u0027 statement here (although, none of the proposed function use this yet)","commit_id":"d3f41d678dad14eaaf3782a3e502c95f578af690"},{"author":{"_account_id":14358,"name":"Marian Horban","email":"m.horban@gmail.com","username":"mhorban"},"change_message_id":"c852449ee8649dc01278c740d80a80268cce19bd","unresolved":false,"context_lines":[{"line_number":275,"context_line":"        kwargs[\u0027tmp_dir_path\u0027] \u003d tmp_dir_path"},{"line_number":276,"context_line":""},{"line_number":277,"context_line":"        try:"},{"line_number":278,"context_line":"            function(*args, **kwargs)"},{"line_number":279,"context_line":"        finally:"},{"line_number":280,"context_line":"            # Remove empty directory"},{"line_number":281,"context_line":"            utils.execute(\u0027rm\u0027, \u0027-rf\u0027, tmp_dir_path)"}],"source_content_type":"text/x-python","patch_set":3,"id":"3a961159_90cda632","line":278,"in_reply_to":"3a961159_9b498990","updated":"2015-01-19 13:28:45.000000000","message":"Done","commit_id":"d3f41d678dad14eaaf3782a3e502c95f578af690"},{"author":{"_account_id":6849,"name":"Roman Podoliaka","email":"roman.podoliaka@gmail.com","username":"rpodolyaka"},"change_message_id":"418164e9a7026eed039d02a4d68af2562cf3b8bf","unresolved":false,"context_lines":[{"line_number":277,"context_line":"        try:"},{"line_number":278,"context_line":"            function(*args, **kwargs)"},{"line_number":279,"context_line":"        finally:"},{"line_number":280,"context_line":"            # Remove empty directory"},{"line_number":281,"context_line":"            utils.execute(\u0027rm\u0027, \u0027-rf\u0027, tmp_dir_path)"},{"line_number":282,"context_line":""},{"line_number":283,"context_line":"    return decorated_function"}],"source_content_type":"text/x-python","patch_set":3,"id":"3a961159_c6afb89b","line":280,"updated":"2015-01-15 16:02:55.000000000","message":"nit: it\u0027s not always empty :)","commit_id":"d3f41d678dad14eaaf3782a3e502c95f578af690"},{"author":{"_account_id":14358,"name":"Marian Horban","email":"m.horban@gmail.com","username":"mhorban"},"change_message_id":"c852449ee8649dc01278c740d80a80268cce19bd","unresolved":false,"context_lines":[{"line_number":277,"context_line":"        try:"},{"line_number":278,"context_line":"            function(*args, **kwargs)"},{"line_number":279,"context_line":"        finally:"},{"line_number":280,"context_line":"            # Remove empty directory"},{"line_number":281,"context_line":"            utils.execute(\u0027rm\u0027, \u0027-rf\u0027, tmp_dir_path)"},{"line_number":282,"context_line":""},{"line_number":283,"context_line":"    return decorated_function"}],"source_content_type":"text/x-python","patch_set":3,"id":"3a961159_b0d0e2c8","line":280,"in_reply_to":"3a961159_c6afb89b","updated":"2015-01-19 13:28:45.000000000","message":":)","commit_id":"d3f41d678dad14eaaf3782a3e502c95f578af690"},{"author":{"_account_id":6849,"name":"Roman Podoliaka","email":"roman.podoliaka@gmail.com","username":"rpodolyaka"},"change_message_id":"418164e9a7026eed039d02a4d68af2562cf3b8bf","unresolved":false,"context_lines":[{"line_number":316,"context_line":""},{"line_number":317,"context_line":""},{"line_number":318,"context_line":"@create_tmp_dir"},{"line_number":319,"context_line":"def create_remote_dir(host, dst_dir, **kwargs):"},{"line_number":320,"context_line":"    \"\"\"Create directory on the remote system."},{"line_number":321,"context_line":""},{"line_number":322,"context_line":"    :param host: Remote host"}],"source_content_type":"text/x-python","patch_set":3,"id":"3a961159_a6162ca5","line":319,"updated":"2015-01-15 16:02:55.000000000","message":"hmm, will it create parent directories as needed? (as mkdir -p would do)","commit_id":"d3f41d678dad14eaaf3782a3e502c95f578af690"},{"author":{"_account_id":14358,"name":"Marian Horban","email":"m.horban@gmail.com","username":"mhorban"},"change_message_id":"c852449ee8649dc01278c740d80a80268cce19bd","unresolved":false,"context_lines":[{"line_number":316,"context_line":""},{"line_number":317,"context_line":""},{"line_number":318,"context_line":"@create_tmp_dir"},{"line_number":319,"context_line":"def create_remote_dir(host, dst_dir, **kwargs):"},{"line_number":320,"context_line":"    \"\"\"Create directory on the remote system."},{"line_number":321,"context_line":""},{"line_number":322,"context_line":"    :param host: Remote host"}],"source_content_type":"text/x-python","patch_set":3,"id":"3a961159_7377649f","line":319,"in_reply_to":"3a961159_a6162ca5","updated":"2015-01-19 13:28:45.000000000","message":"Current implementation expects that all dirs except the latest are exists. \nWill be fixed.","commit_id":"d3f41d678dad14eaaf3782a3e502c95f578af690"},{"author":{"_account_id":6849,"name":"Roman Podoliaka","email":"roman.podoliaka@gmail.com","username":"rpodolyaka"},"change_message_id":"5614e359fec1721906e0a792427cfc28c91091dd","unresolved":false,"context_lines":[{"line_number":292,"context_line":"    :param file_type: Type of file, can be \u0027regular\u0027 or \u0027directory\u0027"},{"line_number":293,"context_line":"    \"\"\""},{"line_number":294,"context_line":""},{"line_number":295,"context_line":"    if file_type \u003d\u003d \u0027directory\u0027:"},{"line_number":296,"context_line":"        # Remove remote directory\u0027s content"},{"line_number":297,"context_line":"        utils.execute(\u0027rsync\u0027, \u0027--archive\u0027, \u0027--delete-excluded\u0027,"},{"line_number":298,"context_line":"                  kwargs[\u0027tmp_dir_path\u0027] + os.path.sep,"}],"source_content_type":"text/x-python","patch_set":5,"id":"3a961159_76a73dbd","line":295,"updated":"2015-01-19 14:42:30.000000000","message":"I don\u0027t really like the idea of dispatching this basing on file_type, but if we decide to leave this as is, can we at least make sure ValueError is raised if anything else except \"regular\" or \"directory\" has been passed?","commit_id":"b3b1d71dea4c8c63bf5b9ab04d28e65d2208e64e"},{"author":{"_account_id":14358,"name":"Marian Horban","email":"m.horban@gmail.com","username":"mhorban"},"change_message_id":"ba9477ffe77c56c87af6c1987410c23836298443","unresolved":false,"context_lines":[{"line_number":292,"context_line":"    :param file_type: Type of file, can be \u0027regular\u0027 or \u0027directory\u0027"},{"line_number":293,"context_line":"    \"\"\""},{"line_number":294,"context_line":""},{"line_number":295,"context_line":"    if file_type \u003d\u003d \u0027directory\u0027:"},{"line_number":296,"context_line":"        # Remove remote directory\u0027s content"},{"line_number":297,"context_line":"        utils.execute(\u0027rsync\u0027, \u0027--archive\u0027, \u0027--delete-excluded\u0027,"},{"line_number":298,"context_line":"                  kwargs[\u0027tmp_dir_path\u0027] + os.path.sep,"}],"source_content_type":"text/x-python","patch_set":5,"id":"1a930d6b_c509abde","line":295,"in_reply_to":"1a930d6b_b17deb70","updated":"2015-01-23 16:28:21.000000000","message":"Done","commit_id":"b3b1d71dea4c8c63bf5b9ab04d28e65d2208e64e"},{"author":{"_account_id":14358,"name":"Marian Horban","email":"m.horban@gmail.com","username":"mhorban"},"change_message_id":"2589df9b44a5be09f93f5f94643b1edaf3746bb3","unresolved":false,"context_lines":[{"line_number":292,"context_line":"    :param file_type: Type of file, can be \u0027regular\u0027 or \u0027directory\u0027"},{"line_number":293,"context_line":"    \"\"\""},{"line_number":294,"context_line":""},{"line_number":295,"context_line":"    if file_type \u003d\u003d \u0027directory\u0027:"},{"line_number":296,"context_line":"        # Remove remote directory\u0027s content"},{"line_number":297,"context_line":"        utils.execute(\u0027rsync\u0027, \u0027--archive\u0027, \u0027--delete-excluded\u0027,"},{"line_number":298,"context_line":"                  kwargs[\u0027tmp_dir_path\u0027] + os.path.sep,"}],"source_content_type":"text/x-python","patch_set":5,"id":"3a961159_c2d82b83","line":295,"in_reply_to":"3a961159_76a73dbd","updated":"2015-01-19 16:16:14.000000000","message":"Actually I don\u0027t like it too :)\nReason that pushed me to do it in such way is to avoid copying code, set of arguments for utils.execute function etc. Especially it concerns for the second function \u0027create_remote_file\u0027.\nAre you OK if I make \u0027remove_remote_file\u0027 and  \u0027create_remote_file\u0027 functions private and declare 4 external functions for creating and removing file and directory? These new functions will call current functions with additional argument.\nPlease let me know your point of view.","commit_id":"b3b1d71dea4c8c63bf5b9ab04d28e65d2208e64e"},{"author":{"_account_id":6849,"name":"Roman Podoliaka","email":"roman.podoliaka@gmail.com","username":"rpodolyaka"},"change_message_id":"284e5b34c44ef92a0f17e1ded3190e18997280a8","unresolved":false,"context_lines":[{"line_number":292,"context_line":"    :param file_type: Type of file, can be \u0027regular\u0027 or \u0027directory\u0027"},{"line_number":293,"context_line":"    \"\"\""},{"line_number":294,"context_line":""},{"line_number":295,"context_line":"    if file_type \u003d\u003d \u0027directory\u0027:"},{"line_number":296,"context_line":"        # Remove remote directory\u0027s content"},{"line_number":297,"context_line":"        utils.execute(\u0027rsync\u0027, \u0027--archive\u0027, \u0027--delete-excluded\u0027,"},{"line_number":298,"context_line":"                  kwargs[\u0027tmp_dir_path\u0027] + os.path.sep,"}],"source_content_type":"text/x-python","patch_set":5,"id":"1a930d6b_b17deb70","line":295,"in_reply_to":"3a961159_c2d82b83","updated":"2015-01-22 17:13:38.000000000","message":"I think something similar to patch set 3 is ok. we can iterate on reusing of the code later","commit_id":"b3b1d71dea4c8c63bf5b9ab04d28e65d2208e64e"},{"author":{"_account_id":6849,"name":"Roman Podoliaka","email":"roman.podoliaka@gmail.com","username":"rpodolyaka"},"change_message_id":"5614e359fec1721906e0a792427cfc28c91091dd","unresolved":false,"context_lines":[{"line_number":300,"context_line":""},{"line_number":301,"context_line":"    # Delete file or empty directory"},{"line_number":302,"context_line":"    utils.execute(\u0027rsync\u0027, \u0027--archive\u0027, \u0027--delete\u0027,"},{"line_number":303,"context_line":"                  \u0027--include\u003d\u0027 + os.path.basename(os.path.normpath(dst)),"},{"line_number":304,"context_line":"                  \u0027--exclude\u003d\u0027 + \u0027*\u0027,"},{"line_number":305,"context_line":"                  kwargs[\u0027tmp_dir_path\u0027] + os.path.sep,"},{"line_number":306,"context_line":"                  \u0027%s:%s\u0027 % (host, os.path.dirname(os.path.normpath(dst))))"}],"source_content_type":"text/x-python","patch_set":5,"id":"3a961159_b677e53b","line":303,"updated":"2015-01-19 14:42:30.000000000","message":"nit: string concatenation shouldn\u0027t be needed here - we can just pass the values as separate arguments:\n\n  ...\n  \u0027--include\u0027, os.path.basename(os.path.normpath(dst)),\n  ...","commit_id":"b3b1d71dea4c8c63bf5b9ab04d28e65d2208e64e"},{"author":{"_account_id":14358,"name":"Marian Horban","email":"m.horban@gmail.com","username":"mhorban"},"change_message_id":"ba9477ffe77c56c87af6c1987410c23836298443","unresolved":false,"context_lines":[{"line_number":300,"context_line":""},{"line_number":301,"context_line":"    # Delete file or empty directory"},{"line_number":302,"context_line":"    utils.execute(\u0027rsync\u0027, \u0027--archive\u0027, \u0027--delete\u0027,"},{"line_number":303,"context_line":"                  \u0027--include\u003d\u0027 + os.path.basename(os.path.normpath(dst)),"},{"line_number":304,"context_line":"                  \u0027--exclude\u003d\u0027 + \u0027*\u0027,"},{"line_number":305,"context_line":"                  kwargs[\u0027tmp_dir_path\u0027] + os.path.sep,"},{"line_number":306,"context_line":"                  \u0027%s:%s\u0027 % (host, os.path.dirname(os.path.normpath(dst))))"}],"source_content_type":"text/x-python","patch_set":5,"id":"1a930d6b_a2a65a51","line":303,"in_reply_to":"3a961159_b677e53b","updated":"2015-01-23 16:28:21.000000000","message":"Done","commit_id":"b3b1d71dea4c8c63bf5b9ab04d28e65d2208e64e"},{"author":{"_account_id":6849,"name":"Roman Podoliaka","email":"roman.podoliaka@gmail.com","username":"rpodolyaka"},"change_message_id":"5614e359fec1721906e0a792427cfc28c91091dd","unresolved":false,"context_lines":[{"line_number":334,"context_line":""},{"line_number":335,"context_line":"    # For creating path on the remote host rsync --relative path must"},{"line_number":336,"context_line":"    # be used. With a modern rsync on the sending side (beginning with"},{"line_number":337,"context_line":"    # 2.6.7), you can insert a dot and a slash into the source path,"},{"line_number":338,"context_line":"    # like this:"},{"line_number":339,"context_line":"    #   rsync -avR /foo/./bar/baz.c remote:/tmp/"},{"line_number":340,"context_line":"    # That would create /tmp/bar/baz.c on the remote machine."}],"source_content_type":"text/x-python","patch_set":5,"id":"3a961159_56b7a1d7","line":337,"updated":"2015-01-19 14:42:30.000000000","message":"could you please check what are the minimum versions of centos/rhel/ubuntu/fedora needed for this to work properly?","commit_id":"b3b1d71dea4c8c63bf5b9ab04d28e65d2208e64e"},{"author":{"_account_id":14358,"name":"Marian Horban","email":"m.horban@gmail.com","username":"mhorban"},"change_message_id":"ba9477ffe77c56c87af6c1987410c23836298443","unresolved":false,"context_lines":[{"line_number":334,"context_line":""},{"line_number":335,"context_line":"    # For creating path on the remote host rsync --relative path must"},{"line_number":336,"context_line":"    # be used. With a modern rsync on the sending side (beginning with"},{"line_number":337,"context_line":"    # 2.6.7), you can insert a dot and a slash into the source path,"},{"line_number":338,"context_line":"    # like this:"},{"line_number":339,"context_line":"    #   rsync -avR /foo/./bar/baz.c remote:/tmp/"},{"line_number":340,"context_line":"    # That would create /tmp/bar/baz.c on the remote machine."}],"source_content_type":"text/x-python","patch_set":5,"id":"1a930d6b_82ab1e1c","line":337,"in_reply_to":"3a961159_56b7a1d7","updated":"2015-01-23 16:28:21.000000000","message":"rsync with version 2.6.7 is present in Ubuntu 8.04.4 LTS,  CentOS-5, Red Hat Enterprise Linux 5, Fedora 7 and above versions of these distributives.","commit_id":"b3b1d71dea4c8c63bf5b9ab04d28e65d2208e64e"},{"author":{"_account_id":6849,"name":"Roman Podoliaka","email":"roman.podoliaka@gmail.com","username":"rpodolyaka"},"change_message_id":"e592833dcdad8aff5436d86b3a42d5b252eb91b0","unresolved":false,"context_lines":[{"line_number":363,"context_line":""},{"line_number":364,"context_line":"    # Create target dir inside temporary directory"},{"line_number":365,"context_line":"    local_tmp_dir \u003d os.path.join(kwargs[\u0027tmp_dir_path\u0027],"},{"line_number":366,"context_line":"                                 dir_path.strip(os.path.sep))"},{"line_number":367,"context_line":"    utils.execute(\u0027mkdir\u0027, \u0027-p\u0027, local_tmp_dir)"},{"line_number":368,"context_line":""},{"line_number":369,"context_line":"    # Create file in directory"}],"source_content_type":"text/x-python","patch_set":6,"id":"1a930d6b_40c29b53","line":366,"updated":"2015-01-27 17:08:50.000000000","message":"nit: is this strip() really needed? os.path.join() must take care of that","commit_id":"b0d8bf2f3ffdced8510b287a08b693fadb46de0e"},{"author":{"_account_id":14358,"name":"Marian Horban","email":"m.horban@gmail.com","username":"mhorban"},"change_message_id":"3f34c5080644c6a5ccb57eef3f4726a4d5f57c9c","unresolved":false,"context_lines":[{"line_number":363,"context_line":""},{"line_number":364,"context_line":"    # Create target dir inside temporary directory"},{"line_number":365,"context_line":"    local_tmp_dir \u003d os.path.join(kwargs[\u0027tmp_dir_path\u0027],"},{"line_number":366,"context_line":"                                 dir_path.strip(os.path.sep))"},{"line_number":367,"context_line":"    utils.execute(\u0027mkdir\u0027, \u0027-p\u0027, local_tmp_dir)"},{"line_number":368,"context_line":""},{"line_number":369,"context_line":"    # Create file in directory"}],"source_content_type":"text/x-python","patch_set":6,"id":"fa81d914_5dd06d50","line":366,"in_reply_to":"1a930d6b_40c29b53","updated":"2015-01-28 17:10:19.000000000","message":"We need \u0027strip\u0027 here because if second argument of join() starts with \u0027/\u0027 first argument would be skipped:\n\u003e\u003e\u003e os.path.join(\"/a/b/c\", \"d/e\")\n\u0027/a/b/c/d/e\u0027\n\u003e\u003e\u003e os.path.join(\"/a/b/c\", \"/d/e\")\n\u0027/d/e\u0027","commit_id":"b0d8bf2f3ffdced8510b287a08b693fadb46de0e"},{"author":{"_account_id":6849,"name":"Roman Podoliaka","email":"roman.podoliaka@gmail.com","username":"rpodolyaka"},"change_message_id":"bdb67eb71e6f26db4d567c3264f32203488ed101","unresolved":false,"context_lines":[{"line_number":363,"context_line":""},{"line_number":364,"context_line":"    # Create target dir inside temporary directory"},{"line_number":365,"context_line":"    local_tmp_dir \u003d os.path.join(kwargs[\u0027tmp_dir_path\u0027],"},{"line_number":366,"context_line":"                                 dir_path.strip(os.path.sep))"},{"line_number":367,"context_line":"    utils.execute(\u0027mkdir\u0027, \u0027-p\u0027, local_tmp_dir)"},{"line_number":368,"context_line":""},{"line_number":369,"context_line":"    # Create file in directory"}],"source_content_type":"text/x-python","patch_set":6,"id":"fa81d914_2bf796f6","line":366,"in_reply_to":"fa81d914_5dd06d50","updated":"2015-01-30 09:21:29.000000000","message":"ack, thanks for clarifying!","commit_id":"b0d8bf2f3ffdced8510b287a08b693fadb46de0e"},{"author":{"_account_id":6849,"name":"Roman Podoliaka","email":"roman.podoliaka@gmail.com","username":"rpodolyaka"},"change_message_id":"e592833dcdad8aff5436d86b3a42d5b252eb91b0","unresolved":false,"context_lines":[{"line_number":386,"context_line":""},{"line_number":387,"context_line":"    # Create target dir inside temporary directory"},{"line_number":388,"context_line":"    local_tmp_dir \u003d os.path.join(kwargs[\u0027tmp_dir_path\u0027],"},{"line_number":389,"context_line":"                             dir_path.strip(os.path.sep))"},{"line_number":390,"context_line":"    utils.execute(\u0027mkdir\u0027, \u0027-p\u0027, local_tmp_dir)"},{"line_number":391,"context_line":"    _synchronize_remote_object(kwargs[\u0027tmp_dir_path\u0027], host, dst_path)"},{"line_number":392,"context_line":""}],"source_content_type":"text/x-python","patch_set":6,"id":"1a930d6b_4099bb77","line":389,"updated":"2015-01-27 17:08:50.000000000","message":"ditto","commit_id":"b0d8bf2f3ffdced8510b287a08b693fadb46de0e"},{"author":{"_account_id":14358,"name":"Marian Horban","email":"m.horban@gmail.com","username":"mhorban"},"change_message_id":"3f34c5080644c6a5ccb57eef3f4726a4d5f57c9c","unresolved":false,"context_lines":[{"line_number":386,"context_line":""},{"line_number":387,"context_line":"    # Create target dir inside temporary directory"},{"line_number":388,"context_line":"    local_tmp_dir \u003d os.path.join(kwargs[\u0027tmp_dir_path\u0027],"},{"line_number":389,"context_line":"                             dir_path.strip(os.path.sep))"},{"line_number":390,"context_line":"    utils.execute(\u0027mkdir\u0027, \u0027-p\u0027, local_tmp_dir)"},{"line_number":391,"context_line":"    _synchronize_remote_object(kwargs[\u0027tmp_dir_path\u0027], host, dst_path)"},{"line_number":392,"context_line":""}],"source_content_type":"text/x-python","patch_set":6,"id":"fa81d914_3d101901","line":389,"in_reply_to":"1a930d6b_4099bb77","updated":"2015-01-28 17:10:19.000000000","message":"same","commit_id":"b0d8bf2f3ffdced8510b287a08b693fadb46de0e"},{"author":{"_account_id":1779,"name":"Daniel Berrange","email":"berrange@redhat.com","username":"berrange"},"change_message_id":"839aaf35c03e19ab532e34a6d477c86691ab9aa0","unresolved":false,"context_lines":[{"line_number":413,"context_line":"                             dir_path.strip(os.path.sep))"},{"line_number":414,"context_line":"    utils.execute(\u0027mkdir\u0027, \u0027-p\u0027, local_tmp_dir)"},{"line_number":415,"context_line":"    _synchronize_remote_object(kwargs[\u0027tmp_dir_path\u0027], host, dst_path)"},{"line_number":416,"context_line":""},{"line_number":417,"context_line":""},{"line_number":418,"context_line":"def copy_image(src, dest, host\u003dNone):"},{"line_number":419,"context_line":"    \"\"\"Copy a disk image to an existing directory"}],"source_content_type":"text/x-python","patch_set":7,"id":"da86d52c_d262b5d8","line":416,"updated":"2015-02-13 11:52:49.000000000","message":"Lets put all these helper methods in a separate \"remotefs.py\" module - this util.py is too much of an arbitrary dumping ground alrady.\n\nI\u0027m not comfortable with just removing SSH support from this, as it will negatively impact people doing continuous deployment who may not have rsync available without extra config work on their part.\n\nI\u0027d suggest, we have a config option that allows us to switch between ssh and rsync impls, with ssh the default so we have a clean upgrade path","commit_id":"b5a75e4aa5548876500d79c68e9b337518b0ba01"},{"author":{"_account_id":14358,"name":"Marian Horban","email":"m.horban@gmail.com","username":"mhorban"},"change_message_id":"dc4c6dba0c4fc9d372cb1ec80835b3738d4afb90","unresolved":false,"context_lines":[{"line_number":413,"context_line":"                             dir_path.strip(os.path.sep))"},{"line_number":414,"context_line":"    utils.execute(\u0027mkdir\u0027, \u0027-p\u0027, local_tmp_dir)"},{"line_number":415,"context_line":"    _synchronize_remote_object(kwargs[\u0027tmp_dir_path\u0027], host, dst_path)"},{"line_number":416,"context_line":""},{"line_number":417,"context_line":""},{"line_number":418,"context_line":"def copy_image(src, dest, host\u003dNone):"},{"line_number":419,"context_line":"    \"\"\"Copy a disk image to an existing directory"}],"source_content_type":"text/x-python","patch_set":7,"id":"da86d52c_86a136ab","line":416,"in_reply_to":"da86d52c_d262b5d8","updated":"2015-02-18 17:52:16.000000000","message":"Done","commit_id":"b5a75e4aa5548876500d79c68e9b337518b0ba01"},{"author":{"_account_id":1779,"name":"Daniel Berrange","email":"berrange@redhat.com","username":"berrange"},"change_message_id":"b28e3bb953bc6737b6df12451e895607194694fd","unresolved":false,"context_lines":[{"line_number":48,"context_line":"               default\u003d\u0027Ssh\u0027,"},{"line_number":49,"context_line":"               choices\u003d(\u0027Ssh\u0027, \u0027Rsync\u0027),"},{"line_number":50,"context_line":"               help\u003d\u0027Use ssh or rsync transport for creating, copying,\u0027"},{"line_number":51,"context_line":"                    \u0027removing files on the remote host.\u0027)"},{"line_number":52,"context_line":""},{"line_number":53,"context_line":"    ]"},{"line_number":54,"context_line":""}],"source_content_type":"text/x-python","patch_set":14,"id":"ba3cc151_1f0a518a","line":51,"updated":"2015-07-03 11:40:36.000000000","message":"I\u0027d suggest putting this config option in the remotefs.py file","commit_id":"1120ae533fc4b2b3c31936e38de7a32652d5b498"},{"author":{"_account_id":14358,"name":"Marian Horban","email":"m.horban@gmail.com","username":"mhorban"},"change_message_id":"168f1001ec3fbb38097ed7a08b5222588d504121","unresolved":false,"context_lines":[{"line_number":48,"context_line":"               default\u003d\u0027Ssh\u0027,"},{"line_number":49,"context_line":"               choices\u003d(\u0027Ssh\u0027, \u0027Rsync\u0027),"},{"line_number":50,"context_line":"               help\u003d\u0027Use ssh or rsync transport for creating, copying,\u0027"},{"line_number":51,"context_line":"                    \u0027removing files on the remote host.\u0027)"},{"line_number":52,"context_line":""},{"line_number":53,"context_line":"    ]"},{"line_number":54,"context_line":""}],"source_content_type":"text/x-python","patch_set":14,"id":"ba3cc151_9b409c37","line":51,"in_reply_to":"ba3cc151_1f0a518a","updated":"2015-07-04 15:54:37.000000000","message":"Done","commit_id":"1120ae533fc4b2b3c31936e38de7a32652d5b498"},{"author":{"_account_id":1779,"name":"Daniel Berrange","email":"berrange@redhat.com","username":"berrange"},"change_message_id":"b28e3bb953bc6737b6df12451e895607194694fd","unresolved":false,"context_lines":[{"line_number":321,"context_line":"        remote_filesystem_driver \u003d getattr("},{"line_number":322,"context_line":"            remotefs, CONF.libvirt.remote_filesystem_transport +"},{"line_number":323,"context_line":"            \u0027RemoteFilesystem\u0027)()"},{"line_number":324,"context_line":"        remote_filesystem_driver.copy_file(src, dest)"},{"line_number":325,"context_line":""},{"line_number":326,"context_line":""},{"line_number":327,"context_line":"def write_to_file(path, contents, umask\u003dNone):"}],"source_content_type":"text/x-python","patch_set":14,"id":"ba3cc151_7f427daf","line":324,"updated":"2015-07-03 11:40:36.000000000","message":"And add a get_instance() method to remotefs.py which returns a (cached) instance of the driver. So all callers here and in driver.py can just do\n\n  remotefs.get_instance().copy_file(src, dst)","commit_id":"1120ae533fc4b2b3c31936e38de7a32652d5b498"},{"author":{"_account_id":14358,"name":"Marian Horban","email":"m.horban@gmail.com","username":"mhorban"},"change_message_id":"168f1001ec3fbb38097ed7a08b5222588d504121","unresolved":false,"context_lines":[{"line_number":321,"context_line":"        remote_filesystem_driver \u003d getattr("},{"line_number":322,"context_line":"            remotefs, CONF.libvirt.remote_filesystem_transport +"},{"line_number":323,"context_line":"            \u0027RemoteFilesystem\u0027)()"},{"line_number":324,"context_line":"        remote_filesystem_driver.copy_file(src, dest)"},{"line_number":325,"context_line":""},{"line_number":326,"context_line":""},{"line_number":327,"context_line":"def write_to_file(path, contents, umask\u003dNone):"}],"source_content_type":"text/x-python","patch_set":14,"id":"ba3cc151_fb5a082a","line":324,"in_reply_to":"ba3cc151_1d057612","updated":"2015-07-04 15:54:37.000000000","message":"I\u0027ve added meta class for RemoteFilesystem class. This metaclass provides singleton functionality.","commit_id":"1120ae533fc4b2b3c31936e38de7a32652d5b498"},{"author":{"_account_id":14358,"name":"Marian Horban","email":"m.horban@gmail.com","username":"mhorban"},"change_message_id":"3a324be28dbb1b385c6348fcb5e21e8dd1127dbe","unresolved":false,"context_lines":[{"line_number":321,"context_line":"        remote_filesystem_driver \u003d getattr("},{"line_number":322,"context_line":"            remotefs, CONF.libvirt.remote_filesystem_transport +"},{"line_number":323,"context_line":"            \u0027RemoteFilesystem\u0027)()"},{"line_number":324,"context_line":"        remote_filesystem_driver.copy_file(src, dest)"},{"line_number":325,"context_line":""},{"line_number":326,"context_line":""},{"line_number":327,"context_line":"def write_to_file(path, contents, umask\u003dNone):"}],"source_content_type":"text/x-python","patch_set":14,"id":"ba3cc151_1d057612","line":324,"in_reply_to":"ba3cc151_7f427daf","updated":"2015-07-03 13:19:03.000000000","message":"Are you OK with singleton pattern?","commit_id":"1120ae533fc4b2b3c31936e38de7a32652d5b498"},{"author":{"_account_id":6849,"name":"Roman Podoliaka","email":"roman.podoliaka@gmail.com","username":"rpodolyaka"},"change_message_id":"43b3b6429fd952b08434a7dfe113a7e0437a5ff1","unresolved":false,"context_lines":[{"line_number":315,"context_line":"        else:"},{"line_number":316,"context_line":"            dest \u003d \"%s:%s\" % (utils.safe_ip_format(host), dest)"},{"line_number":317,"context_line":""},{"line_number":318,"context_line":"        remote_filesystem_driver \u003d getattr("},{"line_number":319,"context_line":"            remotefs, CONF.libvirt.remote_filesystem_transport +"},{"line_number":320,"context_line":"            \u0027RemoteFilesystem\u0027)()"},{"line_number":321,"context_line":"        remote_filesystem_driver.copy_file(src, dest)"}],"source_content_type":"text/x-python","patch_set":17,"id":"9a41bdd9_225bf588","line":318,"updated":"2015-07-14 12:44:37.000000000","message":"nit: import_object() ditto","commit_id":"e3bffd1b5723c6e63f437d651ddad23833099c8a"},{"author":{"_account_id":10618,"name":"Pavel Kholkin","email":"p.v.holkin@mail.ru","username":"pkholkin"},"change_message_id":"05a8d8fc843275c051df3d7dba3900f21a51bad3","unresolved":false,"context_lines":[{"line_number":315,"context_line":"        else:"},{"line_number":316,"context_line":"            dest \u003d \"%s:%s\" % (utils.safe_ip_format(host), dest)"},{"line_number":317,"context_line":""},{"line_number":318,"context_line":"        remote_filesystem_driver \u003d getattr("},{"line_number":319,"context_line":"            remotefs, CONF.libvirt.remote_filesystem_transport +"},{"line_number":320,"context_line":"            \u0027RemoteFilesystem\u0027)()"},{"line_number":321,"context_line":"        remote_filesystem_driver.copy_file(src, dest)"}],"source_content_type":"text/x-python","patch_set":17,"id":"9a41bdd9_2f8679db","line":318,"in_reply_to":"9a41bdd9_225bf588","updated":"2015-07-14 13:56:10.000000000","message":"Done","commit_id":"e3bffd1b5723c6e63f437d651ddad23833099c8a"},{"author":{"_account_id":1653,"name":"garyk","email":"gkotton@vmware.com","username":"garyk"},"change_message_id":"f6219e71489946e7d76edac31650298567153b69","unresolved":false,"context_lines":[{"line_number":49,"context_line":"CONF \u003d cfg.CONF"},{"line_number":50,"context_line":"CONF.register_opts(libvirt_opts, \u0027libvirt\u0027)"},{"line_number":51,"context_line":"CONF.import_opt(\u0027instances_path\u0027, \u0027nova.compute.manager\u0027)"},{"line_number":52,"context_line":""},{"line_number":53,"context_line":"LOG \u003d logging.getLogger(__name__)"},{"line_number":54,"context_line":""},{"line_number":55,"context_line":""}],"source_content_type":"text/x-python","patch_set":21,"id":"9a41bdd9_c6254109","line":52,"updated":"2015-07-15 11:26:19.000000000","message":"unrelated to this patch (sorry for being pathetic)","commit_id":"61edfb6254734ee53bfa8054164c3cb8fe0e4750"},{"author":{"_account_id":14358,"name":"Marian Horban","email":"m.horban@gmail.com","username":"mhorban"},"change_message_id":"443955d7ce00b38ca600002e54019f76a44ddb67","unresolved":false,"context_lines":[{"line_number":49,"context_line":"CONF \u003d cfg.CONF"},{"line_number":50,"context_line":"CONF.register_opts(libvirt_opts, \u0027libvirt\u0027)"},{"line_number":51,"context_line":"CONF.import_opt(\u0027instances_path\u0027, \u0027nova.compute.manager\u0027)"},{"line_number":52,"context_line":""},{"line_number":53,"context_line":"LOG \u003d logging.getLogger(__name__)"},{"line_number":54,"context_line":""},{"line_number":55,"context_line":""}],"source_content_type":"text/x-python","patch_set":21,"id":"3a50d1a3_0b567406","line":52,"in_reply_to":"9a41bdd9_c6254109","updated":"2015-07-24 09:06:57.000000000","message":"Done","commit_id":"61edfb6254734ee53bfa8054164c3cb8fe0e4750"},{"author":{"_account_id":7,"name":"Jay Pipes","email":"jaypipes@gmail.com","username":"jaypipes"},"change_message_id":"6efdf9e16febd8d836dc85bfdedd31d16657cd30","unresolved":false,"context_lines":[{"line_number":320,"context_line":"            # on the destination for example."},{"line_number":321,"context_line":"            execute(\u0027rsync\u0027, \u0027--sparse\u0027, \u0027--compress\u0027, \u0027--dry-run\u0027, src, dest)"},{"line_number":322,"context_line":"        except processutils.ProcessExecutionError:"},{"line_number":323,"context_line":"            execute(\u0027scp\u0027, src, dest)"},{"line_number":324,"context_line":"        else:"},{"line_number":325,"context_line":"            execute(\u0027rsync\u0027, \u0027--sparse\u0027, \u0027--compress\u0027, src, dest)"},{"line_number":326,"context_line":""}],"source_content_type":"text/x-python","patch_set":25,"id":"3a50d1a3_8c2fe83d","side":"PARENT","line":323,"updated":"2015-07-30 19:06:53.000000000","message":"So technically this is changing the existing behaviour of the code. Instead of falling back to using SSH/scp if rsync won\u0027t work, we now will raise a ProcessExecutionError from the rsync remotefs driver\u0027s copy_file() method, which doesn\u0027t do any fallback from what I can tell...\n\nIs this something that you intended?","commit_id":"8a73c0430db27501437fc2b6c1a354a121be7c45"},{"author":{"_account_id":14358,"name":"Marian Horban","email":"m.horban@gmail.com","username":"mhorban"},"change_message_id":"36f3b8ade560fca46b19f80c5ce6fc7f340db122","unresolved":false,"context_lines":[{"line_number":320,"context_line":"            # on the destination for example."},{"line_number":321,"context_line":"            execute(\u0027rsync\u0027, \u0027--sparse\u0027, \u0027--compress\u0027, \u0027--dry-run\u0027, src, dest)"},{"line_number":322,"context_line":"        except processutils.ProcessExecutionError:"},{"line_number":323,"context_line":"            execute(\u0027scp\u0027, src, dest)"},{"line_number":324,"context_line":"        else:"},{"line_number":325,"context_line":"            execute(\u0027rsync\u0027, \u0027--sparse\u0027, \u0027--compress\u0027, src, dest)"},{"line_number":326,"context_line":""}],"source_content_type":"text/x-python","patch_set":25,"id":"1a4dcd0f_3695dce3","side":"PARENT","line":323,"in_reply_to":"3a50d1a3_8c2fe83d","updated":"2015-08-03 20:04:06.000000000","message":"Actually yes.\nThe idea of this review is to allow user to use ONLY rsync or ssh because they use different ports and we want to decrease number of opened ports.\nBut if we need we can implement something like \u0027reliable remote FS\u0027 transport. This transport could behave like this function before I changed it.","commit_id":"8a73c0430db27501437fc2b6c1a354a121be7c45"}],"nova/virt/libvirt/volume/remotefs.py":[{"author":{"_account_id":782,"name":"John Garbutt","email":"john@johngarbutt.com","username":"johngarbutt"},"change_message_id":"c526f485a783d02362e0f523ecbb9027dd40f910","unresolved":false,"context_lines":[{"line_number":332,"context_line":"                      on_execute\u003don_execute, on_completion\u003don_completion)"},{"line_number":333,"context_line":""},{"line_number":334,"context_line":"    def copy_file(self, src, dst, on_execute, on_completion):"},{"line_number":335,"context_line":"        utils.execute(\u0027rsync\u0027, \u0027--sparse\u0027, \u0027--compress\u0027, src, dst,"},{"line_number":336,"context_line":"                      on_execute\u003don_execute, on_completion\u003don_completion)"}],"source_content_type":"text/x-python","patch_set":26,"id":"1a4dcd0f_b75f8a71","line":335,"updated":"2015-08-04 10:43:25.000000000","message":"I agree with Jay, I think we need to keep the scp fallback.\n\nNow what we could do is deprecate that fallback, saying it will be removed in the next release, and add a warning message when its used.\n\nBut we can\u0027t just remove that straight away I am afraid.","commit_id":"7896548afe74ea1fad42a00c056442d838ad8e3d"},{"author":{"_account_id":14358,"name":"Marian Horban","email":"m.horban@gmail.com","username":"mhorban"},"change_message_id":"095f33e95025b0a8a7ece44c76ae4e804483d204","unresolved":false,"context_lines":[{"line_number":332,"context_line":"                      on_execute\u003don_execute, on_completion\u003don_completion)"},{"line_number":333,"context_line":""},{"line_number":334,"context_line":"    def copy_file(self, src, dst, on_execute, on_completion):"},{"line_number":335,"context_line":"        utils.execute(\u0027rsync\u0027, \u0027--sparse\u0027, \u0027--compress\u0027, src, dst,"},{"line_number":336,"context_line":"                      on_execute\u003don_execute, on_completion\u003don_completion)"}],"source_content_type":"text/x-python","patch_set":26,"id":"1a4dcd0f_95e2062e","line":335,"in_reply_to":"1a4dcd0f_58ecf38e","updated":"2015-08-06 11:28:04.000000000","message":"Agree","commit_id":"7896548afe74ea1fad42a00c056442d838ad8e3d"},{"author":{"_account_id":1779,"name":"Daniel Berrange","email":"berrange@redhat.com","username":"berrange"},"change_message_id":"e0de59db66788082fd9b60c42e71ee0db91e5a70","unresolved":false,"context_lines":[{"line_number":332,"context_line":"                      on_execute\u003don_execute, on_completion\u003don_completion)"},{"line_number":333,"context_line":""},{"line_number":334,"context_line":"    def copy_file(self, src, dst, on_execute, on_completion):"},{"line_number":335,"context_line":"        utils.execute(\u0027rsync\u0027, \u0027--sparse\u0027, \u0027--compress\u0027, src, dst,"},{"line_number":336,"context_line":"                      on_execute\u003don_execute, on_completion\u003don_completion)"}],"source_content_type":"text/x-python","patch_set":26,"id":"1a4dcd0f_58ecf38e","line":335,"in_reply_to":"1a4dcd0f_b75f8a71","updated":"2015-08-05 10:24:59.000000000","message":"I don\u0027t think that\u0027s neccessary.  In the existing code, admins will have had to configure their compute hosts to allow  ssh only, or ssh + rsync. So as long as we default to use of the ssh transport, we don\u0027t have a functional regression - merely a small performance degradation, which can be solved by simply switching the nova.conf to use rsync transport. I think that\u0027s an acceptable tradeoff that can be dealt with easily enough in the release notes.","commit_id":"7896548afe74ea1fad42a00c056442d838ad8e3d"}]}
