[live-images] Add support for spin-appliance
The config can specify type=appliance so that koji uses spin-appliance instead of spin-livecd. Signed-off-by: Lubomír Sedlář <lsedlar@redhat.com>
This commit is contained in:
parent
ac29bf05ee
commit
5138a9b6e6
@ -646,6 +646,9 @@ Live Images Settings
|
|||||||
* ``specfile`` (*str*) -- for images wrapped in RPM
|
* ``specfile`` (*str*) -- for images wrapped in RPM
|
||||||
* ``scratch`` (*bool*) -- only RPM-wrapped images can use scratch builds,
|
* ``scratch`` (*bool*) -- only RPM-wrapped images can use scratch builds,
|
||||||
but by default this is turned off
|
but by default this is turned off
|
||||||
|
* ``type`` (*str*) -- what kind of task to start in Koji. Defaults to
|
||||||
|
``live`` meaning ``koji spin-livecd`` will be used. Alternative option
|
||||||
|
is ``appliance`` corresponding to ``koji spin-appliance``.
|
||||||
|
|
||||||
Live Media Settings
|
Live Media Settings
|
||||||
===================
|
===================
|
||||||
|
@ -119,6 +119,8 @@ class LiveImagesPhase(PhaseBase):
|
|||||||
cmd["name"] = data[0].get("name", None)
|
cmd["name"] = data[0].get("name", None)
|
||||||
cmd["version"] = data[0].get("version", None)
|
cmd["version"] = data[0].get("version", None)
|
||||||
|
|
||||||
|
cmd['type'] = data[0].get('type', 'live')
|
||||||
|
|
||||||
# Specfile (for images wrapped in rpm)
|
# Specfile (for images wrapped in rpm)
|
||||||
cmd["specfile"] = data[0].get("specfile", None)
|
cmd["specfile"] = data[0].get("specfile", None)
|
||||||
|
|
||||||
@ -195,7 +197,14 @@ class CreateLiveImageThread(WorkerThread):
|
|||||||
# Non scratch build are allowed only for rpm wrapped images
|
# Non scratch build are allowed only for rpm wrapped images
|
||||||
archive = True
|
archive = True
|
||||||
target = compose.conf.get("live_target", "rhel-7.0-candidate") # compatability for hardcoded target
|
target = compose.conf.get("live_target", "rhel-7.0-candidate") # compatability for hardcoded target
|
||||||
koji_cmd = koji_wrapper.get_create_image_cmd(name, version, target, cmd["build_arch"], cmd["ks_file"], cmd["repos"], image_type="live", wait=True, archive=archive, specfile=cmd["specfile"])
|
koji_cmd = koji_wrapper.get_create_image_cmd(name, version, target,
|
||||||
|
cmd["build_arch"],
|
||||||
|
cmd["ks_file"],
|
||||||
|
cmd["repos"],
|
||||||
|
image_type=cmd['type'],
|
||||||
|
wait=True,
|
||||||
|
archive=archive,
|
||||||
|
specfile=cmd["specfile"])
|
||||||
|
|
||||||
# avoid race conditions?
|
# avoid race conditions?
|
||||||
# Kerberos authentication failed: Permission denied in replay cache code (-1765328215)
|
# Kerberos authentication failed: Permission denied in replay cache code (-1765328215)
|
||||||
|
@ -63,7 +63,7 @@ class TestLiveImagesPhase(unittest.TestCase):
|
|||||||
@mock.patch('pungi.phases.live_images.ThreadPool')
|
@mock.patch('pungi.phases.live_images.ThreadPool')
|
||||||
@mock.patch('pungi.phases.live_images.get_ks_in')
|
@mock.patch('pungi.phases.live_images.get_ks_in')
|
||||||
@mock.patch('pungi.phases.live_images.tweak_ks')
|
@mock.patch('pungi.phases.live_images.tweak_ks')
|
||||||
def test_image_build(self, tweak_ks, get_ks_in, ThreadPool):
|
def test_live_image_build(self, tweak_ks, get_ks_in, ThreadPool):
|
||||||
compose = _DummyCompose({
|
compose = _DummyCompose({
|
||||||
'live_images': [
|
'live_images': [
|
||||||
('^Client$', {
|
('^Client$', {
|
||||||
@ -99,7 +99,53 @@ class TestLiveImagesPhase(unittest.TestCase):
|
|||||||
'name': None,
|
'name': None,
|
||||||
'iso_path': '/iso_dir/amd64/Client/image-name',
|
'iso_path': '/iso_dir/amd64/Client/image-name',
|
||||||
'version': None,
|
'version': None,
|
||||||
'specfile': None},
|
'specfile': None,
|
||||||
|
'type': 'live'},
|
||||||
|
compose.variants['Client'],
|
||||||
|
'amd64'))])
|
||||||
|
|
||||||
|
@mock.patch('pungi.phases.live_images.ThreadPool')
|
||||||
|
@mock.patch('pungi.phases.live_images.get_ks_in')
|
||||||
|
@mock.patch('pungi.phases.live_images.tweak_ks')
|
||||||
|
def test_spin_appliance(self, tweak_ks, get_ks_in, ThreadPool):
|
||||||
|
compose = _DummyCompose({
|
||||||
|
'live_images': [
|
||||||
|
('^Client$', {
|
||||||
|
'amd64': {
|
||||||
|
'additional_repos': ['http://example.com/repo/'],
|
||||||
|
'repos_from': ['Everything'],
|
||||||
|
'type': 'appliance',
|
||||||
|
}
|
||||||
|
})
|
||||||
|
],
|
||||||
|
})
|
||||||
|
|
||||||
|
get_ks_in.side_effect = (lambda compose, arch, variant:
|
||||||
|
None if variant.uid != 'Client' or arch != 'amd64' else '/path/to/ks_in')
|
||||||
|
tweak_ks.return_value = '/path/to/ks_file'
|
||||||
|
|
||||||
|
phase = LiveImagesPhase(compose)
|
||||||
|
|
||||||
|
phase.run()
|
||||||
|
|
||||||
|
# assert at least one thread was started
|
||||||
|
self.assertTrue(phase.pool.add.called)
|
||||||
|
self.maxDiff = None
|
||||||
|
self.assertItemsEqual(phase.pool.queue_put.mock_calls,
|
||||||
|
[mock.call((compose,
|
||||||
|
{'ks_file': '/path/to/ks_file',
|
||||||
|
'build_arch': 'amd64',
|
||||||
|
'wrapped_rpms_path': '/iso_dir/amd64/Client',
|
||||||
|
'scratch': False,
|
||||||
|
'repos': ['/repo/amd64/Client',
|
||||||
|
'http://example.com/repo/',
|
||||||
|
'/repo/amd64/Everything'],
|
||||||
|
'label': '',
|
||||||
|
'name': None,
|
||||||
|
'iso_path': '/iso_dir/amd64/Client/image-name',
|
||||||
|
'version': None,
|
||||||
|
'specfile': None,
|
||||||
|
'type': 'appliance'},
|
||||||
compose.variants['Client'],
|
compose.variants['Client'],
|
||||||
'amd64'))])
|
'amd64'))])
|
||||||
|
|
||||||
@ -124,7 +170,8 @@ class TestCreateLiveImageThread(unittest.TestCase):
|
|||||||
'name': None,
|
'name': None,
|
||||||
'iso_path': '/iso_dir/amd64/Client/image-name',
|
'iso_path': '/iso_dir/amd64/Client/image-name',
|
||||||
'version': None,
|
'version': None,
|
||||||
'specfile': None
|
'specfile': None,
|
||||||
|
'type': 'live',
|
||||||
}
|
}
|
||||||
|
|
||||||
koji_wrapper = KojiWrapper.return_value
|
koji_wrapper = KojiWrapper.return_value
|
||||||
@ -151,6 +198,73 @@ class TestCreateLiveImageThread(unittest.TestCase):
|
|||||||
'isoinfo -R -f -i image-name | grep -v \'/TRANS.TBL$\' | sort >> image-name.manifest'
|
'isoinfo -R -f -i image-name | grep -v \'/TRANS.TBL$\' | sort >> image-name.manifest'
|
||||||
])
|
])
|
||||||
self.assertEqual(run.mock_calls, [mock.call(write_manifest_cmd)])
|
self.assertEqual(run.mock_calls, [mock.call(write_manifest_cmd)])
|
||||||
|
self.assertEqual(koji_wrapper.get_create_image_cmd.mock_calls,
|
||||||
|
[mock.call('Test', '20151203.0.t', 'rhel-7.0-candidate',
|
||||||
|
'amd64', '/path/to/ks_file',
|
||||||
|
['/repo/amd64/Client',
|
||||||
|
'http://example.com/repo/',
|
||||||
|
'/repo/amd64/Everything'],
|
||||||
|
image_type='live',
|
||||||
|
archive=False,
|
||||||
|
specfile=None,
|
||||||
|
wait=True)])
|
||||||
|
|
||||||
|
@mock.patch('shutil.copy2')
|
||||||
|
@mock.patch('pungi.phases.live_images.run')
|
||||||
|
@mock.patch('pungi.phases.live_images.KojiWrapper')
|
||||||
|
def test_process_applicance(self, KojiWrapper, run, copy2):
|
||||||
|
compose = _DummyCompose({'koji_profile': 'koji'})
|
||||||
|
pool = mock.Mock()
|
||||||
|
cmd = {
|
||||||
|
'ks_file': '/path/to/ks_file',
|
||||||
|
'build_arch': 'amd64',
|
||||||
|
'wrapped_rpms_path': '/iso_dir/amd64/Client',
|
||||||
|
'scratch': False,
|
||||||
|
'repos': ['/repo/amd64/Client',
|
||||||
|
'http://example.com/repo/',
|
||||||
|
'/repo/amd64/Everything'],
|
||||||
|
'label': '',
|
||||||
|
'name': None,
|
||||||
|
'iso_path': '/iso_dir/amd64/Client/image-name',
|
||||||
|
'version': None,
|
||||||
|
'specfile': None,
|
||||||
|
'type': 'appliance',
|
||||||
|
}
|
||||||
|
|
||||||
|
koji_wrapper = KojiWrapper.return_value
|
||||||
|
koji_wrapper.get_create_image_cmd.return_value = 'koji spin-livecd ...'
|
||||||
|
koji_wrapper.run_blocking_cmd.return_value = {
|
||||||
|
'retcode': 0,
|
||||||
|
'output': 'some output',
|
||||||
|
'task_id': 123
|
||||||
|
}
|
||||||
|
koji_wrapper.get_image_path.return_value = ['/path/to/image']
|
||||||
|
|
||||||
|
t = CreateLiveImageThread(pool)
|
||||||
|
with mock.patch('time.sleep'):
|
||||||
|
t.process((compose, cmd, compose.variants['Client'], 'amd64'), 1)
|
||||||
|
|
||||||
|
self.assertEqual(koji_wrapper.run_blocking_cmd.mock_calls,
|
||||||
|
[mock.call('koji spin-livecd ...', log_file='/a/b/log/log_file')])
|
||||||
|
self.assertEqual(koji_wrapper.get_image_path.mock_calls, [mock.call(123)])
|
||||||
|
self.assertEqual(copy2.mock_calls,
|
||||||
|
[mock.call('/path/to/image', '/iso_dir/amd64/Client/image-name')])
|
||||||
|
|
||||||
|
write_manifest_cmd = ' && '.join([
|
||||||
|
'cd /iso_dir/amd64/Client',
|
||||||
|
'isoinfo -R -f -i image-name | grep -v \'/TRANS.TBL$\' | sort >> image-name.manifest'
|
||||||
|
])
|
||||||
|
self.assertEqual(run.mock_calls, [mock.call(write_manifest_cmd)])
|
||||||
|
self.assertEqual(koji_wrapper.get_create_image_cmd.mock_calls,
|
||||||
|
[mock.call('Test', '20151203.0.t', 'rhel-7.0-candidate',
|
||||||
|
'amd64', '/path/to/ks_file',
|
||||||
|
['/repo/amd64/Client',
|
||||||
|
'http://example.com/repo/',
|
||||||
|
'/repo/amd64/Everything'],
|
||||||
|
image_type='appliance',
|
||||||
|
archive=False,
|
||||||
|
specfile=None,
|
||||||
|
wait=True)])
|
||||||
|
|
||||||
@mock.patch('shutil.copy2')
|
@mock.patch('shutil.copy2')
|
||||||
@mock.patch('pungi.phases.live_images.run')
|
@mock.patch('pungi.phases.live_images.run')
|
||||||
|
Loading…
Reference in New Issue
Block a user