From ffcf7ec7de471dfb51c6d18c87621c84be9c0bd1 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Henar=20Mu=C3=B1oz=20Frutos?= Date: Mon, 27 Jul 2015 11:12:34 +0200 Subject: [PATCH] Adding svn for file download. Murano agent can download files in the VM when it is executing the execution plan. However, just git client is allowed for download files. Svn client should be provided to add files in a svn repository Closes Bug: #1486055 Change-Id: Ib1fd13fa86d012fb95d19aabda0dff7c28f99620 --- muranoagent/files_manager.py | 43 +++++++++++++++++++ muranoagent/tests/unit/test_files_manager.py | 44 +++++++++++++++++++- 2 files changed, 86 insertions(+), 1 deletion(-) diff --git a/muranoagent/files_manager.py b/muranoagent/files_manager.py index 1b892c3a..461fb162 100644 --- a/muranoagent/files_manager.py +++ b/muranoagent/files_manager.py @@ -16,11 +16,14 @@ import base64 import git import os +import re import requests import shutil +import subprocess import urlparse from oslo_log import log as logging +from oslo_utils import encodeutils from muranoagent.common import config @@ -113,6 +116,8 @@ class FilesManager(object): try: if self._is_git_repository(url_file): git.Git().clone(url_file, folder) + elif self._is_svn_repository(url_file): + self._download_svn(url_file, folder) else: self._download_file(url_file, folder) except Exception as e: @@ -160,3 +165,41 @@ class FilesManager(object): return (url.startswith(("git://", "git+http://", "git+https:/")) or url.endswith('.git')) + + def _is_svn_repository(self, url): + http_regex = "https?://(.*)/svn/(.*)" + http_matches = re.search(http_regex, url) + svn_regex = "svn://(.*)" + svn_matches = re.search(svn_regex, url) + if http_matches is None and svn_matches is None: + return False + else: + return True + + def _download_svn(self, url_file, folder): + self._execute_command("svn checkout {0} --non-interactive " + "--trust-server-cert {1}". + format(url_file, folder)) + + def _execute_command(self, command): + + process = subprocess.Popen( + command, + stdout=subprocess.PIPE, + stderr=subprocess.PIPE, + universal_newlines=True, + cwd=os.getcwd(), + shell=True) + stdout, stderr = process.communicate(input) + retcode = process.poll() + + if stdout is not None: + stdout = encodeutils.safe_decode('utf-8') + LOG.debug(stdout) + + if stderr is not None: + stderr = encodeutils.safe_decode('utf-8') + LOG.error(stderr) + + if retcode != 0: + raise ValueError(stderr) diff --git a/muranoagent/tests/unit/test_files_manager.py b/muranoagent/tests/unit/test_files_manager.py index d6646d2e..ffdfabde 100644 --- a/muranoagent/tests/unit/test_files_manager.py +++ b/muranoagent/tests/unit/test_files_manager.py @@ -35,6 +35,22 @@ class TestFileManager(base.MuranoAgentTestCase): super(TestFileManager, self).setUp() CONF.set_override('storage', 'cache') + def test_is_svn(self): + files = files_manager.FilesManager(self.get_template_downloable()) + self.assertTrue(files._is_svn_repository("https://sdfa/svn/ss")) + + def test_is_svn_first(self): + files = files_manager.FilesManager(self.get_template_downloable()) + self.assertTrue(files._is_svn_repository("svn://test")) + + def test_is_svn_wrong_http_protocol(self): + files = files_manager.FilesManager(self.get_template_downloable()) + self.assertFalse(files._is_svn_repository("httpp://sdfa/svn/ss")) + + def test_is_svn_wrong_svn_slash(self): + files = files_manager.FilesManager(self.get_template_downloable()) + self.assertFalse(files._is_svn_repository("svn:sdfa/svn/ss")) + @mock.patch('os.makedirs') def test_get_folder_git(self, mock_path): """It gets the folder where the URL is a git URL.""" @@ -89,6 +105,20 @@ class TestFileManager(base.MuranoAgentTestCase): files = files_manager.FilesManager(self.get_template_downloable()) files._download_url_file(template.Files['file']) + @mock.patch('subprocess.Popen') + @mock.patch('os.makedirs') + def test_execution_plan_type_svn(self, mock_makedir, mock_subproc_popen): + """Test an execution plan with svn files.""" + process_mock = mock.Mock() + attrs = {'communicate.return_value': ('ouput', 'ok'), + 'poll.return_value': 0} + process_mock.configure_mock(**attrs) + mock_subproc_popen.return_value = process_mock + + template = self.get_template_svn() + files = files_manager.FilesManager(template) + files._download_url_file(template.Files['file']) + @mock.patch('os.makedirs') def test_execution_plan_type_downloable_no_Url(self, mock_makedir): """It validates the URL.""" @@ -164,7 +194,19 @@ class TestFileManager(base.MuranoAgentTestCase): Files={ 'file': { 'Name': 'myfile', - 'URL': 'https://www.apache.org/licenses/LICENSE-2.0', + 'URL': 'https://www.apache.org/licenses', + 'Type': 'Downloadable' + } + } + ) + + def get_template_svn(self): + return bunch.Bunch( + ID='ID', + Files={ + 'file': { + 'Name': 'svn', + 'URL': 'https://mysvn/svn/repo', 'Type': 'Downloadable' } }