diff --git a/module_build_service/builder/utils.py b/module_build_service/builder/utils.py index 26fa4020..65e9ee6b 100644 --- a/module_build_service/builder/utils.py +++ b/module_build_service/builder/utils.py @@ -6,6 +6,8 @@ import subprocess import munch import errno import logging +import urlgrabber.grabber as grabber +import urlgrabber.progress as progress import module_build_service import module_build_service.scheduler from module_build_service import log, scm, messaging @@ -112,8 +114,6 @@ def create_local_repo_from_koji_tag(config, tag, repo_dir, archs=None): # Placed here to avoid py2/py3 conflicts... import koji - import urlgrabber.grabber as grabber - import urlgrabber.progress as progress if not archs: archs = ["x86_64", "noarch"] diff --git a/module_build_service/config.py b/module_build_service/config.py index 4f58b18a..c4addbea 100644 --- a/module_build_service/config.py +++ b/module_build_service/config.py @@ -103,6 +103,12 @@ def init_config(app): app.config.from_object(config_section_obj) return conf +class Path: + """ + Config type for paths. Expands the users home directory. + """ + pass + class Config(object): """Class representing the orchestrator configuration.""" @@ -128,8 +134,8 @@ class Config(object): 'default': 0, 'desc': 'Polling interval, in seconds.'}, 'cache_dir': { - 'type': str, - 'default': '/var/cache/module-build-service', + 'type': Path, + 'default': '~/modulebuild/cache', 'desc': 'Cache directory'}, 'pdc_url': { 'type': str, @@ -280,8 +286,8 @@ class Config(object): 'default': 'fedpkg --release f26 srpm', 'desc': ''}, 'mock_resultsdir': { - 'type': str, - 'default': '/tmp', + 'type': Path, + 'default': '~/modulebuild/builds', 'desc': 'Directory for Mock build results.'}, 'scmurls': { 'type': list, @@ -321,7 +327,7 @@ class Config(object): # set defaults for name, values in self._defaults.items(): - self.set_item(name, values['default']) + self.set_item(name, values['default'], values['type']) # override defaults for key in dir(conf_section_obj): @@ -331,7 +337,7 @@ class Config(object): # set item (lower key) self.set_item(key.lower(), getattr(conf_section_obj, key)) - def set_item(self, key, value): + def set_item(self, key, value, value_type=None): """ Set value for configuration item. Creates the self._key = value attribute and self.key property to set/get/del the attribute. @@ -347,6 +353,10 @@ class Config(object): setifok_func = '_setifok_{}'.format(key) if hasattr(self, setifok_func): setx = lambda self, val: getattr(self, setifok_func)(val) + elif value_type == Path: + # For paths, expanduser. + setx = lambda self, val: setattr( + self, "_" + key, os.path.expanduser(val)) else: setx = lambda self, val: setattr(self, "_" + key, val) getx = lambda self: getattr(self, "_" + key) @@ -364,8 +374,8 @@ class Config(object): value = convert(value) except: raise TypeError("Configuration value conversion failed for name: %s" % key) - # unknown type/unsupported conversion - elif convert is not None: + # unknown type/unsupported conversion, or conversion not needed + elif convert is not None and convert not in [Path]: raise TypeError("Unsupported type %s for configuration item name: %s" % (convert, key)) # Set the attribute to the correct value diff --git a/tests/test_config.py b/tests/test_config.py new file mode 100644 index 00000000..73a24ca7 --- /dev/null +++ b/tests/test_config.py @@ -0,0 +1,37 @@ +# Copyright (c) 2016 Red Hat, Inc. +# +# Permission is hereby granted, free of charge, to any person obtaining a copy +# of this software and associated documentation files (the "Software"), to deal +# in the Software without restriction, including without limitation the rights +# to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +# copies of the Software, and to permit persons to whom the Software is +# furnished to do so, subject to the following conditions: +# +# The above copyright notice and this permission notice shall be included in all +# copies or substantial portions of the Software. +# +# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +# IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +# FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +# AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +# LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +# OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE +# SOFTWARE. +# +# Written by Jan Kaluza + +from nose.tools import raises, eq_ + + +import unittest +import mock +import os.path +from mock import patch + +from module_build_service import conf + +class TestConfig(unittest.TestCase): + def test_path_expanduser(self): + test_dir = "~/modulebuild/builds" + conf.mock_resultsdir = test_dir + self.assertEqual(conf.mock_resultsdir, os.path.expanduser(test_dir))