image-build: Support repo/install_tree as path

If a repo or install tree is specified as an absolute path on the local
filesystem, we should either translate it using the configured mappings,
or if no mapping matches, it should be return unchanged. A variant name
can not start with a slash, so attempting that translation does not make
much sense.

JIRA: COMPOSE-3290
Signed-off-by: Lubomír Sedlář <lsedlar@redhat.com>
This commit is contained in:
Lubomír Sedlář 2019-02-21 10:00:03 +01:00
parent 8c82cfc1c7
commit 3efcfede6a
5 changed files with 81 additions and 0 deletions

View File

@ -1227,6 +1227,14 @@ Image Build Settings
based on current variant. You can use ``install_tree_from`` key to use based on current variant. You can use ``install_tree_from`` key to use
install tree from another variant. install tree from another variant.
Both the install tree and repos can use one of following formats:
* URL to the location
* name of variant in the current compose
* absolute path on local filesystem (which will be translated using
configured mappings or used unchanged, in which case you have to ensure
the koji builders can access it)
You can set either a single format, or a list of formats. For available You can set either a single format, or a list of formats. For available
values see help output for ``koji image-build`` command. values see help output for ``koji image-build`` command.

View File

@ -60,7 +60,12 @@ class ImageBuildPhase(base.PhaseLoggerMixin, base.ImageConfigMixin, base.ConfigG
install_tree_from = image_conf.pop('install_tree_from', variant.uid) install_tree_from = image_conf.pop('install_tree_from', variant.uid)
if '://' in install_tree_from: if '://' in install_tree_from:
# It's a URL, return it unchanged
return install_tree_from return install_tree_from
if install_tree_from.startswith("/"):
# It's a path on local filesystem.
return translate_path(self.compose, install_tree_from)
install_tree_source = self.compose.all_variants.get(install_tree_from) install_tree_source = self.compose.all_variants.get(install_tree_from)
if not install_tree_source: if not install_tree_source:
raise RuntimeError( raise RuntimeError(

View File

@ -731,6 +731,9 @@ def get_repo_url(compose, repo, arch='$basearch'):
repo = repo['baseurl'] repo = repo['baseurl']
except KeyError: except KeyError:
raise RuntimeError('Baseurl is required in repo dict %s' % str(repo)) raise RuntimeError('Baseurl is required in repo dict %s' % str(repo))
if repo.startswith("/"):
# It's an absolute path, translate it and return it
return translate_path(compose, repo)
if '://' not in repo: if '://' not in repo:
# this is a variant name # this is a variant name
if compose is not None: if compose is not None:

View File

@ -313,6 +313,67 @@ class TestImageBuildPhase(PungiTestCase):
"scratch": False, "scratch": False,
}) })
@mock.patch("pungi.phases.image_build.ThreadPool")
def test_image_build_set_install_tree_from_path(self, ThreadPool):
compose = DummyCompose(self.topdir, {
"image_build": {
"^Server$": [
{
"image-build": {
"format": ["docker"],
"name": "Fedora-Docker-Base",
"target": "f24",
"version": "Rawhide",
"ksurl": "git://git.fedorahosted.org/git/spin-kickstarts.git",
"kickstart": "fedora-docker-base.ks",
"distro": "Fedora-20",
"disk_size": 3,
"arches": ["x86_64"],
"install_tree_from": "/my/tree",
}
}
]
},
"koji_profile": "koji",
"translate_paths": [("/my", "http://example.com")],
})
self.assertValidConfig(compose.conf)
phase = ImageBuildPhase(compose)
phase.run()
# assert at least one thread was started
self.assertTrue(phase.pool.add.called)
self.assertTrue(phase.pool.queue_put.called_once)
args, kwargs = phase.pool.queue_put.call_args
self.assertEqual(args[0][0], compose)
self.assertDictEqual(args[0][1], {
"image_conf": {
"image-build": {
"install_tree": "http://example.com/tree",
"kickstart": "fedora-docker-base.ks",
"format": ["docker"],
"repo": self.topdir + "/compose/Server/$arch/os",
"variant": compose.variants["Server"],
"target": "f24",
"disk_size": 3,
"name": "Fedora-Docker-Base",
"arches": ["x86_64"],
"version": "Rawhide",
"ksurl": "git://git.fedorahosted.org/git/spin-kickstarts.git",
"distro": "Fedora-20",
}
},
"conf_file": self.topdir + "/work/image-build/Server/docker_Fedora-Docker-Base_x86_64.cfg",
"image_dir": self.topdir + "/compose/Server/%(arch)s/images",
"relative_image_dir": "Server/%(arch)s/images",
"link_type": "hardlink-or-copy",
"scratch": False,
})
@mock.patch('pungi.phases.image_build.ThreadPool') @mock.patch('pungi.phases.image_build.ThreadPool')
def test_image_build_set_extra_repos(self, ThreadPool): def test_image_build_set_extra_repos(self, ThreadPool):
compose = DummyCompose(self.topdir, { compose = DummyCompose(self.topdir, {

View File

@ -626,6 +626,10 @@ class GetRepoFuncsTestCase(unittest.TestCase):
url = util.get_repo_url(self.compose, 'http://example.com/repo') url = util.get_repo_url(self.compose, 'http://example.com/repo')
self.assertEqual(url, 'http://example.com/repo') self.assertEqual(url, 'http://example.com/repo')
def test_get_repo_url_from_path(self):
url = util.get_repo_url(self.compose, os.path.join(self.tmp_dir, "repo"))
self.assertEqual(url, "http://example.com/repo")
def test_get_repo_url_from_variant_uid(self): def test_get_repo_url_from_variant_uid(self):
url = util.get_repo_url(self.compose, 'Server') url = util.get_repo_url(self.compose, 'Server')
self.assertEqual(url, 'http://example.com/RHEL-8.0-20180101.n.0/compose/Server/$basearch/os') self.assertEqual(url, 'http://example.com/RHEL-8.0-20180101.n.0/compose/Server/$basearch/os')