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