From 6ce41230c5dcd2240b5f358497d2c8bb5979e166 Mon Sep 17 00:00:00 2001 From: Lindley Vieira Date: Mon, 16 Sep 2024 12:04:15 -0300 Subject: [PATCH] Remove apt-ostree component If some Debian package is corrupted inside apt-ostree repo, it can not be deleted by name. To fix it this commit adds the option to remove the component with all packages inside it. Test-Plan: PASS: run 'sudo apt-ostree repo remove --feed= \ --release=bullseye --component=' to remove the component PASS: see in the logs 'Component removed successfully' PASS: Check in /conf/distributions if the component is not there. Story: 2010676 Task: 51067 Change-Id: I77ae8047a757ead1f96f72b0935dea878a9bc434 Signed-off-by: Lindley Vieira --- apt_ostree/cmd/options.py | 2 +- apt_ostree/repo.py | 38 ++++++++++++++++++++++++++------------ apt_ostree/utils.py | 36 ++++++++++++++++++++++++++++++++++++ 3 files changed, 63 insertions(+), 13 deletions(-) diff --git a/apt_ostree/cmd/options.py b/apt_ostree/cmd/options.py index fc15c05..d4b97aa 100644 --- a/apt_ostree/cmd/options.py +++ b/apt_ostree/cmd/options.py @@ -249,7 +249,7 @@ def packages_option(f): "packages", nargs=-1, callback=callback, - required=True, + required=False, )(f) diff --git a/apt_ostree/repo.py b/apt_ostree/repo.py index b46ff19..96605e8 100644 --- a/apt_ostree/repo.py +++ b/apt_ostree/repo.py @@ -119,21 +119,35 @@ class Repo: self.console.print(table) def remove(self): - """Remove a Debian package from a component.""" + """Remove Debian packages or a component.""" + component = self.state.component or self.state.origin - for pkg in self.state.packages: - self.logging.info(f"Removing {pkg}.") - r = utils.run_command( - ["reprepro", "-b", str(self.repo), "-C", component, - "remove", self.state.release, pkg], - check=True) - if r.returncode == 0: - self.logging.info( - f"Successfully removed {pkg} from component {component}\n") + if self.state.packages: + # delete package by package + for pkg in self.state.packages: + self.logging.info(f"Removing {pkg}.") + r = utils.run_command( + ["reprepro", "-b", str(self.repo), "-C", component, + "remove", self.state.release, pkg], + check=True) + if r.returncode == 0: + self.logging.info( + f"Removed {pkg} from component {component}\n") + else: + self.logging.error( + f"Failed to remove {pkg} from component {component}\n") + else: + # delete the entire component + config = self.repo.joinpath("conf/distributions") + + if utils.remove_component_from_config(config, component): + utils.run_command( + ["reprepro", "-b", str(self.repo), "clearvanished"], + check=True) + self.logging.info(f"Removed component {component}\n") else: - self.logging.error( - f"Failed to remove {pkg} from component {component}\n") + self.logging.error(f"Failed to remove component {component}\n") def disable_repo(self): """Disable Debian feed via apt-add-repository.""" diff --git a/apt_ostree/utils.py b/apt_ostree/utils.py index 54a19d4..213ea62 100644 --- a/apt_ostree/utils.py +++ b/apt_ostree/utils.py @@ -100,3 +100,39 @@ def check_and_append_component(config_path, component): with open(config_path, 'w') as file: file.writelines(lines) + + +def remove_component_from_config(config_path, component): + try: + with open(config_path, 'r') as file: + lines = file.readlines() + except FileNotFoundError: + msg = "The file %s does not exist." % config_path + LOG.error(msg) + return False + + updated_lines = [] + component_found = False + for line in lines: + if line.startswith("Components:"): + components = line.split()[1:] + if component in components: + components.remove(component) + component_found = True + + updated_line = "Components: " + " ".join(components) + "\n" + updated_lines.append(updated_line) + else: + updated_lines.append(line) + + if not component_found: + msg = "Component %s not found in the configuration." % component + LOG.error(msg) + return False + + with open(config_path, 'w') as file: + file.writelines(updated_lines) + + LOG.info("Component %s removed from %s successfully" + % (component, config_path)) + return True