From fecd81655ee6db7e50dd096fc147657d804e1d5f Mon Sep 17 00:00:00 2001 From: Julien Duponchelle Date: Thu, 2 Jun 2016 16:44:38 +0200 Subject: [PATCH] Support recursive image search Fix #546 --- gns3server/compute/base_manager.py | 24 +++++++++++++--- tests/compute/test_manager.py | 44 +++++++++++++++++++++++++++--- 2 files changed, 60 insertions(+), 8 deletions(-) diff --git a/gns3server/compute/base_manager.py b/gns3server/compute/base_manager.py index 50dcc76e..be69b1d6 100644 --- a/gns3server/compute/base_manager.py +++ b/gns3server/compute/base_manager.py @@ -428,13 +428,12 @@ class BaseManager: if not os.path.isabs(path): orig_path = path - s = os.path.split(path) - for directory in self.images_directories(): - path = os.path.normpath(os.path.join(directory, *s)) - if os.path.exists(path): + path = self._recursive_search_file_in_directory(directory, orig_path) + if path: return force_unix_path(path) # Not found we return the default directory + s = os.path.split(orig_path) return force_unix_path(os.path.join(self.get_images_directory(), *s)) # For non local server we disallow using absolute path outside image directory @@ -447,6 +446,23 @@ class BaseManager: return path raise NodeError("{} is not allowed on this remote server. Please use only a filename in {}.".format(path, self.get_images_directory())) + def _recursive_search_file_in_directory(self, directory, searched_file): + """ + Search for a file in directory and is subdirectories + + :returns: Path or None if not found + """ + s = os.path.split(searched_file) + + for root, dirs, files in os.walk(directory): + for file in files: + # If filename is the same + if s[1] == file and (s[0] == '' or s[0] == os.path.basename(root)): + path = os.path.normpath(os.path.join(root, s[1])) + if os.path.exists(path): + return path + return None + def get_relative_image_path(self, path): """ Get a path relative to images directory path diff --git a/tests/compute/test_manager.py b/tests/compute/test_manager.py index f868aeed..85b6fe03 100644 --- a/tests/compute/test_manager.py +++ b/tests/compute/test_manager.py @@ -169,6 +169,42 @@ def test_get_abs_image_additional_image_paths(qemu, tmpdir): assert qemu.get_abs_image_path("test4.bin") == os.path.join(qemu.get_images_directory(), "test4.bin") +def test_get_abs_image_recursive(qemu, tmpdir): + path1 = tmpdir / "images1" / "QEMU" / "demo" / "test1.bin" + path1.write("1", ensure=True) + path1 = force_unix_path(str(path1)) + + path2 = tmpdir / "images1" / "QEMU" / "test2.bin" + path2.write("1", ensure=True) + path2 = force_unix_path(str(path2)) + + with patch("gns3server.config.Config.get_section_config", return_value={ + "images_path": str(tmpdir / "images1"), + "local": False}): + assert qemu.get_abs_image_path("test1.bin") == path1 + assert qemu.get_abs_image_path("test2.bin") == path2 + # Absolute path + assert qemu.get_abs_image_path(str(path1)) == path1 + + +def test_get_abs_image_recursive_ova(qemu, tmpdir): + path1 = tmpdir / "images1" / "QEMU" / "demo" / "test.ova" / "test1.bin" + path1.write("1", ensure=True) + path1 = force_unix_path(str(path1)) + + path2 = tmpdir / "images1" / "QEMU" / "test.ova" / "test2.bin" + path2.write("1", ensure=True) + path2 = force_unix_path(str(path2)) + + with patch("gns3server.config.Config.get_section_config", return_value={ + "images_path": str(tmpdir / "images1"), + "local": False}): + assert qemu.get_abs_image_path("test.ova/test1.bin") == path1 + assert qemu.get_abs_image_path("test.ova/test2.bin") == path2 + # Absolute path + assert qemu.get_abs_image_path(str(path1)) == path1 + + def test_get_relative_image_path(qemu, tmpdir): os.makedirs(str(tmpdir / "images1" / "QEMU")) path1 = force_unix_path(str(tmpdir / "images1" / "test1.bin")) @@ -194,13 +230,13 @@ def test_get_relative_image_path(qemu, tmpdir): def test_get_relative_image_path_ova(qemu, tmpdir): - os.makedirs(str(tmpdir / "QEMU" / "test.ovf")) - path = str(tmpdir / "QEMU" / "test.ovf" / "test.bin") + os.makedirs(str(tmpdir / "QEMU" / "test.ova")) + path = str(tmpdir / "QEMU" / "test.ova" / "test.bin") open(path, 'w+').close() with patch("gns3server.config.Config.get_section_config", return_value={"images_path": str(tmpdir)}): - assert qemu.get_relative_image_path(path) == os.path.join("test.ovf", "test.bin") - assert qemu.get_relative_image_path(os.path.join("test.ovf", "test.bin")) == os.path.join("test.ovf", "test.bin") + assert qemu.get_relative_image_path(path) == os.path.join("test.ova", "test.bin") + assert qemu.get_relative_image_path(os.path.join("test.ova", "test.bin")) == os.path.join("test.ova", "test.bin") def test_list_images(loop, qemu, tmpdir):