Source code for reemote.operations.builtin.apt_key

# Copyright (c) 2025 Kim Jarvis TPF Software Services S.A. kim.jarvis@tpfsystems.com 
# This software is licensed under the MIT License. See the LICENSE file for details.
#
from reemote.command import Command


[docs] class Apt_key: """ A class to encapsulate the functionality of managing apt keys in Debian-based systems. It allows users to add or remove apt keys from keyring, optionally downloading them from a keyserver or URL, or using local keyfiles. Attributes: data (str): The keyfile contents to add to the keyring. file (str): The path to a keyfile on the remote server to add to the keyring. id (str): The identifier of the key. keyring (str): The full path to specific keyring file in /etc/apt/trusted.gpg.d/. keyserver (str): The keyserver to retrieve key from. state (str): Ensures that the key is present (added) or absent (revoked). url (str): The URL to retrieve key from. validate_certs (bool): If False, SSL certificates for the target url will not be validated. **Examples:** .. code:: python # Add an apt key by id from a keyserver r = yield AptKey(keyserver="keyserver.ubuntu.com", id="36A1D7869245C8950F966E92D8576A8BA88D21E9") # Add an Apt signing key from URL r = yield AptKey(url="https://ftp-master.debian.org/keys/archive-key-6.0.asc", state="present") # Remove an Apt specific signing key r = yield AptKey(id="0x9FED2BCBDCD29CDF762678CBAED4B06F473041FA", state="absent") # Add a key from data content key_data = "-----BEGIN PGP PUBLIC KEY BLOCK-----\\n..." r = yield AptKey(data=key_data, state="present") # Add an Apt signing key to a specific keyring file r = yield AptKey(id="9FED2BCBDCD29CDF762678CBAED4B06F473041FA", url="https://ftp-master.debian.org/keys/archive-key-6.0.asc", keyring="/etc/apt/trusted.gpg.d/debian.gpg") Usage: This class is designed to be used in a generator-based workflow where commands are yielded for execution. Notes: - The apt-key command used by this implementation has been deprecated. - Adding a new key requires an apt cache update. - Use full fingerprint (40 characters) key ids to avoid key collisions. """ def __init__(self, data: str = None, file: str = None, id: str = None, keyring: str = None, keyserver: str = None, state: str = "present", url: str = None, validate_certs: bool = True, guard: bool = True, sudo: bool = True): # apt-key typically requires sudo self.data = data self.file = file self.id = id self.keyring = keyring self.keyserver = keyserver self.state = state self.url = url self.validate_certs = validate_certs self.guard = guard self.sudo = sudo def __repr__(self): return (f"AptKey(data={self.data!r}, " f"file={self.file!r}, " f"id={self.id!r}, " f"keyring={self.keyring!r}, " f"keyserver={self.keyserver!r}, " f"state={self.state!r}, " f"url={self.url!r}, " f"validate_certs={self.validate_certs!r}, " f"guard={self.guard!r}, " f"sudo={self.sudo!r})") def execute(self): # Build the apt-key command cmd_parts = ["apt-key"] if self.keyring: cmd_parts.extend(["--keyring", self.keyring]) if self.state == "absent": if not self.id: raise ValueError("id parameter is required when state is absent") cmd_parts.extend(["del", self.id]) else: # state == "present" if self.data: # For data, we need to echo it and pipe to apt-key cmd_parts = ["echo", repr(self.data), "|"] + cmd_parts + ["add", "-"] elif self.file: cmd_parts.extend(["add", self.file]) elif self.keyserver and self.id: cmd_parts.extend(["adv", "--keyserver", self.keyserver, "--recv-keys", self.id]) elif self.url: # Download and add from URL cmd_parts.extend(["adv", "--fetch-keys", self.url]) elif self.id and not self.keyserver: # If only ID is provided, try to receive from default keyserver cmd_parts.extend(["adv", "--recv-keys", self.id]) else: raise ValueError("Insufficient parameters to add key. Provide data, file, keyserver+id, or url.") cmd = " ".join(cmd_parts) r = yield Command(cmd, guard=self.guard, sudo=self.sudo) r.changed = True