1#!/usr/bin/env python3 2# Copyright 2020 The ChromiumOS Authors 3# Use of this source code is governed by a BSD-style license that can be 4# found in the LICENSE file. 5 6"""Chroot helper functions.""" 7 8import os 9from pathlib import Path 10import subprocess 11from typing import Iterable, List, Union 12 13 14def InChroot() -> bool: 15 """Returns True if currently in the chroot.""" 16 return "CROS_WORKON_SRCROOT" in os.environ 17 18 19def VerifyInsideChroot() -> None: 20 """Checks whether the script invoked was executed in the chroot. 21 22 Raises: 23 AssertionError: The script was run outside the chroot. 24 """ 25 26 assert InChroot(), "Script should be run inside the chroot." 27 28 29def VerifyOutsideChroot() -> None: 30 """Checks whether the script invoked was executed in the chroot. 31 32 Raises: 33 AssertionError: The script was run inside the chroot. 34 """ 35 36 assert not InChroot(), "Script should be run outside the chroot." 37 38 39def VerifyChromeOSRoot(chromeos_root: Union[Path, str]) -> None: 40 """Checks whether the path actually points to ChromiumOS checkout root. 41 42 Raises: 43 AssertionError: The path is not ChromiumOS checkout root. 44 """ 45 46 subdir = "src/third_party/chromiumos-overlay" 47 path = Path(chromeos_root).expanduser() / subdir 48 msg = f"Wrong ChromeOS path. No {subdir} directory in {chromeos_root} ." 49 assert path.is_dir(), msg 50 51 52def FindChromeOSRootAbove(chromeos_tree_path: Path) -> Path: 53 """Returns the root of a ChromeOS tree, given a path in said tree. 54 55 May return `chromeos_tree_path`, if that's already the root of the tree. 56 57 Raises: 58 ValueError if the given path is not in a ChromeOS tree. 59 """ 60 if (chromeos_tree_path / ".repo").exists(): 61 return chromeos_tree_path 62 63 for parent in chromeos_tree_path.parents: 64 if (parent / ".repo").exists(): 65 return parent 66 raise ValueError(f"{chromeos_tree_path} is not in a repo checkout") 67 68 69def GetChrootEbuildPaths( 70 chromeos_root: Union[Path, str], 71 packages: Iterable[str], 72 chroot_name: str = "chroot", 73 out_dir: str = "out", 74) -> List[str]: 75 """Gets the chroot path(s) of the package(s). 76 77 Args: 78 chromeos_root: The absolute path to the chromeos tree to use. 79 packages: A list of a package/packages to 80 be used to find their chroot path. 81 chroot_name: name of the chroot to enter. 82 out_dir: name of the out directory for the chroot. 83 84 Returns: 85 A list of chroot paths of the packages' ebuild files. 86 87 Raises: 88 ValueError: Failed to get the chroot path of a package. 89 """ 90 91 chroot_paths = [] 92 93 cros_sdk = [ 94 "cros_sdk", 95 f"--chroot={chroot_name}", 96 f"--out-dir={out_dir}", 97 ] 98 99 # Find the chroot path for each package's ebuild. 100 for package in packages: 101 chroot_path = subprocess.check_output( 102 cros_sdk + ["--", "equery", "w", package], 103 cwd=chromeos_root, 104 encoding="utf-8", 105 ) 106 chroot_paths.append(chroot_path.strip()) 107 108 return chroot_paths 109 110 111def ConvertChrootPathsToAbsolutePaths( 112 chromeos_root: str, 113 chroot_paths: List[str], 114) -> List[str]: 115 """Converts the chroot path(s) to absolute symlink path(s). 116 117 Args: 118 chromeos_root: The absolute path to the chroot. 119 chroot_paths: A list of chroot paths to convert to absolute paths. 120 121 Returns: 122 A list of absolute path(s). 123 124 Raises: 125 ValueError: Invalid prefix for the chroot path or 126 invalid chroot paths were provided. 127 """ 128 129 abs_paths = [] 130 chroot_prefix = "/mnt/host/source/" 131 # Iterate through the chroot paths. 132 # For each chroot file path, remove '/mnt/host/source/' prefix 133 # and combine the chroot path with the result and add it to the list. 134 for chroot_path in chroot_paths: 135 if not chroot_path.startswith(chroot_prefix): 136 raise ValueError( 137 "Invalid prefix for the chroot path: %s" % chroot_path 138 ) 139 rel_path = chroot_path[len(chroot_prefix) :] 140 # combine the chromeos root path + '/src/...' 141 abs_path = os.path.join(chromeos_root, rel_path) 142 abs_paths.append(abs_path) 143 return abs_paths 144