From c4b4a9b9f26675c010bc021e882ff5525ac99c39 Mon Sep 17 00:00:00 2001 From: Danis Valiullin Date: Sat, 11 Jan 2020 12:20:11 +0300 Subject: [PATCH] [imager] Add repository options support. --- src/img_boss/build_ks.py | 26 ++++++++++++++---- src/img_web/app/forms.py | 13 +++++++-- src/img_web/app/models.py | 3 +- src/img_web/app/views.py | 58 +++++++++++++++++++++++++++++---------- 4 files changed, 77 insertions(+), 23 deletions(-) diff --git a/src/img_boss/build_ks.py b/src/img_boss/build_ks.py index 64542b1..4724086 100755 --- a/src/img_boss/build_ks.py +++ b/src/img_boss/build_ks.py @@ -50,6 +50,9 @@ :image.extra_repos (list): OPTIONAL URLs of package repositories that will be added to the kickstart file + :image.repourl_options (dict) + OPTIONAL Additional options for `repo` string in kickstart file + (key - repo url; value - dict of options) :image.groups (list): OPTIONAL Group names to be added to the kickstart file :image.packages (list): @@ -258,7 +261,8 @@ class Moblin_RepoData(F8_RepoData): def __init__(self, baseurl="", mirrorlist="", name="", priority=None, includepkgs=[], excludepkgs=[], save=False, proxy=None, proxy_username=None, proxy_password=None, debuginfo=False, - source=False, gpgkey=None, disable=False, ssl_verify="yes"): + source=False, gpgkey=None, disable=False, ssl_verify="yes", + **kwargs): F8_RepoData.__init__(self, baseurl=baseurl, mirrorlist=mirrorlist, name=name, includepkgs=includepkgs, excludepkgs=excludepkgs) @@ -738,7 +742,8 @@ def __str__(self): return retval -def build_kickstart(base_ks, packages=[], groups=[], projects=[]): +def build_kickstart(base_ks, packages=[], groups=[], projects=[], + project_options=None): """Build a kickstart file using the handler class, with custom kickstart, packages, groups and projects. @@ -746,6 +751,7 @@ def build_kickstart(base_ks, packages=[], groups=[], projects=[]): :param packages: list of packagenames :param groups: list of groupnames :param projects: list of rpm repository URLs + :param project_options: options for each project :returns: Validated kickstart with any extra packages, groups or repourls added @@ -790,7 +796,13 @@ def __str__(self): name = name.replace(":/", "_") name = name.replace("/", "_") name = re.sub('@[A-Z]*@', '_', name) - repo = Moblin_RepoData(baseurl=prj, name=name, save=True) + params = { + 'baseurl': prj, 'name': name, 'save': True, + } + if project_options: + url_params = project_options.get(prj, {}) + params.update(url_params) + repo = Moblin_RepoData(**params) ks.handler.repo.repoList.append(repo) ks_txt = str(ks.handler) @@ -928,9 +940,13 @@ def handle_wi(self, wid): kstemplate.write(f.image.kickstart) ksfile = kstemplate.name remove = ksfile + + project_options = ( + f.image.repourl_options and f.image.repourl_options.as_dict()) try: - ks = build_kickstart(ksfile, packages=packages, groups=groups, - projects=projects) + ks = build_kickstart( + ksfile, packages=packages, groups=groups, + projects=projects, project_options=project_options) f.image.kickstart = ks except (KickstartError, OptionValueError, ValueError), error: f.msg.append("Error while handling Kickstart: %s" % error) diff --git a/src/img_web/app/forms.py b/src/img_web/app/forms.py index 87d523e..5cd06de 100644 --- a/src/img_web/app/forms.py +++ b/src/img_web/app/forms.py @@ -39,7 +39,8 @@ def list_features(): features = get_features() choices = set() for name in features.sections(): - if name.startswith("repositories"): + if (name.startswith("repositories") or + name.startswith("repository-options-")): continue description = name if features.has_option(name, "description"): @@ -58,11 +59,19 @@ def expand_feature(name): if features.has_option(name, "packages"): feat["packages"].update(features.get(name, "packages").split(',')) + feat['repo_options'] = {} if features.has_option(name, "repos"): + options_prefix = "repository-options-" for repo in features.get(name, "repos").split(","): + if features.has_section(options_prefix + repo): + feat['repo_options'][repo] = dict( + features.items(options_prefix + repo)) + for section in repo_sections: + if isinstance(feat[section], set): + feat[section] = {} if features.has_option(section, repo): - feat[section].add(features.get(section, repo)) + feat[section][repo] = features.get(section, repo) return dict(feat) class extraReposForm(forms.Form): diff --git a/src/img_web/app/models.py b/src/img_web/app/models.py index 2ab82cd..351ed6b 100644 --- a/src/img_web/app/models.py +++ b/src/img_web/app/models.py @@ -134,7 +134,8 @@ def to_fields(self): "arch" : self.arch, "prefix" : "%s/%s" % (self.queue.name, self.user.username), - "result" : self.status + "result" : self.status, + "repourl_options": getattr(self, 'repourl_options', {}), } } diff --git a/src/img_web/app/views.py b/src/img_web/app/views.py index 394a93d..905a830 100644 --- a/src/img_web/app/views.py +++ b/src/img_web/app/views.py @@ -92,32 +92,54 @@ def submit(request): imgjob.kickstart = "".join(ks) + vars_re = re.compile(r'^# Var@([\S]+)@([\S]+):(.*)$') + features_vars = {} + for line in ks: - if re.match(r'^#.*?KickstartType:.+$', line): - ks_type = line.split(":", 1)[1].strip() + if not line.startswith('#'): break + vars_match = vars_re.match(line) + if vars_match: + feature = vars_match.group(1) + var = vars_match.group(2) + val = vars_match.group(3).strip() + if feature in features_vars: + features_vars[feature][var] = val + else: + features_vars[feature] = {var: val} + elif re.match(r'^#.*?KickstartType:.+$', line): + ks_type = line.split(":", 1)[1].strip() + if ksname.endswith('.ks'): ksname = ksname[0:-3] - extra_repos = set() + extra_repos_data = {} for repo in reposdata: if repo.get('obs', None): reponame = repo['repo'] if not reponame.startswith('/'): reponame = "/%s" % reponame repo_url = repo['obs'] + repo['project'].replace(':', ':/') + reponame - extra_repos.add(repo_url) + extra_repos_data[reponame] = repo_url + repo_options = {} overlay = set([ x for x in jobdata['overlay'].split(',') if x.strip()]) if 'features' in jobdata: for feat in jobdata['features']: print feat + repo_options.update(feat.get('repo_options', {})) repos_type = 'repositories-%s' % ks_type if not ks_type or not repos_type in feat: repos_type = 'repositories' - extra_repos.update(feat.get(repos_type, set())) + feat_repos = feat.get(repos_type, dict()) + for name, url in feat_repos.items(): + if name in features_vars: + for var, val in features_vars[name].items(): + url = url.replace('@%s@' % var, val) + extra_repos_data[name] = url + overlay.update(feat.get('pattern', '')) overlay.update(feat.get('packages', set())) @@ -154,16 +176,22 @@ def submit(request): if devicevarianttoken: tokenmap['DEVICEVARIANT'] = devicevarianttoken - tokens_list = [] - extra_repos_tmp = [] - for token, tokenvalue in tokenmap.items(): - ksname = ksname.replace("@%s@" % token, tokenvalue) - tokens_list.append("%s:%s" % (token, tokenvalue)) - for repo in extra_repos: - extra_repos_tmp.append(repo.replace("@%s@" % token, tokenvalue)) - extra_repos = extra_repos_tmp[:] - extra_repos_tmp = [] - + tokens_list = set() + extra_repos = set() + repourl_options = {} + + for repo_name, repo_url_tmpl in extra_repos_data.items(): + repo_url = repo_url_tmpl + for token, tokenvalue in tokenmap.items(): + ksname = ksname.replace("@%s@" % token, tokenvalue) + tokens_list.add("%s:%s" % (token, tokenvalue)) + repo_url = repo_url_tmpl.replace("@%s@" % token, tokenvalue) + extra_repos.add(repo_url) + cur_repo_options = repo_options.get(repo_name) + if cur_repo_options: + repourl_options[repo_url] = cur_repo_options + + imgjob.repourl_options = repourl_options imgjob.name = ksname imgjob.arch = jobdata['architecture'] imgjob.tokenmap = ",".join(tokens_list)