From patchwork Thu May 7 22:14:56 2026 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Simon Glass X-Patchwork-Id: 2289 Return-Path: X-Original-To: u-boot-concept@u-boot.org Delivered-To: u-boot-concept@u-boot.org DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=u-boot.org; s=default; t=1778192142; bh=2TsbhyAuIILU6V4o+vFHUxs6WzutSgy1biKbAUHuwiA=; h=From:To:Date:In-Reply-To:References:CC:Subject:List-Id: List-Archive:List-Help:List-Owner:List-Post:List-Subscribe: List-Unsubscribe:From; b=oa3x44HsNMk4b6OeYflElAP+LnbtBL8HNXvwWLnLKpWhK0iOp2h0Z8kQx50Ltd9jb YDSL2RHiXdzCAy6RY/ejGBFks75YtQka1++7uJqORMgGydYHWHXxEWfrNvX0nibgHk fwZhjzfZo7GXMGW9seV7yokZgaKlmpsq38WoFgpo= Received: from localhost (localhost [127.0.0.1]) by mail.u-boot.org (Postfix) with ESMTP id 3BE996A9AB for ; Thu, 7 May 2026 16:15:42 -0600 (MDT) X-Virus-Scanned: Debian amavis at Received: from mail.u-boot.org ([127.0.0.1]) by localhost (mail.u-boot.org [127.0.0.1]) (amavis, port 10024) with ESMTP id jVpu5JmIJJzN for ; Thu, 7 May 2026 16:15:42 -0600 (MDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=u-boot.org; s=default; t=1778192140; bh=2TsbhyAuIILU6V4o+vFHUxs6WzutSgy1biKbAUHuwiA=; h=From:To:Date:In-Reply-To:References:CC:Subject:List-Id: List-Archive:List-Help:List-Owner:List-Post:List-Subscribe: List-Unsubscribe:From; b=aVBd6HavlhqtC76tX91ba/UWU8I7RmLp4zRaopuOxaLgpq1JorPp1ShyYxzOUvVrq xBbCL/BGeZsN2HOTiRl6gD/tavnHBsnPQMDdKxfnYl/8OjDxx1Y5JmP0nLRqRSs7ip 6X3ZM2Weq7VJC0iKGTs8bpwmcge30RNo0iHqgt2U= Received: from mail.u-boot.org (localhost [127.0.0.1]) by mail.u-boot.org (Postfix) with ESMTP id AD9656A9A8 for ; Thu, 7 May 2026 16:15:40 -0600 (MDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=u-boot.org; s=default; t=1778192138; bh=KYK2bqbCBbf8cDljGZ6RgPmZQ0lGci36p4TfeoET16w=; h=From:To:Cc:Subject:Date:In-Reply-To:References:From; b=hCwhcYA1jvJORfWpPQbNM/4i4iJbN0Dw58ZI/dACXNni7RY1DUe7zHSotpPmo29dr OFACvxbP+tl/8Jvo/wTzdaybwarD6vHl4uiMeYJ0DdMhbVT0xwSWQuLRdJY8OLuSY1 lhlz/EQSNM6fHWDeLNT+D5O2UsXdYqFC7ulepuoU= Received: from localhost (localhost [127.0.0.1]) by mail.u-boot.org (Postfix) with ESMTP id 798E06A9A8; Thu, 7 May 2026 16:15:38 -0600 (MDT) X-Virus-Scanned: Debian amavis at Received: from mail.u-boot.org ([127.0.0.1]) by localhost (mail.u-boot.org [127.0.0.1]) (amavis, port 10026) with ESMTP id BVyB1DrqsNLD; Thu, 7 May 2026 16:15:38 -0600 (MDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=u-boot.org; s=default; t=1778192136; bh=gHIvTj99faIg1jFhq52u+ASoRZokoKBYHiiWHvNE7Tc=; h=From:To:Cc:Subject:Date:In-Reply-To:References:From; b=N/o96kRudNn55YO1YBeILHCEE6mFU1MLpXy6aaCYC3vOhNlfU07LEonv3BCaIOI9h txb1I93nLl+UUXrio9kQvTWiz8d1GUDR7QF+CJafSLmLnU2ye6sJax6H+xu+nNAHor t8xHBT98Zz3rr7TPGrs0RQNaULYtgqo1BHtXTRoA= Received: from u-boot.org (unknown [174.51.25.52]) by mail.u-boot.org (Postfix) with ESMTPSA id 3E7906A9BA; Thu, 7 May 2026 16:15:36 -0600 (MDT) From: Simon Glass To: U-Boot Concept Date: Thu, 7 May 2026 16:14:56 -0600 Message-ID: <20260507221507.505998-12-sjg@u-boot.org> X-Mailer: git-send-email 2.43.0 In-Reply-To: <20260507221507.505998-1-sjg@u-boot.org> References: <20260507221507.505998-1-sjg@u-boot.org> MIME-Version: 1.0 Message-ID-Hash: PGWX2Z6QOW3F5FJ6G35TG7DDESJXGE2V X-Message-ID-Hash: PGWX2Z6QOW3F5FJ6G35TG7DDESJXGE2V X-MailFrom: sjg@u-boot.org X-Mailman-Rule-Misses: dmarc-mitigation; no-senders; approved; loop; banned-address; emergency; member-moderation; nonmember-moderation; administrivia; implicit-dest; max-recipients; max-size; news-moderation; no-subject; digests; suspicious-header CC: Simon Glass X-Mailman-Version: 3.3.10 Precedence: list Subject: [Concept] [PATCH 11/13] scripts: ubuntu: Use Args:/Returns: docstrings throughout List-Id: Discussion and patches related to U-Boot Concept Archived-At: List-Archive: List-Help: List-Owner: List-Post: List-Subscribe: List-Unsubscribe: From: Simon Glass build_esp() already documents its parameters with the Google-style Args: block u_boot_pylib uses, but the rest of the script only hand-waves about its arguments in prose (when it documents them at all). That makes generated help and IDE tooltips uneven and forces a reader to grep the body to find out what each parameter means. Add Args:/Returns:/Raises: sections to every public helper and to _run(); also give check_tools() a one-line summary it had been missing. No behaviour change. Signed-off-by: Simon Glass --- scripts/ubuntu-iso-to-uboot.py | 71 ++++++++++++++++++++++++++++++---- 1 file changed, 64 insertions(+), 7 deletions(-) diff --git a/scripts/ubuntu-iso-to-uboot.py b/scripts/ubuntu-iso-to-uboot.py index ba11aedc89c..8dcd37fda82 100755 --- a/scripts/ubuntu-iso-to-uboot.py +++ b/scripts/ubuntu-iso-to-uboot.py @@ -156,12 +156,16 @@ def _run(*cmd) -> None: On failure u_boot_pylib's CommandExc still carries the captured output, so the user sees what went wrong. + + Args: + *cmd: Command and its arguments, as separate strings """ quiet = _quiet() command.run(*cmd, capture=quiet, capture_stderr=quiet) def check_tools() -> None: + """Abort with a helpful message if any REQUIRED_TOOLS binary is missing.""" missing = [t for t in REQUIRED_TOOLS if not shutil.which(t)] if missing: tout.fatal( @@ -176,6 +180,13 @@ def parse_grub_cmdline(iso: Path, kernel: str) -> str: Parses the first `linux ...` line in /boot/grub/grub.cfg and strips the kernel path, so the caller can pass the remaining tokens to the kernel (e.g. '--- quiet splash' on Ubuntu 24.04.1). + + Args: + iso (Path): Input ISO to inspect + kernel (str): Kernel path inside the ISO to look for in grub.cfg + + Returns: + str: Kernel cmdline tokens, with whitespace collapsed """ with tempfile.TemporaryDirectory(prefix='iso2uboot.grub.') as td: dst = Path(td) / 'grub.cfg' @@ -203,8 +214,16 @@ def parse_grub_cmdline(iso: Path, kernel: str) -> str: def parse_boot_report(iso: Path) -> tuple[str, str]: """Return (volume_label, esp_partition_guid) from xorriso's mkisofs report. - Raises SystemExit if the ISO does not have an appended EFI System - Partition on slot 2 + Args: + iso (Path): Input ISO to inspect + + Returns: + tuple[str, str]: (volume label, partition-2 GUID) parsed from + xorriso's '-report_el_torito as_mkisofs' output + + Raises: + SystemExit: if the ISO does not have an appended EFI System + Partition on slot 2 """ # xorriso prints the report on stdout (which we need to parse) and # progress/status on stderr (which we swallow unless -v was passed). @@ -264,6 +283,15 @@ def repack_iso( xorriso refuses to write to an existing non-empty file when -indev and -outdev differ (it would treat the outdev as a session to extend), so unlink any stale output first. + + Args: + in_iso (Path): Source ISO to read + out_iso (Path): Destination ISO; unlinked first if it exists + esp_img (Path): FAT image to splice in as the appended partition + esp_guid (str): GPT type GUID for the appended partition (from + parse_boot_report()) + file_maps (list[tuple[Path, str]]): (src, dst) pairs added to the + ISO 9660 tree via xorriso -map """ if out_iso.exists(): out_iso.unlink() @@ -291,10 +319,10 @@ def inject_first_boot_unit( """Unpack the install squashfs, drop in a first-boot BLS-setup unit plus its helper script and a copy of u-boot.efi, and repack. - u-boot.efi travels through the install at /usr/lib/u-boot/u-boot.efi - so the first-boot unit (and the autoinstall late-commands, which - also run in-target after the squashfs has been unpacked) can copy - it onto the installed ESP. + u-boot.efi travels through the install at TARGET_UBOOT_EFI so the + first-boot unit (and the autoinstall late-commands, which also run + in-target after the squashfs has been unpacked) can copy it onto + the installed ESP. The whole unpack/modify/repack cycle runs under one fakeroot invocation so ownership survives round-tripping through a regular @@ -302,7 +330,16 @@ def inject_first_boot_unit( resulting ISO close to the source in size; that does mean the rewrite takes several minutes. - Returns the path to the modified squashfs. + Args: + iso (Path): Input ISO containing the install squashfs to extract + sqfs_in_iso (str): Path of the install squashfs inside @iso + (e.g. 'casper/minimal.squashfs') + uboot_efi (Path): U-Boot EFI app to plant inside the squashfs at + TARGET_UBOOT_EFI + work (Path): Scratch directory for the unpack/repack staging + + Returns: + Path: Modified squashfs ready to splice back into the ISO """ extracted = work / 'orig.squashfs' modified = work / 'modified.squashfs' @@ -350,6 +387,13 @@ def hash_password(password: str) -> str: Subiquity's identity.password field wants a crypt(3) hash, not a plaintext password. Shelling out to openssl keeps the script's dependency list unchanged (Python's crypt module is gone in 3.13). + + Args: + password (str): Plaintext password, fed via stdin so it never appears + on the openssl command line + + Returns: + str: SHA-512 crypt hash, with trailing newline stripped """ return command.run( 'openssl', 'passwd', '-6', '-stdin', @@ -382,6 +426,19 @@ def autoinstall_yaml( When @unattended is True, also emit identity and storage sections so subiquity can complete without user input - required for the test_distro_ubuntu_iso_install CI path. + + Args: + unattended (bool): True to emit the identity/storage/ssh sections + needed for an end-to-end autoinstall + hostname (str): Hostname for the autoinstalled system + (used only when @unattended) + username (str): Login user created by autoinstall + (used only when @unattended) + password_hash (str): SHA-512 crypt hash for that user, as + produced by hash_password() (used only when @unattended) + + Returns: + str: autoinstall.yaml document body """ head = '''\ #cloud-config