portage_utils: add sysroot support to all portageq helpers
We have APIs for operating on sysroots directly rather than going
through |board| all the time, so extend the portageq helpers to
support either method of tool lookup.
BUG=chromium:401332, chromium:1019728
TEST=CQ passes
Change-Id: I3e93f93667a04dd674212b7a83ba311a98c88c5f
Reviewed-on: https://chromium-review.googlesource.com/c/chromiumos/chromite/+/2309711
Commit-Queue: Mike Frysinger <vapier@chromium.org>
Tested-by: Mike Frysinger <vapier@chromium.org>
Reviewed-by: Alex Klein <saklein@chromium.org>
diff --git a/cros/test/image_test.py b/cros/test/image_test.py
index caf9b55..f80f504 100644
--- a/cros/test/image_test.py
+++ b/cros/test/image_test.py
@@ -149,7 +149,8 @@
"""Fail if any blacklisted packages are installed."""
for package in self.BLACKLISTED_PACKAGES:
self.assertFalse(
- portage_util.PortageqHasVersion(package, root=image_test_lib.ROOT_A))
+ portage_util.PortageqHasVersion(
+ package, sysroot=image_test_lib.ROOT_A))
def TestBlacklistedFiles(self):
"""Fail if any blacklisted files exist."""
@@ -219,8 +220,8 @@
)
def _IsPackageMerged(self, package_name):
- has_version = portage_util.PortageqHasVersion(package_name,
- root=image_test_lib.ROOT_A)
+ has_version = portage_util.PortageqHasVersion(
+ package_name, sysroot=image_test_lib.ROOT_A)
if has_version:
logging.info('Package is available: %s', package_name)
else:
diff --git a/lib/portage_util.py b/lib/portage_util.py
index c34545b..93340d3 100644
--- a/lib/portage_util.py
+++ b/lib/portage_util.py
@@ -2262,12 +2262,29 @@
"""Portageq command error."""
-def _Portageq(command, board=None, **kwargs):
+def _GetPortageq(board=None, sysroot=None):
+ """Return the portageq tool to use."""
+ if sysroot is None and board is None:
+ return 'portageq'
+
+ # Prefer the sysroot tool if it exists.
+ if sysroot is None:
+ sysroot = cros_build_lib.GetSysroot(board)
+ tool = cros_build_lib.GetSysrootToolPath(sysroot, 'portageq')
+ if os.path.exists(tool):
+ return tool
+
+ # Fallback to the general PATH wrappers if possible.
+ return 'portageq' if board is None else 'portageq-%s' % board
+
+
+def _Portageq(command, board=None, sysroot=None, **kwargs):
"""Run a portageq command.
Args:
command: list - Portageq command to run excluding portageq.
board: [str] - Specific board to query.
+ sysroot: The sysroot to query.
kwargs: Additional run arguments.
Returns:
@@ -2282,29 +2299,31 @@
kwargs.setdefault('encoding', 'utf-8')
kwargs.setdefault('enter_chroot', True)
- portageq = 'portageq-%s' % board if board else 'portageq'
- return cros_build_lib.run([portageq] + command, **kwargs)
+ return cros_build_lib.run([_GetPortageq(board, sysroot)] + command, **kwargs)
-def PortageqBestVisible(atom, board=None, pkg_type='ebuild', cwd=None):
+def PortageqBestVisible(atom, board=None, sysroot=None, pkg_type='ebuild',
+ cwd=None):
"""Get the best visible ebuild CPV for the given atom.
Args:
atom: Portage atom.
board: Board to look at. By default, look in chroot.
+ sysroot: The sysroot to query.
pkg_type: Package type (ebuild, binary, or installed).
cwd: Path to use for the working directory for run.
Returns:
A CPV object.
"""
- root = cros_build_lib.GetSysroot(board=board)
- cmd = ['best_visible', root, pkg_type, atom]
- result = _Portageq(cmd, board=board, cwd=cwd)
+ if sysroot is None:
+ sysroot = cros_build_lib.GetSysroot(board=board)
+ cmd = ['best_visible', sysroot, pkg_type, atom]
+ result = _Portageq(cmd, board=board, sysroot=sysroot, cwd=cwd)
return SplitCPV(result.output.strip())
-def PortageqEnvvar(variable, board=None, allow_undefined=False):
+def PortageqEnvvar(variable, board=None, sysroot=None, allow_undefined=False):
"""Run portageq envvar for a single variable.
Like PortageqEnvvars, but returns the value of the single variable rather
@@ -2313,6 +2332,7 @@
Args:
variable: str - The variable to retrieve.
board: str|None - See PortageqEnvvars.
+ sysroot: The sysroot to query.
allow_undefined: bool - See PortageqEnvvars.
Returns:
@@ -2328,17 +2348,18 @@
elif not variable:
raise ValueError('Variable must not be empty.')
- result = PortageqEnvvars([variable], board=board,
+ result = PortageqEnvvars([variable], board=board, sysroot=sysroot,
allow_undefined=allow_undefined)
return result[variable]
-def PortageqEnvvars(variables, board=None, allow_undefined=False):
+def PortageqEnvvars(variables, board=None, sysroot=None, allow_undefined=False):
"""Run portageq envvar for the given variables.
Args:
variables: List[str] - Variables to query.
board: str|None - Specific board to query.
+ sysroot: The sysroot to query.
allow_undefined: bool - True to quietly allow empty strings when the
variable is undefined. False to raise an error.
@@ -2358,7 +2379,8 @@
return {}
try:
- result = _Portageq(['envvar', '-v'] + variables, board=board)
+ result = _Portageq(['envvar', '-v'] + variables, board=board,
+ sysroot=sysroot)
except cros_build_lib.RunCommandError as e:
if e.result.returncode != 1:
# Actual error running command, raise.
@@ -2374,13 +2396,13 @@
return key_value_store.LoadData(result.output, multiline=True)
-def PortageqHasVersion(category_package, root='/', board=None):
+def PortageqHasVersion(category_package, board=None, sysroot=None):
"""Run portageq has_version.
Args:
category_package: str - The atom whose version is to be verified.
- root: str - Root directory to consider.
board: str|None - Specific board to query.
+ sysroot: str - Root directory to consider.
Returns:
bool
@@ -2388,14 +2410,16 @@
Raises:
cros_build_lib.RunCommandError when the command fails to run.
"""
+ if sysroot is None:
+ sysroot = cros_build_lib.GetSysroot(board=board)
# Exit codes 0/1+ indicate "have"/"don't have".
# Normalize them into True/False values.
- result = _Portageq(['has_version', root, category_package], board=board,
- check=False)
+ result = _Portageq(['has_version', sysroot, category_package], board=board,
+ sysroot=sysroot, check=False)
return not result.returncode
-def PortageqMatch(atom, board=None):
+def PortageqMatch(atom, board=None, sysroot=None):
"""Run portageq match.
Find the full category/package-version for the specified atom.
@@ -2403,11 +2427,14 @@
Args:
atom: str - Portage atom.
board: str|None - Specific board to query.
+ sysroot: The sysroot to query.
Returns:
CPV|None
"""
- result = _Portageq(['match', '/', atom], board=board)
+ if sysroot is None:
+ sysroot = cros_build_lib.GetSysroot(board=board)
+ result = _Portageq(['match', sysroot, atom], board=board, sysroot=sysroot)
return SplitCPV(result.output.strip()) if result.output else None