diff --git a/.github/scripts/install-slices/deb-requirements.txt b/.github/scripts/install-slices/deb-requirements.txt deleted file mode 100644 index eabfeb22c..000000000 --- a/.github/scripts/install-slices/deb-requirements.txt +++ /dev/null @@ -1,2 +0,0 @@ -devscripts -python3-apt diff --git a/.github/scripts/install-slices/install_slices.py b/.github/scripts/install-slices/install_slices.py deleted file mode 100755 index 3bdcee24d..000000000 --- a/.github/scripts/install-slices/install_slices.py +++ /dev/null @@ -1,402 +0,0 @@ -#!/usr/bin/python3 - -""" -Verify chisel slice definition files by installing the slices. - -Usage ------ -install_slices [-h] --arch ARCH --release RELEASE [--dry-run] - [--ensure-existence] [--ignore-missing] [file ...] - -positional arguments: - file Chisel slice definition file(s) - -options: - -h, --help show this help message and exit - --arch ARCH Package architecture - --release RELEASE chisel-releases branch name or directory - --dry-run Perform dry run: do not actually install the slices - --ensure-existence Each package must exist in the archive for at least one architecture - --ignore-missing Ignore arch-specific package not found in archive errors -""" - -import argparse -from apt.debfile import DebPackage -from dataclasses import dataclass -import logging -import magic -import os -import pathlib -import subprocess -import tempfile -import sys - -import apt_pkg -import requests -import yaml - - -CHISEL_PKG_CACHE = pathlib.Path.home() / ".cache/chisel/sha256" - - -class MissingCopyright(Exception): - pass - - -def configure_logging() -> None: - """ - Configure the logging options for this script. - """ - logging.basicConfig( - format="%(levelname)s: %(message)s", - level=logging.INFO, - ) - - -def parse_args() -> argparse.Namespace: - """ - Parse CLI args passed to this script. - """ - parser = argparse.ArgumentParser( - description="Verify slice definition files by installing the slices", - ) - parser.add_argument( - "--arch", - required=True, - help="Package architecture", - ) - parser.add_argument( - "--release", - required=True, - help="chisel-releases branch name or directory", - ) - parser.add_argument( - "--dry-run", - required=False, - action="store_true", - help="Perform dry run: do not actually install the slices", - ) - parser.add_argument( - "--ensure-existence", - required=False, - action="store_true", - help="Each package must exist in the archive for at least one architecture", - ) - parser.add_argument( - "--ignore-missing", - required=False, - action="store_true", - help="Ignore arch-specific package not found in archive errors", - ) - parser.add_argument( - "files", - metavar="file", - help="Chisel slice definition file(s)", - nargs="*", - ) - return parser.parse_args() - - -@dataclass -class Archive: - """ - Minimal data class replicating ubuntu archive in chisel.yaml. - """ - - version: str - components: list[str] - suites: list[str] - - -def parse_archive(release: str) -> Archive: - """ - Parse the "ubuntu" archive from the chisel.yaml file of a release. - The chisel.yaml file has the following structure: - ... - archives: - ubuntu: - version: 22.04 - components: [main, universe] - suites: [jammy, jammy-security, jammy-updates] - ... - ... - """ - logging.debug("Parsing ubuntu archive info...") - # (download and) parse chisel.yaml for ubuntu archive info - try: - if "/" in release: - filepath = os.path.join(release, "chisel.yaml") - with open(filepath, "r", encoding="utf-8") as stream: - data = yaml.safe_load(stream) - else: - base_url = "https://raw.githubusercontent.com/canonical/chisel-releases" - req_url = f"{base_url}/{release}/chisel.yaml" - response = requests.get(req_url, timeout=30) - response.raise_for_status() - data = yaml.safe_load(response.content) - except yaml.YAMLError as e: - logging.error("chisel.yaml: %s", e) - sys.exit(1) - # load the yaml data into Archive - archive_data = data["archives"]["ubuntu"] - version = archive_data["version"] - if isinstance(version, float): - version = f"{version:.2f}" - archive = Archive(str(version), archive_data["components"], archive_data["suites"]) - return archive - - -@dataclass -class Package: - """ - Minimal data class to store package info. - """ - - package: str - slices: list[str] - - -def full_slice_name(pkg: str, slice: str) -> str: - """ - Return the full slice name in "pkg_slice" format. - """ - return f"{pkg}_{slice}" - - -def parse_package(filepath: str) -> Package: - """ - Parse a slice definition file and return the Package. - """ - logging.debug("Parsing %s...", filepath) - with open(filepath, "r", encoding="utf-8") as stream: - try: - data = yaml.safe_load(stream) - except yaml.YAMLError as e: - logging.error("%s: %s", filepath, e) - sys.exit(1) - try: - package = data["package"] - slices = list(data["slices"].keys()) - slices = sorted(slices) - except KeyError as e: - logging.error("%s: key %s not found", filepath, e) - sys.exit(1) - pkg = Package(package, slices) - return pkg - - -def query_package_existence( - packages: list[str], - archive: Archive, - arch: list[str] | None = None, -) -> tuple[list[str], list[str]]: - """ - Check which packages exist in the archive. Return a list of packages - that exist and another list for which do not. - """ - # Prepare cmd. - args = ["rmadison"] - if arch and len(arch) > 0: - args += ["--architecture", ",".join(arch)] - if len(archive.components) > 0: - args += ["--component", ",".join(archive.components)] - if len(archive.suites) > 0: - args += ["--suite", ",".join(archive.suites)] - args.append(" ".join(packages)) - # Query the archives using rmadison. - logging.debug("Querying the archives for packages...") - logging.debug("Executing %s", " ".join(args)) - res = subprocess.run(args, capture_output=True, text=True, check=False) - if res.returncode != 0: - logging.error("Failed to query the archives %d", res.returncode) - sys.exit(res.returncode) - output = res.stdout.rstrip() - logging.debug("Archive query output:\n%s", output) - # Parse the output for available packages. - found = [] - for line in output.split("\n"): - line = line.strip() - if line == "": - continue - pkg = line.split("|")[0].strip() - found.append(pkg) - found = list(set(found)) - missing = list(set(packages) - set(found)) - return sorted(found), sorted(missing) - - -def ensure_package_existence(packages: list[str], archive: Archive) -> None: - """ - Ensure that packages exist in the archive for any arch. - """ - logging.info("Ensuring packages existence in ubuntu-%s archive...", archive.version) - _, missing = query_package_existence(packages, archive) - if len(missing) > 0: - logging.error( - "The following packages do not exist for ubuntu-%s:\n%s", - archive.version, - "\n".join(f" - {p}" for p in missing), - ) - sys.exit(1) - - -def ignore_missing_packages( - packages: list[Package], - arch: str, - release: str, -) -> tuple[list[Package], list[Package]]: - """ - Filter the packages that do not exist in the archive for [arch, release]. - """ - package_names = [p.package for p in packages] - archive = parse_archive(release) - found, _ = query_package_existence(package_names, archive, arch=[arch]) - # - logging.info("Ignoring missing packages in ubuntu-%s/%s...", archive.version, arch) - filtered = [] - ignored = [] - for p in packages: - if p.package in found: - filtered.append(p) - else: - ignored.append(p) - return filtered, ignored - - -def install_slice( - pkg: str, slice: str, arch: str, release: str, missing_copyright: set -) -> None: - """ - Install the slice by running "chisel cut". - """ - slice_name = full_slice_name(pkg, slice) - logging.info("Installing %s on %s...", slice_name, arch) - with tempfile.TemporaryDirectory() as tmpfs: - res = subprocess.run( - args=[ - "chisel", - "cut", - "--arch", - arch, - "--release", - release, - "--root", - tmpfs, - slice_name, - ], - capture_output=True, - text=True, - check=False, - ) - if res.returncode != 0: - logging.error( - "==============================================\n%s", - res.stderr.rstrip(), - ) - sys.exit(res.returncode) - # Check if the copyright file has been installed with this slice - copyright_file = pathlib.Path(f"{tmpfs}/usr/share/doc/{pkg}/copyright") - if not copyright_file.is_file() and not copyright_file.is_symlink(): - missing_copyright.add(slice_name) - - -def deb_has_copyright_file(pkg: str) -> bool: - """ - Checks if a deb's contents comprise a copyright file - - NOTE: this is a temporary and convoluted implementation, as at the moment - we don't have an easy and reliable way to check which deb was used for - the installation (at least not without duplicating a some of the Chisel - codebase). - - TODO: update this function once the Chisel DB is available, as the pkg - SHAs will be available from the DB itself. - """ - for sha_file in pathlib.Path(CHISEL_PKG_CACHE).rglob("*"): - try: - sha_type = magic.from_file(str(sha_file), mime=True) - except: - # Ignore any other kind - continue - - if sha_type and "debian.binary-package" in sha_type: - deb_path = str(pathlib.Path(CHISEL_PKG_CACHE / sha_file)) - sha_pkg = os.popen(f"dpkg-deb -f {deb_path} Package").read().strip() - - if sha_pkg == pkg: - deb = DebPackage(deb_path) - return f"usr/share/doc/{pkg}/copyright" in deb.filelist - - return False - - -def main() -> None: - """ - The main function -- execution should start from here. - """ - configure_logging() - cli_args = parse_args() - # Parse slice definition files. - packages = [] - for file in cli_args.files: - pkg = parse_package(file) - packages.append(pkg) - # Ensure package existence for at least one architecture. This means that - # each package must be present in the archive for at least one of the - # architectures. - if cli_args.ensure_existence: - archive = parse_archive(cli_args.release) - ensure_package_existence([p.package for p in packages], archive) - # Ignore packages who do not exist in the archive for this particular - # architecture. - if cli_args.ignore_missing: - packages, ignored = ignore_missing_packages( - packages, cli_args.arch, cli_args.release - ) - if len(ignored) > 0: - logging.info("The following packages will be IGNORED:") - for pkg in ignored: - logging.info(" - %s", pkg.package) - # - if len(packages) > 0: - logging.info("Slices of the following packages will be INSTALLED:") - for pkg in packages: - logging.info(" - %s", pkg.package) - else: - logging.info("No slices will be installed.") - return - # Install the slices in each package. - for pkg in packages: - # Keep track of whether the copyright file is installed on every "cut" - # This should always be the case, whether enforced by a global "essential" - # or Chisel itself. Exception: the copyright file will not be installed - # if it doesn't exist in the deb itself. - missing_copyright = set() - for slice in pkg.slices: - if cli_args.dry_run: - logging.info( - "Installing %s on %s... (--dry-run)", - full_slice_name(pkg.package, slice), - cli_args.arch, - ) - else: - install_slice( - pkg.package, - slice, - cli_args.arch, - cli_args.release, - missing_copyright, - ) - - if len(missing_copyright) > 0: - # Does the copyright file exist in the deb? - if deb_has_copyright_file(pkg.package): - err = "{} has a copyright file but it wasn't installed with: {}".format( - pkg.package, - ",".join(missing_copyright), - ) - raise MissingCopyright(err) - - -if __name__ == "__main__": - main() diff --git a/.github/scripts/install-slices/requirements.txt b/.github/scripts/install-slices/requirements.txt deleted file mode 100644 index e6fdf129a..000000000 --- a/.github/scripts/install-slices/requirements.txt +++ /dev/null @@ -1,3 +0,0 @@ -python-magic -pyyaml -requests diff --git a/.github/scripts/install-slices/test_install_slices.py b/.github/scripts/install-slices/test_install_slices.py deleted file mode 100644 index d08c68a1b..000000000 --- a/.github/scripts/install-slices/test_install_slices.py +++ /dev/null @@ -1,295 +0,0 @@ -#!/usr/bin/python3 - -""" -Tests for install_slices.py script -""" - -import logging -import os -import tempfile -import unittest -import unittest.mock - -from install_slices import ( - CHISEL_PKG_CACHE, - Package, - Archive, - parse_archive, - full_slice_name, - parse_package, - query_package_existence, - ensure_package_existence, - ignore_missing_packages, - install_slice, - deb_has_copyright_file, - main, -) - - -# Default archive for testing. Copied from the ubuntu-22.04 release. -DEFAULT_CHISEL_YAML = """ -format: v1 - -archives: - ubuntu: - version: 22.04 - components: [main, universe] - suites: [jammy, jammy-security, jammy-updates] - public-keys: [ubuntu-archive-key-2018] - -public-keys: - # Ubuntu Archive Automatic Signing Key (2018) - # rsa4096/f6ecb3762474eda9d21b7022871920d1991bc93c 2018-09-17T15:01:46Z - ubuntu-archive-key-2018: - id: "871920D1991BC93C" - armor: | - -----BEGIN PGP PUBLIC KEY BLOCK----- - - mQINBFufwdoBEADv/Gxytx/LcSXYuM0MwKojbBye81s0G1nEx+lz6VAUpIUZnbkq - dXBHC+dwrGS/CeeLuAjPRLU8AoxE/jjvZVp8xFGEWHYdklqXGZ/gJfP5d3fIUBtZ - HZEJl8B8m9pMHf/AQQdsC+YzizSG5t5Mhnotw044LXtdEEkx2t6Jz0OGrh+5Ioxq - X7pZiq6Cv19BohaUioKMdp7ES6RYfN7ol6HSLFlrMXtVfh/ijpN9j3ZhVGVeRC8k - KHQsJ5PkIbmvxBiUh7SJmfZUx0IQhNMaDHXfdZAGNtnhzzNReb1FqNLSVkrS/Pns - AQzMhG1BDm2VOSF64jebKXffFqM5LXRQTeqTLsjUbbrqR6s/GCO8UF7jfUj6I7ta - LygmsHO/JD4jpKRC0gbpUBfaiJyLvuepx3kWoqL3sN0LhlMI80+fA7GTvoOx4tpq - VlzlE6TajYu+jfW3QpOFS5ewEMdL26hzxsZg/geZvTbArcP+OsJKRmhv4kNo6Ayd - yHQ/3ZV/f3X9mT3/SPLbJaumkgp3Yzd6t5PeBu+ZQk/mN5WNNuaihNEV7llb1Zhv - Y0Fxu9BVd/BNl0rzuxp3rIinB2TX2SCg7wE5xXkwXuQ/2eTDE0v0HlGntkuZjGow - DZkxHZQSxZVOzdZCRVaX/WEFLpKa2AQpw5RJrQ4oZ/OfifXyJzP27o03wQARAQAB - tEJVYnVudHUgQXJjaGl2ZSBBdXRvbWF0aWMgU2lnbmluZyBLZXkgKDIwMTgpIDxm - dHBtYXN0ZXJAdWJ1bnR1LmNvbT6JAjgEEwEKACIFAlufwdoCGwMGCwkIBwMCBhUI - AgkKCwQWAgMBAh4BAheAAAoJEIcZINGZG8k8LHMQAKS2cnxz/5WaoCOWArf5g6UH - beOCgc5DBm0hCuFDZWWv427aGei3CPuLw0DGLCXZdyc5dqE8mvjMlOmmAKKlj1uG - g3TYCbQWjWPeMnBPZbkFgkZoXJ7/6CB7bWRht1sHzpt1LTZ+SYDwOwJ68QRp7DRa - Zl9Y6QiUbeuhq2DUcTofVbBxbhrckN4ZteLvm+/nG9m/ciopc66LwRdkxqfJ32Cy - q+1TS5VaIJDG7DWziG+Kbu6qCDM4QNlg3LH7p14CrRxAbc4lvohRgsV4eQqsIcdF - kuVY5HPPj2K8TqpY6STe8Gh0aprG1RV8ZKay3KSMpnyV1fAKn4fM9byiLzQAovC0 - LZ9MMMsrAS/45AvC3IEKSShjLFn1X1dRCiO6/7jmZEoZtAp53hkf8SMBsi78hVNr - BumZwfIdBA1v22+LY4xQK8q4XCoRcA9G+pvzU9YVW7cRnDZZGl0uwOw7z9PkQBF5 - KFKjWDz4fCk+K6+YtGpovGKekGBb8I7EA6UpvPgqA/QdI0t1IBP0N06RQcs1fUaA - QEtz6DGy5zkRhR4pGSZn+dFET7PdAjEK84y7BdY4t+U1jcSIvBj0F2B7LwRL7xGp - SpIKi/ekAXLs117bvFHaCvmUYN7JVp1GMmVFxhIdx6CFm3fxG8QjNb5tere/YqK+ - uOgcXny1UlwtCUzlrSaP - =9AdM - -----END PGP PUBLIC KEY BLOCK----- -""" -DEFAULT_ARCHIVE = Archive( - version="22.04", - components=["main", "universe"], - suites=["jammy", "jammy-security", "jammy-updates"], -) - -# Default package for testing. -DEFAULT_PACKAGE_YAML = """ -package: hello -slices: - bins: - contents: - /usr/bin/hello: -""" -DEFAULT_PACKAGE = Package( - package="hello", - slices=["bins"], -) - - -class TestScriptMethods(unittest.TestCase): - """ - Test the methods of install-slices - """ - - def setUp(self) -> None: - logging.disable(logging.CRITICAL) - - def tearDown(self) -> None: - logging.disable(logging.NOTSET) - - def test_parse_archive(self): - """ - Test parse_archive() - """ - # test parsing local release - with tempfile.TemporaryDirectory() as tmpfs: - filepath = os.path.join(tmpfs, "chisel.yaml") - with open(filepath, "w", encoding="utf-8") as file: - file.write(DEFAULT_CHISEL_YAML) - archive = parse_archive(tmpfs) - self.assertEqual(archive, DEFAULT_ARCHIVE) - # test parsing remote release - archive = parse_archive("ubuntu-22.04") - self.assertEqual(archive, DEFAULT_ARCHIVE) - # test parsing archive version properly - chisel_yaml = DEFAULT_CHISEL_YAML.replace("22.04", "23.10") - chisel_yaml = chisel_yaml.replace("jammy", "mantic") - with tempfile.TemporaryDirectory() as tmpfs: - filepath = os.path.join(tmpfs, "chisel.yaml") - with open(filepath, "w", encoding="utf-8") as file: - file.write(chisel_yaml) - archive = parse_archive(tmpfs) - self.assertEqual( - archive, - Archive( - version="23.10", - components=["main", "universe"], - suites=["mantic", "mantic-security", "mantic-updates"], - ), - ) - - def test_full_slice_name(self): - """ - Test full_slice_name() - """ - name = full_slice_name("foo", "bar") - self.assertEqual(name, "foo_bar") - - def test_parse_package(self): - """ - Test parse_package() - """ - with tempfile.TemporaryDirectory() as tmpfs: - filepath = os.path.join(tmpfs, "hello.yaml") - with open(filepath, "w", encoding="utf-8") as file: - file.write(DEFAULT_PACKAGE_YAML) - pkg = parse_package(filepath) - self.assertEqual(pkg, DEFAULT_PACKAGE) - - def test_query_package_existence(self): - """ - Test query_package_existence() - """ - found, missing = query_package_existence( - packages=["libc6", "hello", "foo123"], - archive=DEFAULT_ARCHIVE, - ) - self.assertEqual(found, ["hello", "libc6"]) - self.assertEqual(missing, ["foo123"]) - # with specific arch - found, missing = query_package_existence( - packages=["libc6", "hello", "foo123"], - archive=DEFAULT_ARCHIVE, - arch=["i386"], - ) - self.assertEqual(found, ["libc6"]) - self.assertEqual(missing, ["foo123", "hello"]) - - def test_ensure_package_existence(self): - """ - Test ensure_package_existence() - """ - ensure_package_existence( - packages=["libc6", "hello"], - archive=DEFAULT_ARCHIVE, - ) - # - try: - ensure_package_existence( - packages=["libc6", "hello", "foo123"], - archive=DEFAULT_ARCHIVE, - ) - assert False - except SystemExit as e: - self.assertEqual(e.code, 1) - - def test_ignore_missing_packages(self): - """ - Test ignore_missing_packages() - """ - filtered, ignored = ignore_missing_packages( - packages=[ - Package("libc6", []), - Package("hello", []), - Package("foo123", []), - ], - arch="i386", - release="ubuntu-22.04", - ) - self.assertEqual(filtered, [Package("libc6", [])]) - self.assertEqual( - ignored, - [ - Package("hello", []), - Package("foo123", []), - ], - ) - - def test_install_slice(self): - """ - Test install_slice() - """ - mock_missing_copyright = set() - install_slice("libc6", "libs", "amd64", "ubuntu-22.04", mock_missing_copyright) - assert mock_missing_copyright == set() - # - try: - install_slice( - "foo123", "bar", "amd64", "ubuntu-22.04", mock_missing_copyright - ) - assert False - except SystemExit as e: - self.assertEqual(e.code, 1) - - @unittest.mock.patch("os.popen") - @unittest.mock.patch("pathlib.Path.rglob") - @unittest.mock.patch("apt.debfile.DebPackage.__new__") - @unittest.mock.patch("magic.from_file") - def test_deb_has_copyright_file( - self, mock_magic, mock_debpackage, mock_rglob, mock_popen - ): - """ - Test deb_has_copyright_file() - """ - # No files, nothing to do - mock_rglob.return_value = [] - assert deb_has_copyright_file("mock_pkg") == False - mock_debpackage.assert_not_called() - - # If SHA exists but is not a deb, we skip - mock_rglob.return_value = ["fake_sha"] - mock_magic.return_value = "not-a-deb" - assert deb_has_copyright_file("mock_pkg") == False - mock_magic.assert_called_once_with("fake_sha", mime=True) - mock_popen.assert_not_called() - - # If the deb exists but the pkg doesn't match, we skip - mock_magic.return_value = "debian.binary-package" - mock_popen.return_value.read.return_value = "bad-pkg-name" - assert deb_has_copyright_file("mock_pkg") == False - mock_popen.assert_called_once_with( - f"dpkg-deb -f {str(CHISEL_PKG_CACHE) + '/fake_sha'} Package" - ) - mock_debpackage.assert_not_called() - - # If the deb exists and matches, then return True is copyright exists - mock_popen.return_value.read.return_value = "mock_pkg" - mock_deb = unittest.mock.MagicMock() - mock_deb.filelist = "no\ncopyright\nfile" - mock_debpackage.return_value = mock_deb - assert deb_has_copyright_file("mock_pkg") == False - mock_debpackage.assert_called_once() - - mock_deb.filelist = "something\nusr/share/doc/mock_pkg/copyright\nextra" - mock_debpackage.return_value = mock_deb - assert deb_has_copyright_file("mock_pkg") == True - - def test_main(self): - """ - Test main() - """ - with tempfile.TemporaryDirectory() as tmpfs: - with open(os.path.join(tmpfs, "chisel.yaml"), "w", encoding="utf-8") as f: - f.write(DEFAULT_CHISEL_YAML) - slices_dir = os.path.join(tmpfs, "slices") - os.mkdir(slices_dir) - slice_path = os.path.join(slices_dir, "hello.yaml") - with open(slice_path, "w", encoding="utf-8") as f: - f.write(DEFAULT_PACKAGE_YAML) - args = ["", "--arch", "amd64", "--release", tmpfs, slice_path] - with unittest.mock.patch("sys.argv", args): - try: - main() - except SystemExit as e: - self.assertEqual(e.code, 0) - - -if __name__ == "__main__": - unittest.main() diff --git a/.github/workflows/install-slices.yaml b/.github/workflows/install-slices.yaml index 4b0af1f67..635c86f4a 100644 --- a/.github/workflows/install-slices.yaml +++ b/.github/workflows/install-slices.yaml @@ -6,13 +6,11 @@ on: - "main" paths: - ".github/scripts/install-slices/**" - - ".github/workflows/install-slices.yaml" pull_request: branches: - "main" paths: - ".github/scripts/install-slices/**" - - ".github/workflows/install-slices.yaml" schedule: # Run at 00:00 every day. # Ref: https://man7.org/linux/man-pages/man5/crontab.5.html @@ -107,8 +105,6 @@ jobs: matrix: ${{ fromJson(needs.prepare-install.outputs.matrix) }} env: install-all: ${{ needs.prepare-install.outputs.install-all }} - main-branch-ref: ${{ needs.prepare-install.outputs.checkout-main-ref }} - main-branch-path: files-from-main steps: - uses: actions/checkout@v4 with: @@ -135,34 +131,25 @@ jobs: - name: Setup Go environment uses: actions/setup-go@v5 - - - name: Setup Python - uses: actions/setup-python@v5 - with: - python-version: '3.10' - - - name: Checkout main branch - uses: actions/checkout@v4 with: - ref: ${{ env.main-branch-ref }} - path: ${{ env.main-branch-path }} + go-version: '>=1.24' + check-latest: true - name: Install dependencies - env: - script-dir: "${{ env.main-branch-path }}/.github/scripts/install-slices" run: | set -ex # Install chisel go install "github.com/canonical/chisel/cmd/chisel@${{ matrix.chisel-version }}" - # Install dependencies of the install_slices script - sudo apt-get -y update - sudo apt-get install -y $(cat "${{ env.script-dir }}/deb-requirements.txt") - pip install -r "${{ env.script-dir }}/requirements.txt" + # Install sdf (from rebornplusplus' chisel-tools). + # TODO we would like to move this to rocks-toolbox. + git clone "https://github.com/rebornplusplus/chisel-tools.git" + cd chisel-tools && go install ./... - # Configure the path of install_slices script - ln -s "${{ env.script-dir }}/install_slices.py" install-slices + # Install additional apt dependencies. + sudo apt-get -y update + sudo apt-get install -y devscripts # for rmadison # TODO: As we are installing the slices for every (ref, arch), when # installing all slices, we are also checking the existence of every @@ -172,6 +159,8 @@ jobs: # future and propose improvements. # See also https://github.com/canonical/chisel-releases/pull/119#discussion_r1494785644 - name: Install slices + env: + WORKERS: 20 run: | set -ex if [[ @@ -181,14 +170,18 @@ jobs: # Install all slices in slices/ dir. # We need to enable globstar to use the ** patterns below. shopt -s globstar - ./install-slices --arch "${{ matrix.arch }}" --release ./ \ + sdf install --arch "${{ matrix.arch }}" --release ./ \ --ensure-existence \ --ignore-missing \ + --prune \ + --workers "${WORKERS}" \ slices/**/*.yaml elif [[ "${{ steps.changed-paths.outputs.slices }}" == "true" ]]; then # Install slices from changed files. - ./install-slices --arch "${{ matrix.arch }}" --release ./ \ + sdf install --arch "${{ matrix.arch }}" --release ./ \ --ensure-existence \ --ignore-missing \ + --prune \ + --workers "${WORKERS}" \ ${{ steps.changed-paths.outputs.slices_files }} fi