-
Notifications
You must be signed in to change notification settings - Fork 12
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Mtf config file #218
Mtf config file #218
Conversation
52284c9
to
3863727
Compare
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
What is the expected workflow? Will the mtf.yaml config be supplied with the package and users will override it?
moduleframework/mtf.yaml
Outdated
@@ -0,0 +1,61 @@ | |||
default_module: docker |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
this file will require a lot of documentation so users would understand what each key means
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
thanks for these comments.
Yep, I expect that package will provide some default configuration (for testing upstream/fedora)
and some users who understand that, is able to reconfigure it to another value.
from that PoV it is not expected that "normal" user should understand that.
Yep, would be nice to add there documentation. for now probably it is better without documentation, than have these values hardcoded inside python code.
logic of loading files is on lines:
https://github.com/fedora-modularity/meta-test-family/pull/218/files#diff-d49eca679ceb3a9c6a60a7a4afec5f21R89
it will use these files and configuration is updated with each existing file, meand that it loads 1. and in case 3. exist, config is updated by these values
- /usr/lib/python2.7/site-packages/moduleframework/mtf.yaml
- /etc/mtf.yaml
- ~/.mtf.yaml
c1d28ce
to
24c1c38
Compare
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Sometimes you use common.fce
and sometimes only fce
. Like print_info.
Also improve ConfigMTF class so that it is able to use getattr
method like https://docs.python.org/2/library/functions.html#getattr
moduleframework/common.py
Outdated
@@ -1,4 +1,4 @@ | |||
# | |||
# -*- coding: utf-8 -*- | |||
# Meta test family (MTF) is a tool to test components of a modular Fedora: |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I would prefer to remove it. It tests also containers. Not or modular Fedora. The line below too.
moduleframework/common.py
Outdated
|
||
class MTFConfParser(object): | ||
configname = "mtf.yaml" | ||
source_cfg_file = os.path.join(os.path.dirname(__file__), configname) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I would move it to /usr/share/modularityframework/
. /usr/lib/python2.7/...
is for python packages.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I thought about that too and in init version I had it there. I'll move it there
moduleframework/common.py
Outdated
class MTFConfParser(object): | ||
configname = "mtf.yaml" | ||
source_cfg_file = os.path.join(os.path.dirname(__file__), configname) | ||
default_cfg_file = os.path.join("/etc", configname) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Add /etc
at the beginning of the file common.py. There is already set of constants.
moduleframework/common.py
Outdated
self.options = config | ||
|
||
|
||
def get(self, section=None, key=None): |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
What about to use function getattr
like https://docs.python.org/2/library/functions.html#getattr
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I'll implement that. sounds well
@@ -868,9 +858,10 @@ def get_module_type(): | |||
""" | |||
amodule = os.environ.get('MODULE') | |||
readconfig = get_config(fail_without_url=False) | |||
if "default_module" in readconfig and readconfig[ | |||
"default_module"] is not None and amodule is None: | |||
if amodule is None and readconfig.get("default_module"): |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
what about something like:
amodule = getattr(conf[options], "default_module", None)
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
fixed by elegant way: config parser has dict as parent class, so all dict methods available there.
@@ -104,14 +107,16 @@ def setRepositoriesAndWhatToInstall(self, repos=[], whattooinstall=None): | |||
if repos: | |||
self.repos = repos | |||
else: | |||
self.repos += get_compose_url() or self.get_url() | |||
self.repos += common.get_compose_url() or self.get_url() |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Here you use common.
, but above only print_info
. Any reason?
Keep the python style.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I'll fix it. would be nice also to fix all these issues in next PR, we can do issue for this cleanup
moduleframework/mtf.yaml
Outdated
|
||
# openshift specific section | ||
openshift: | ||
init_wait: 50 |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Add more documentation
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I'm not able to add there documenttation, because you wrote this part and I've just moved these constants out of code to this file without knowledge what this does mean
moduleframework/mtf.yaml
Outdated
( test -e /usr/bin/yum && echo 'yum -y' || | ||
echo 'apt-get -y' ) )" | ||
# which values are considered as true | ||
true_values: ['yes', 'YES', 'yes', 'True', 'true', 'ok', 'OK'] |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This can be one general function. I don't see any reason, why to have it here, in config file.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
make sense
moduleframework/mtf_scheduler.py
Outdated
@@ -205,10 +202,10 @@ def __init__(self, args, unknown): | |||
if args.linter: | |||
self.tests += glob.glob("{MTF_TOOLS}/{GENERIC_TEST}/*.py".format( | |||
MTF_TOOLS=metadata_common.MetadataLoaderMTF.MTF_LINTER_PATH, | |||
GENERIC_TEST=common.GENERIC_TEST)) | |||
GENERIC_TEST=conf.get("generic", "generic_tests"))) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Again, either double get
or even better getattr
.
moduleframework/mtf.yaml
Outdated
|
||
# openshift specific section | ||
openshift: | ||
init_wait: 50 |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Configuration file is a bit long. What about to create a directory /etc/mtf/
and have there several configuration files. One for each type. Ease for modification.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
this is good idea, but I'm not sure if anybody than me will modify it :-)
We can discuss it. I like this idea
moduleframework/mtf.yaml
Outdated
# timeout in secs, how long wait for compose (composes are cached, but first round can take long time (createrepo of packages)) | ||
timeout: 1200 | ||
new_compose_dict: { sigkeys: [''] } | ||
url: "https://odcs.fedoraproject.org" |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I expect that internally we'll have a different config.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Yes, it is also mentioned few lines under (location of internal odcs server)
Probably we will ship, or somewhere stored config file for downstream testing
prepare for using private neworks inside nspawn prepare for using private neworks inside nspawn
moduleframework/common.py
Outdated
from avocado.utils import process | ||
from moduleframework.mtfexceptions import ModuleFrameworkException, ConfigExc, CmdExc, DefaultConfigExc | ||
from mtfexceptions import ModuleFrameworkException, ConfigExc, CmdExc, DefaultConfigExc | ||
from core import DATADIR, is_debug, is_not_silent, print_info, print_debug |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Why not only import core
. print_info is so general and we don't know from which module comes from.
moduleframework/common.py
Outdated
|
||
class MTFConfParser(dict): | ||
configdir = "mtf.conf.d" | ||
source_cfg = os.path.join(*(["/"] + DATADIR + [configdir])) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Add /
to DATADIR and remove ["/"].
I would write
os.path.join(*(DATADIR, [configdir]))
What do you want to do with this code? All directories under DATADIR?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
@phracek this is not possible, it is connected with using this in setup.py (there is just relative path, so I cannot add this to this DATADIR list)
|
||
def __init__(self): | ||
config = {} | ||
for cfgdir in [self.source_cfg, self.default_cfg, self.user_cfg]: |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Will this work with several self.source_cfg directories?
if is_true(odcstoken): | ||
if conf.get("openidc").get("token"): | ||
# use value defined in config file if defined | ||
return conf["openidc"]["token"] |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
get
and get
are missing.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
@phracek it is dict, so it is not important to use get, because it is already checked that is defined in if
'https://pagure.io/odcs/renew-compose', | ||
'https://pagure.io/odcs/delete-compose', | ||
] | ||
oidc = openidc_client.OpenIDCClient(*conf["openidc"]["auth"]) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
the same as above.
'https://pagure.io/odcs/delete-compose', | ||
] | ||
oidc = openidc_client.OpenIDCClient(*conf["openidc"]["auth"]) | ||
scopes = conf["openidc"]["scopes"] |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
the same
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
@jscotka You did not catch traceback. Is it enough exception for request.exception.HTTPError?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
@phracek I think that this is enough. Not important to catch it and transform to another exception. And I've not changed this behaviour anyhow
@@ -348,7 +288,7 @@ def get_profile(): | |||
:return: str | |||
""" | |||
|
|||
return os.environ.get('PROFILE') or MODULE_DEFAULT_PROFILE | |||
return os.environ.get('PROFILE') or conf["modularity"]["default_profile"] |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
the same.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
@jscotka This returns, either environment variable or value from conf
or None. Is it requested?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
yes this is expected. or this also can cause traceback in case some user break this value from config. It is expected
@@ -469,7 +409,7 @@ def get_template(self): | |||
get location of template from config.yaml file | |||
:return: str | |||
""" | |||
return self.info.get(TEMPLATE) | |||
return self.info.get(conf["openshift"]["template"]) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Default value is missing.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
@jscotka Do you count with None if template
is not specified?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
It has to be specified in this config. There is stored default value and in case user remove this item from config, it causes traceback, it is expected.
@@ -26,7 +26,8 @@ | |||
import random | |||
import string | |||
from avocado.utils.process import CmdError | |||
from moduleframework import common | |||
from moduleframework.common import conf, is_debug, print_debug, print_info, trans_dict, sanitize_cmd, \ |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Some parts are part of module core
instead of common
.
62c2004
to
e2abdb4
Compare
|
||
class MTFConfParser(dict): | ||
configdir = "mtf.conf.d" | ||
source_cfg = os.path.join(*(["/"] + core.DATADIR + [configdir])) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
@jscotka What do you want to do with this command?
source_cfg = os.path.join(*(["/"] + ['etc'] + ["yum"]))
print source_cfg
prints /etc/yum
Why not only os.path.join(core.DATADIR, configdir)?
core.DATADIR could be
core.DATADIR = "/usr/share/moduleframework"
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
because threre is by intention missing leading /
so that it created relative path, instead of /usr/share/moduleframework
, and also it is caused by that this syntax was used in setup.py
for this directory. So I did not want to change it in setup.py, just put it out of hardcoded value in setup.py
see: https://github.com/fedora-modularity/meta-test-family/pull/218/files#diff-2eeaed663bd0d25b7e608891384b7298L59
'https://pagure.io/odcs/renew-compose', | ||
'https://pagure.io/odcs/delete-compose', | ||
] | ||
oidc = openidc_client.OpenIDCClient(*conf["openidc"]["auth"]) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
@jscotka Check if ["openidc"]["auth"] exists.
what about if oidc is None. Where do you catch traceback?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I don't want to catch traceback here in case user break config. This behaviour is same for various service, like apache server, in case user write bad config, or break default apache config file, it did not start and probably just lead to some strange error.
@@ -674,7 +612,7 @@ def run(self, command, **kwargs): | |||
|
|||
def get_packager(self): | |||
if not self.packager: | |||
self.packager = self.run(PACKAGER_COMMAND, verbose=False).stdout.strip() | |||
self.packager = self.run(conf["generic"]["packager_cmd"], verbose=False).stdout.strip() |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
It will be specified always, right? What if packager_cmd is missing?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
it causes traceback. by default it is defined in shipped mtf config. if user remove this. then it will lead to expected traceback.
cfgfile = "/usr/share/moduleframework/docs/example-config-minimal.yaml" | ||
print_debug("Using default minimal config: %s" % cfgfile) | ||
core.print_debug("Using default minimal config: %s" % cfgfile) | ||
|
||
|
||
try: | ||
with open(cfgfile, 'r') as ymlfile: | ||
xcfg = yaml.load(ymlfile.read()) | ||
doc_name = ['modularity-testing', 'meta-test-family', 'meta-test'] |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Why meta-test
?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I don't know. I've defided it looong time ago, as shorter name in config files, it is closed to modularity-testing, it also miss word framework
return parent | ||
|
||
|
||
def get_docker_file(dir_name=DEFAULT_DIR_OF_DOCKER_RELATED_STUFF): | ||
def get_docker_file(dir_name=conf["docker"]["dockerfiledefaultlocation"]): |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This can be None if dockerfiledefaultlocation
is empty. Do you count with it?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
it will lead to traceback, it is expected
@@ -40,7 +44,7 @@ class ComposeParser(object): | |||
|
|||
def __init__(self, compose): | |||
self.compose = compose | |||
xmlrepomd = compose + "/" + REPOMD | |||
xmlrepomd = compose + "/" + common.conf["compose"]["repomd"] |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Why not os.path.join?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I Know why, it is URL, not directory. It is possible to use os.path.join now, it is equivalent, but in some case os.path.join can lead to another separator like \
at windows, and it causes bad URL
import sys | ||
import os | ||
|
||
DATADIR = ['usr', 'share', 'moduleframework'] |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
@jscotka Why not /usr/share/moduleframework
?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
because original usage of this list is in setup.py
in this format, copyied from other upstream projects, and I did't want to change this behaviour, just need to have this location in better place that in setup.py.
see https://github.com/fedora-modularity/meta-test-family/pull/218/files#diff-2eeaed663bd0d25b7e608891384b7298L59
import core | ||
|
||
|
||
class MTFConfParser(dict): |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
@jscotka What about something like this:
class Config(dict):
def __getattr__(self, key):
try:
return self[key]
except KeyError:
raise AttributeError
def __setattr__(self, key, value):
self[key] = value
def __init__(self, yaml_file, release="current"):
config = yaml.load(yaml_file)
self["raw"] = config
pdc = config["pdc"]
....
And you have access to all fields.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
@phracek does that have some benefits instead of actual implementation to redefine these getters and setters?
I trough to redefine __getattr__
to lead some easier to debug exceptions (like, show path to file where is this found, and show value from default config, what should not be modifed), but it could be further improvement
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
yeah let's leave it for now.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
LGTM now.
This tries to remove hardcoded variables and move them to config file(s)