package-installs : allow a list of parameters
The change Ia6f10741fa6be24b11d6991c8a6b6e07951ff68d introduced having "when:" as a list of values. However, this was actually not sufficient to express the logic required for arm64/x86_64/xenial kernel matching we wanted. Because the package name is a key, we can't have multiple entires in the package-map YAML files. This means we can't do more advanced matching and thus we need to be able to match through multiple parameters. Similar to Ia6f10741fa6be24b11d6991c8a6b6e07951ff68d we modify the matching rules to allow a list. A an example of using this is provided in the README.rst, and this same example worked through by the unit tests. This also slightly updates the matching logic to be more sequential. After each check we either continue on or log the failure and continue to the next check (rather than set a list of flags then check that at the end). This makes it much easier to understand what is being matched in the logging output from the tool. Change-Id: Idff7b067ad4255e6fc4138f7eff313a81b75c8ba
This commit is contained in:
parent
6ee2995214
commit
b71d1c60d2
@ -96,6 +96,29 @@ packages), you can use something like::
|
|||||||
You can also use a list of items in the ``when`` statement, which will
|
You can also use a list of items in the ``when`` statement, which will
|
||||||
be effectively combined with *and*.
|
be effectively combined with *and*.
|
||||||
|
|
||||||
|
If you need to filter multiple paths for a single package, you can
|
||||||
|
make the parameters a list. For example, if ``linux-image-generic``
|
||||||
|
package should be installed when ``DIB_UBUNTU_KERNEL =
|
||||||
|
linux-image-generic`` is set *except* on ``arm64`` Xenial hosts, where
|
||||||
|
we would like to install ``linux-generic-hwe-16.04`` you could use the
|
||||||
|
following:
|
||||||
|
|
||||||
|
.. code-block:: YAML
|
||||||
|
|
||||||
|
linux-image-generic:
|
||||||
|
- not-arch: arm64
|
||||||
|
when: DIB_UBUNTU_KERNEL = linux-image-generic
|
||||||
|
- arch: arm64
|
||||||
|
when:
|
||||||
|
- DIB_RELEASE != xenial
|
||||||
|
- DIB_UBUNTU_KERNEL = linux-image-generic
|
||||||
|
|
||||||
|
linux-generic-hwe-16.04:
|
||||||
|
arch: arm64
|
||||||
|
when:
|
||||||
|
- DIB_RELEASE = xenial
|
||||||
|
- DIB_UBUNTU_KERNEL = linux-image-generic
|
||||||
|
|
||||||
DEPRECATED: Adding a file under your elements pre-install.d, install.d, or
|
DEPRECATED: Adding a file under your elements pre-install.d, install.d, or
|
||||||
post-install.d directories called package-installs-<element-name> will cause
|
post-install.d directories called package-installs-<element-name> will cause
|
||||||
the list of packages in that file to be installed at the beginning of the
|
the list of packages in that file to be installed at the beginning of the
|
||||||
|
@ -76,10 +76,8 @@ def _when(statements):
|
|||||||
# No statement means install
|
# No statement means install
|
||||||
if statements is None:
|
if statements is None:
|
||||||
return True
|
return True
|
||||||
|
if not isinstance(statements, (list, tuple)):
|
||||||
if not isinstance(statements, list):
|
|
||||||
statements = [statements]
|
statements = [statements]
|
||||||
|
|
||||||
result = []
|
result = []
|
||||||
|
|
||||||
for s in statements:
|
for s in statements:
|
||||||
@ -98,7 +96,7 @@ def _when(statements):
|
|||||||
if var not in os.environ:
|
if var not in os.environ:
|
||||||
raise RuntimeError("The variable <%s> is not set" % var)
|
raise RuntimeError("The variable <%s> is not set" % var)
|
||||||
|
|
||||||
logger.debug("when eval %s%s%s against <%s>" %
|
logger.debug("... when eval %s%s%s against <%s>" %
|
||||||
(var, op, val, os.environ[var]))
|
(var, op, val, os.environ[var]))
|
||||||
|
|
||||||
if op == '=':
|
if op == '=':
|
||||||
@ -121,34 +119,50 @@ def _when(statements):
|
|||||||
def collect_data(data, objs, element_name):
|
def collect_data(data, objs, element_name):
|
||||||
for pkg_name, params in objs.items():
|
for pkg_name, params in objs.items():
|
||||||
if not params:
|
if not params:
|
||||||
params = {}
|
params = [{}]
|
||||||
phase = params.get('phase', 'install.d')
|
if not isinstance(params, (list, tuple)):
|
||||||
|
params = [params]
|
||||||
|
|
||||||
|
for param in params:
|
||||||
|
logger.debug("Considering %s/%s param:%s" %
|
||||||
|
(element_name, pkg_name, param))
|
||||||
|
phase = param.get('phase', 'install.d')
|
||||||
installs = ["install"]
|
installs = ["install"]
|
||||||
if 'uninstall' in params:
|
if 'uninstall' in param:
|
||||||
installs = ["uninstall"]
|
installs = ["uninstall"]
|
||||||
if 'build-only' in params:
|
if 'build-only' in param:
|
||||||
installs = ["install", "uninstall"]
|
installs = ["install", "uninstall"]
|
||||||
|
|
||||||
# Filter out incorrect installtypes
|
# Filter out incorrect installtypes
|
||||||
installtype = params.get('installtype', None)
|
installtype = param.get('installtype', None)
|
||||||
elem_installtype = get_element_installtype(element_name)
|
elem_installtype = get_element_installtype(element_name)
|
||||||
valid_installtype = (installtype is None or
|
valid_installtype = (installtype is None or
|
||||||
installtype == elem_installtype)
|
installtype == elem_installtype)
|
||||||
valid_arch = _valid_for_arch(pkg_name, params.get('arch', None),
|
if not valid_installtype:
|
||||||
params.get('not-arch', None))
|
logger.debug("... skipping due to installtype")
|
||||||
dib_py_version = str(params.get('dib_python_version', ''))
|
continue
|
||||||
|
|
||||||
|
valid_arch = _valid_for_arch(pkg_name, param.get('arch', None),
|
||||||
|
param.get('not-arch', None))
|
||||||
|
if not valid_arch:
|
||||||
|
logger.debug("... skipping due to arch match")
|
||||||
|
continue
|
||||||
|
|
||||||
|
dib_py_version = str(param.get('dib_python_version', ''))
|
||||||
dib_py_version_env = os.environ.get('DIB_PYTHON_VERSION', '')
|
dib_py_version_env = os.environ.get('DIB_PYTHON_VERSION', '')
|
||||||
valid_dib_python_version = (dib_py_version == '' or
|
valid_dib_python_version = (dib_py_version == '' or
|
||||||
dib_py_version == dib_py_version_env)
|
dib_py_version == dib_py_version_env)
|
||||||
|
if not valid_dib_python_version:
|
||||||
# True means install, false skip
|
logger.debug("... skipping due to python version")
|
||||||
if _when(params.get('when', None)) is False:
|
continue
|
||||||
logger.debug("Skipped due to when: %s/%s" %
|
|
||||||
(element_name, pkg_name))
|
# True means install, false skip
|
||||||
|
if _when(param.get('when', None)) is False:
|
||||||
|
logger.debug("... skipped due to when: failures")
|
||||||
continue
|
continue
|
||||||
|
|
||||||
if valid_installtype and valid_arch and valid_dib_python_version:
|
|
||||||
for install in installs:
|
for install in installs:
|
||||||
|
logger.debug("... installing for '%s'" % install)
|
||||||
data[phase][install].append((pkg_name, element_name))
|
data[phase][install].append((pkg_name, element_name))
|
||||||
|
|
||||||
return data
|
return data
|
||||||
|
@ -98,6 +98,55 @@ class TestPackageInstall(base.BaseTestCase):
|
|||||||
|
|
||||||
self.assertThat(result, IsMatchingInstallList(expected))
|
self.assertThat(result, IsMatchingInstallList(expected))
|
||||||
|
|
||||||
|
kernel_objs = {
|
||||||
|
'linux-image-generic': [
|
||||||
|
{
|
||||||
|
'not-arch': 'arm64',
|
||||||
|
'when': 'DIB_UBUNTU_KERNEL = linux-image-generic',
|
||||||
|
},
|
||||||
|
{
|
||||||
|
'arch': 'arm64',
|
||||||
|
'when': (
|
||||||
|
'DIB_RELEASE != xenial',
|
||||||
|
'DIB_UBUNTU_KERNEL = linux-image-generic',
|
||||||
|
)
|
||||||
|
},
|
||||||
|
],
|
||||||
|
'linux-generic-hwe-16.04': {
|
||||||
|
'arch': 'arm64',
|
||||||
|
'when': (
|
||||||
|
'DIB_RELEASE = xenial',
|
||||||
|
'DIB_UBUNTU_KERNEL = linux-image-generic',
|
||||||
|
)
|
||||||
|
},
|
||||||
|
}
|
||||||
|
|
||||||
|
def _test_kernel_objs_match(self, arch, release, expected):
|
||||||
|
with mock.patch.object(os, 'environ',
|
||||||
|
dict(ARCH=arch,
|
||||||
|
DIB_UBUNTU_KERNEL='linux-image-generic',
|
||||||
|
DIB_RELEASE=release,
|
||||||
|
**os.environ)):
|
||||||
|
result = installs_squash.collect_data(
|
||||||
|
self.final_dict, self.kernel_objs, 'test_element')
|
||||||
|
|
||||||
|
expected = {
|
||||||
|
'install.d': {
|
||||||
|
'install': [(expected, 'test_element')]
|
||||||
|
}
|
||||||
|
}
|
||||||
|
self.assertThat(result, IsMatchingInstallList(expected))
|
||||||
|
|
||||||
|
def test_param_list_x86(self):
|
||||||
|
self._test_kernel_objs_match('x86_64', 'focal', 'linux-image-generic')
|
||||||
|
|
||||||
|
def test_param_list_arm64_xenial(self):
|
||||||
|
self._test_kernel_objs_match('arm64', 'xenial',
|
||||||
|
'linux-generic-hwe-16.04')
|
||||||
|
|
||||||
|
def test_param_list_arm64_focal(self):
|
||||||
|
self._test_kernel_objs_match('arm64', 'focal', 'linux-image-generic')
|
||||||
|
|
||||||
@mock.patch.object(os, 'environ', dict(DIB_FEATURE='1', **os.environ))
|
@mock.patch.object(os, 'environ', dict(DIB_FEATURE='1', **os.environ))
|
||||||
def test_skip_when(self):
|
def test_skip_when(self):
|
||||||
'''Exercise the when flag'''
|
'''Exercise the when flag'''
|
||||||
|
Loading…
Reference in New Issue
Block a user