[live-media] Add global settings
These can be overriden for a particular image, but in general case they can simplify the config. Signed-off-by: Lubomír Sedlář <lsedlar@redhat.com>
This commit is contained in:
parent
595845e104
commit
86bb816417
@ -758,6 +758,29 @@ Live Media Settings
|
|||||||
* ``title`` (*str*)
|
* ``title`` (*str*)
|
||||||
* ``install_tree_from`` (*str*) -- variant to take install tree from
|
* ``install_tree_from`` (*str*) -- variant to take install tree from
|
||||||
|
|
||||||
|
If many of your media use the same value for one of ``ksurl``, ``release``,
|
||||||
|
``target`` or ``version``, consider using these options to set the value in one
|
||||||
|
place and have all media inherit it.
|
||||||
|
|
||||||
|
**live_media_ksurl**
|
||||||
|
(*str*) -- Provides a fallback for media that do not specify ``ksurl`` in
|
||||||
|
the ``live_media`` block.
|
||||||
|
|
||||||
|
**live_media_release**
|
||||||
|
(*str*) -- Provides a fallback for media that do not specify ``release`` in
|
||||||
|
the ``live_media`` block. Please note that if you set this, there is no way
|
||||||
|
to unset it for a particular media. This is important if you want the
|
||||||
|
release generated by Koji.
|
||||||
|
|
||||||
|
**live_media_target**
|
||||||
|
(*str*) -- Provides a fallback for media that do not specify ``target`` in
|
||||||
|
the ``live_media`` block.
|
||||||
|
|
||||||
|
**live_media_version**
|
||||||
|
(*str*) -- Provides a fallback for media that do not specify ``version`` in
|
||||||
|
the ``live_media`` block.
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
Image Build Settings
|
Image Build Settings
|
||||||
====================
|
====================
|
||||||
|
@ -17,9 +17,33 @@ class LiveMediaPhase(PhaseBase):
|
|||||||
"""class for wrapping up koji spin-livemedia"""
|
"""class for wrapping up koji spin-livemedia"""
|
||||||
name = 'live_media'
|
name = 'live_media'
|
||||||
|
|
||||||
|
config_options = (
|
||||||
|
{
|
||||||
|
"name": "live_media",
|
||||||
|
"expected_types": [dict],
|
||||||
|
"optional": True,
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"name": "live_media_ksurl",
|
||||||
|
"expected_types": [str],
|
||||||
|
"optional": True,
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"name": "live_media_target",
|
||||||
|
"expected_types": [str],
|
||||||
|
"optional": True,
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"name": "live_media_release",
|
||||||
|
"expected_types": [str],
|
||||||
|
"optional": True,
|
||||||
|
}
|
||||||
|
)
|
||||||
|
|
||||||
def __init__(self, compose):
|
def __init__(self, compose):
|
||||||
super(LiveMediaPhase, self).__init__(compose)
|
super(LiveMediaPhase, self).__init__(compose)
|
||||||
self.pool = ThreadPool(logger=self.compose._logger)
|
self.pool = ThreadPool(logger=self.compose._logger)
|
||||||
|
self._global_ksurl = None
|
||||||
|
|
||||||
def skip(self):
|
def skip(self):
|
||||||
if super(LiveMediaPhase, self).skip():
|
if super(LiveMediaPhase, self).skip():
|
||||||
@ -61,10 +85,13 @@ class LiveMediaPhase(PhaseBase):
|
|||||||
return sorted(arches)
|
return sorted(arches)
|
||||||
|
|
||||||
def _get_release(self, image_conf):
|
def _get_release(self, image_conf):
|
||||||
"""If release is set explicitly to None, replace it with date and respin."""
|
"""If release is set explicitly to None, replace it with date and respin.
|
||||||
if 'release' in image_conf and image_conf['release'] is None:
|
Uses both image configuration and global config.
|
||||||
|
"""
|
||||||
|
for key, conf in [('release', image_conf), ('live_media_release', self.compose.conf)]:
|
||||||
|
if key in conf and conf[key] is None:
|
||||||
return '%s.%s' % (self.compose.compose_date, self.compose.compose_respin)
|
return '%s.%s' % (self.compose.compose_date, self.compose.compose_respin)
|
||||||
return image_conf.get('release', None)
|
return image_conf.get('release', self.compose.conf.get('live_media_release'))
|
||||||
|
|
||||||
def _get_install_tree(self, image_conf, variant):
|
def _get_install_tree(self, image_conf, variant):
|
||||||
if 'install_tree_from' in image_conf:
|
if 'install_tree_from' in image_conf:
|
||||||
@ -80,16 +107,33 @@ class LiveMediaPhase(PhaseBase):
|
|||||||
self.compose.paths.compose.os_tree('$basearch', variant, create_dir=False)
|
self.compose.paths.compose.os_tree('$basearch', variant, create_dir=False)
|
||||||
)
|
)
|
||||||
|
|
||||||
|
@property
|
||||||
|
def global_ksurl(self):
|
||||||
|
"""Get globally configure kickstart URL. It will only be resolved once."""
|
||||||
|
if not self._global_ksurl:
|
||||||
|
ksurl = self.compose.conf.get('live_media_ksurl')
|
||||||
|
self._global_ksurl = resolve_git_url(ksurl)
|
||||||
|
return self._global_ksurl
|
||||||
|
|
||||||
|
def _get_ksurl(self, image_conf):
|
||||||
|
"""Get ksurl from `image_conf`. If not present, fall back to global one."""
|
||||||
|
if 'ksurl' in image_conf:
|
||||||
|
return resolve_git_url(image_conf['ksurl'])
|
||||||
|
return self.global_ksurl
|
||||||
|
|
||||||
|
def _get_config(self, image_conf, opt):
|
||||||
|
return image_conf.get(opt, self.compose.conf.get('live_media_' + opt))
|
||||||
|
|
||||||
def run(self):
|
def run(self):
|
||||||
for variant in self.compose.get_variants():
|
for variant in self.compose.get_variants():
|
||||||
arches = set([x for x in variant.arches if x != 'src'])
|
arches = set([x for x in variant.arches if x != 'src'])
|
||||||
|
|
||||||
for image_conf in get_variant_data(self.compose.conf, self.name, variant):
|
for image_conf in get_variant_data(self.compose.conf, self.name, variant):
|
||||||
config = {
|
config = {
|
||||||
'target': image_conf['target'],
|
'target': self._get_config(image_conf, 'target'),
|
||||||
'arches': self._get_arches(image_conf, arches),
|
'arches': self._get_arches(image_conf, arches),
|
||||||
'ksfile': image_conf['kickstart'],
|
'ksfile': image_conf['kickstart'],
|
||||||
'ksurl': resolve_git_url(image_conf['ksurl']),
|
'ksurl': self._get_ksurl(image_conf),
|
||||||
'ksversion': image_conf.get('ksversion'),
|
'ksversion': image_conf.get('ksversion'),
|
||||||
'scratch': image_conf.get('scratch', False),
|
'scratch': image_conf.get('scratch', False),
|
||||||
'release': self._get_release(image_conf),
|
'release': self._get_release(image_conf),
|
||||||
@ -98,7 +142,7 @@ class LiveMediaPhase(PhaseBase):
|
|||||||
'title': image_conf.get('title'),
|
'title': image_conf.get('title'),
|
||||||
'repo': self._get_repos(image_conf, variant),
|
'repo': self._get_repos(image_conf, variant),
|
||||||
'install_tree': self._get_install_tree(image_conf, variant),
|
'install_tree': self._get_install_tree(image_conf, variant),
|
||||||
'version': image_conf['version'],
|
'version': self._get_config(image_conf, 'version'),
|
||||||
}
|
}
|
||||||
self.pool.add(LiveMediaThread(self.pool))
|
self.pool.add(LiveMediaThread(self.pool))
|
||||||
self.pool.queue_put((self.compose, variant, config))
|
self.pool.queue_put((self.compose, variant, config))
|
||||||
|
@ -54,6 +54,99 @@ class TestLiveMediaPhase(PungiTestCase):
|
|||||||
'version': 'Rawhide',
|
'version': 'Rawhide',
|
||||||
}))])
|
}))])
|
||||||
|
|
||||||
|
@mock.patch('pungi.phases.livemedia_phase.resolve_git_url')
|
||||||
|
@mock.patch('pungi.phases.livemedia_phase.ThreadPool')
|
||||||
|
def test_live_media_with_global_opts(self, ThreadPool, resolve_git_url):
|
||||||
|
compose = DummyCompose(self.topdir, {
|
||||||
|
'live_media_ksurl': 'git://example.com/repo.git#HEAD',
|
||||||
|
'live_media_target': 'f24',
|
||||||
|
'live_media_release': 'RRR',
|
||||||
|
'live_media_version': 'Rawhide',
|
||||||
|
'live_media': {
|
||||||
|
'^Server$': [
|
||||||
|
{
|
||||||
|
'kickstart': 'file.ks',
|
||||||
|
'name': 'Fedora Server Live',
|
||||||
|
},
|
||||||
|
{
|
||||||
|
'kickstart': 'different.ks',
|
||||||
|
'name': 'Fedora Server Live',
|
||||||
|
},
|
||||||
|
{
|
||||||
|
'kickstart': 'yet-another.ks',
|
||||||
|
'name': 'Fedora Server Live',
|
||||||
|
'ksurl': 'git://different.com/repo.git',
|
||||||
|
'target': 'f25',
|
||||||
|
'release': 'XXX',
|
||||||
|
'version': '25',
|
||||||
|
}
|
||||||
|
]
|
||||||
|
},
|
||||||
|
'koji_profile': 'koji',
|
||||||
|
})
|
||||||
|
|
||||||
|
resolve_git_url.return_value = 'git://example.com/repo.git#BEEFCAFE'
|
||||||
|
|
||||||
|
phase = LiveMediaPhase(compose)
|
||||||
|
|
||||||
|
phase.run()
|
||||||
|
self.assertTrue(phase.pool.add.called)
|
||||||
|
self.assertItemsEqual(resolve_git_url.mock_calls,
|
||||||
|
[mock.call('git://example.com/repo.git#HEAD'),
|
||||||
|
mock.call('git://different.com/repo.git')])
|
||||||
|
self.assertEqual(phase.pool.queue_put.call_args_list,
|
||||||
|
[mock.call((compose,
|
||||||
|
compose.variants['Server'],
|
||||||
|
{
|
||||||
|
'arches': ['amd64', 'x86_64'],
|
||||||
|
'ksfile': 'file.ks',
|
||||||
|
'ksurl': 'git://example.com/repo.git#BEEFCAFE',
|
||||||
|
'ksversion': None,
|
||||||
|
'name': 'Fedora Server Live',
|
||||||
|
'release': 'RRR',
|
||||||
|
'repo': [self.topdir + '/compose/Server/$basearch/os'],
|
||||||
|
'scratch': False,
|
||||||
|
'skip_tag': None,
|
||||||
|
'target': 'f24',
|
||||||
|
'title': None,
|
||||||
|
'install_tree': self.topdir + '/compose/Server/$basearch/os',
|
||||||
|
'version': 'Rawhide',
|
||||||
|
})),
|
||||||
|
mock.call((compose,
|
||||||
|
compose.variants['Server'],
|
||||||
|
{
|
||||||
|
'arches': ['amd64', 'x86_64'],
|
||||||
|
'ksfile': 'different.ks',
|
||||||
|
'ksurl': 'git://example.com/repo.git#BEEFCAFE',
|
||||||
|
'ksversion': None,
|
||||||
|
'name': 'Fedora Server Live',
|
||||||
|
'release': 'RRR',
|
||||||
|
'repo': [self.topdir + '/compose/Server/$basearch/os'],
|
||||||
|
'scratch': False,
|
||||||
|
'skip_tag': None,
|
||||||
|
'target': 'f24',
|
||||||
|
'title': None,
|
||||||
|
'install_tree': self.topdir + '/compose/Server/$basearch/os',
|
||||||
|
'version': 'Rawhide',
|
||||||
|
})),
|
||||||
|
mock.call((compose,
|
||||||
|
compose.variants['Server'],
|
||||||
|
{
|
||||||
|
'arches': ['amd64', 'x86_64'],
|
||||||
|
'ksfile': 'yet-another.ks',
|
||||||
|
'ksurl': 'git://example.com/repo.git#BEEFCAFE',
|
||||||
|
'ksversion': None,
|
||||||
|
'name': 'Fedora Server Live',
|
||||||
|
'release': 'XXX',
|
||||||
|
'repo': [self.topdir + '/compose/Server/$basearch/os'],
|
||||||
|
'scratch': False,
|
||||||
|
'skip_tag': None,
|
||||||
|
'target': 'f25',
|
||||||
|
'title': None,
|
||||||
|
'install_tree': self.topdir + '/compose/Server/$basearch/os',
|
||||||
|
'version': '25',
|
||||||
|
}))])
|
||||||
|
|
||||||
@mock.patch('pungi.phases.livemedia_phase.ThreadPool')
|
@mock.patch('pungi.phases.livemedia_phase.ThreadPool')
|
||||||
def test_live_media_non_existing_install_tree(self, ThreadPool):
|
def test_live_media_non_existing_install_tree(self, ThreadPool):
|
||||||
compose = DummyCompose(self.topdir, {
|
compose = DummyCompose(self.topdir, {
|
||||||
|
Loading…
Reference in New Issue
Block a user