From 7fe9fb9599e0d6ef70308c36dc4c6dbed0993a5b Mon Sep 17 00:00:00 2001 From: Luca Boccassi Date: Sun, 19 Jan 2025 15:58:47 +0000 Subject: [PATCH 1/3] linter: run ruff format --diff so that the needed changes are actually printed --- .github/workflows/linter.yml | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/.github/workflows/linter.yml b/.github/workflows/linter.yml index dde1477d5d9..bd5376dc424 100644 --- a/.github/workflows/linter.yml +++ b/.github/workflows/linter.yml @@ -57,4 +57,8 @@ jobs: - name: Run ruff format run: | ruff --version - ruff format --check src/boot/generate-hwids-section.py src/test/generate-sym-test.py src/ukify/ukify.py test/integration-test-wrapper.py + if ! ruff format --check src/boot/generate-hwids-section.py src/test/generate-sym-test.py src/ukify/ukify.py test/integration-test-wrapper.py + then + echo "Please run 'ruff format' on the above files or apply the diffs below manually" + ruff format --check --quiet --diff src/boot/generate-hwids-section.py src/test/generate-sym-test.py src/ukify/ukify.py test/integration-test-wrapper.py + fi From 7bf31680ad9a1148c9a5e1421661717641e68c59 Mon Sep 17 00:00:00 2001 From: Luca Boccassi Date: Sun, 19 Jan 2025 15:43:14 +0000 Subject: [PATCH 2/3] ukify: pass through --json to systemd-measure So that --measure --json prints usable json output --- src/ukify/ukify.py | 2 ++ 1 file changed, 2 insertions(+) diff --git a/src/ukify/ukify.py b/src/ukify/ukify.py index 6b532437acb..b4070f3897b 100755 --- a/src/ukify/ukify.py +++ b/src/ukify/ukify.py @@ -763,6 +763,8 @@ def call_systemd_measure(uki: UKI, opts: UkifyConfig, profile_start: int = 0) -> cmd = [ measure_tool, 'calculate', + '--json', + opts.json, *(f'--{s.name.removeprefix(".")}={s.content}' for s in to_measure.values()), *(f'--bank={bank}' for bank in banks), # For measurement, the keys are not relevant, so we can lump all the phase paths From 7d64e2f368ec7c683fee95d21f527c406b8eb5e6 Mon Sep 17 00:00:00 2001 From: Luca Boccassi Date: Sun, 19 Jan 2025 15:42:47 +0000 Subject: [PATCH 3/3] ukify: print debug/progress messages to stderr Otherwise json will be interleaved with plain text messages --- src/ukify/ukify.py | 39 +++++++++++++++++++++------------------ 1 file changed, 21 insertions(+), 18 deletions(-) diff --git a/src/ukify/ukify.py b/src/ukify/ukify.py index b4070f3897b..b3673a032aa 100755 --- a/src/ukify/ukify.py +++ b/src/ukify/ukify.py @@ -324,7 +324,7 @@ class Uname: filename, ] - print('+', shell_join(cmd)) + print('+', shell_join(cmd), file=sys.stderr) try: notes = subprocess.check_output(cmd, stderr=subprocess.PIPE, text=True) except subprocess.CalledProcessError as e: @@ -355,7 +355,7 @@ class Uname: for func in (cls.scrape_x86, cls.scrape_elf, cls.scrape_generic): try: version = func(filename, opts=opts) - print(f'Found uname version: {version}') + print(f'Found uname version: {version}', file=sys.stderr) return version except ValueError as e: print(str(e)) @@ -496,7 +496,7 @@ class PeSign(SignTool): '-o', output_f, ] # fmt: skip - print('+', shell_join(cmd)) + print('+', shell_join(cmd), file=sys.stderr) subprocess.check_call(cmd) @staticmethod @@ -506,7 +506,7 @@ class PeSign(SignTool): tool = find_tool('pesign', opts=opts) cmd = [tool, '-i', opts.linux, '-S'] - print('+', shell_join(cmd)) + print('+', shell_join(cmd), file=sys.stderr) info = subprocess.check_output(cmd, text=True) return 'No signatures found.' in info @@ -528,7 +528,7 @@ class SbSign(SignTool): '--output', output_f, ] # fmt: skip - print('+', shell_join(cmd)) + print('+', shell_join(cmd), file=sys.stderr) subprocess.check_call(cmd) @staticmethod @@ -538,7 +538,7 @@ class SbSign(SignTool): tool = find_tool('sbverify', opts=opts) cmd = [tool, '--list', opts.linux] - print('+', shell_join(cmd)) + print('+', shell_join(cmd), file=sys.stderr) info = subprocess.check_output(cmd, text=True) return 'No signature table present' in info @@ -580,7 +580,7 @@ class SystemdSbSign(SignTool): '--output', output_f, ] # fmt: skip - print('+', shell_join(cmd)) + print('+', shell_join(cmd), file=sys.stderr) subprocess.check_call(cmd) @staticmethod @@ -627,7 +627,7 @@ def check_splash(filename: Optional[Path]) -> None: return img = Image.open(filename, formats=['BMP']) - print(f'Splash image {filename} is {img.width}×{img.height} pixels') + print(f'Splash image {filename} is {img.width}×{img.height} pixels', file=sys.stderr) def check_inputs(opts: UkifyConfig) -> None: @@ -772,7 +772,7 @@ def call_systemd_measure(uki: UKI, opts: UkifyConfig, profile_start: int = 0) -> *(f'--phase={phase_path}' for phase_path in itertools.chain.from_iterable(pp_groups)), ] - print('+', shell_join(cmd)) + print('+', shell_join(cmd), file=sys.stderr) subprocess.check_call(cmd) # PCR signing @@ -810,7 +810,7 @@ def call_systemd_measure(uki: UKI, opts: UkifyConfig, profile_start: int = 0) -> extra += [f'--phase={phase_path}' for phase_path in group or ()] - print('+', shell_join(cmd + extra)) # type: ignore + print('+', shell_join(cmd + extra), file=sys.stderr) # type: ignore pcrsig = subprocess.check_output(cmd + extra, text=True) # type: ignore pcrsig = json.loads(pcrsig) pcrsigs += [pcrsig] @@ -1147,7 +1147,7 @@ def make_uki(opts: UkifyConfig) -> None: signtool.sign(os.fspath(opts.linux), os.fspath(linux), opts=opts) if opts.uname is None and opts.linux is not None: - print('Kernel version not specified, starting autodetection 😖.') + print('Kernel version not specified, starting autodetection 😖.', file=sys.stderr) opts.uname = Uname.scrape(opts.linux, opts=opts) uki = UKI(opts.stub) @@ -1165,7 +1165,7 @@ def make_uki(opts: UkifyConfig) -> None: if opts.certificate_provider: cmd += ['--certificate-source', f'provider:{opts.certificate_provider}'] - print('+', shell_join(cmd)) + print('+', shell_join(cmd), file=sys.stderr) pcrpkey = subprocess.check_output(cmd) else: pcrpkey = Path(opts.pcr_public_keys[0]) @@ -1177,7 +1177,7 @@ def make_uki(opts: UkifyConfig) -> None: if opts.signing_provider: cmd += ['--private-key-source', f'provider:{opts.signing_provider}'] - print('+', shell_join(cmd)) + print('+', shell_join(cmd), file=sys.stderr) pcrpkey = subprocess.check_output(cmd) hwids = None @@ -1284,7 +1284,10 @@ def make_uki(opts: UkifyConfig) -> None: if n not in to_import: continue - print(f"Copying section '{n}' from '{profile}': {pesection.Misc_VirtualSize} bytes") + print( + f"Copying section '{n}' from '{profile}': {pesection.Misc_VirtualSize} bytes", + file=sys.stderr, + ) uki.add_section( Section.create(n, pesection.get_data(length=pesection.Misc_VirtualSize), measure=True) ) @@ -1313,7 +1316,7 @@ def make_uki(opts: UkifyConfig) -> None: os.umask(umask := os.umask(0)) os.chmod(opts.output, 0o777 & ~umask) - print(f'Wrote {"signed" if sign_args_present else "unsigned"} {opts.output}') + print(f'Wrote {"signed" if sign_args_present else "unsigned"} {opts.output}', file=sys.stderr) @contextlib.contextmanager @@ -1965,14 +1968,14 @@ def apply_config(namespace: argparse.Namespace, filename: Union[str, Path, None] if namespace.config: # Config set by the user, use that. filename = namespace.config - print(f'Using config file: {filename}') + print(f'Using config file: {filename}', file=sys.stderr) else: # Try to look for a config file then use the first one found. for config_dir in DEFAULT_CONFIG_DIRS: filename = Path(config_dir) / DEFAULT_CONFIG_FILE if filename.is_file(): # Found a config file, use it. - print(f'Using found config file: {filename}') + print(f'Using found config file: {filename}', file=sys.stderr) break else: # No config file specified or found, nothing to do. @@ -2096,7 +2099,7 @@ def finalize_options(opts: argparse.Namespace) -> None: elif opts.linux or opts.initrd: raise ValueError('--linux=/--initrd= options cannot be used with positional arguments') else: - print("Assuming obsolete command line syntax with no verb. Please use 'build'.") + print("Assuming obsolete command line syntax with no verb. Please use 'build'.", file=sys.stderr) if opts.positional: opts.linux = Path(opts.positional[0]) # If we have initrds from parsing config files, append our positional args at the end