From 7cce4ea8c968a1ff8df7ed867d6188242b1e5014 Mon Sep 17 00:00:00 2001 From: Matthias Andreas Benkard Date: Sat, 2 Mar 2024 21:21:51 +0100 Subject: jgvariant-tool, add-static-delta: Document better, accept modified Base64. Change-Id: Icad477b34d074164ffdd162afd91f4abf627b979 --- README.md | 14 ++-- .../src/main/java/eu/mulk/jgvariant/tool/Main.java | 8 +-- .../java/eu/mulk/jgvariant/tool/MainCommand.java | 81 +++++++++++++++++----- jgvariant-tool/src/main/java/module-info.java | 8 +-- 4 files changed, 82 insertions(+), 29 deletions(-) diff --git a/README.md b/README.md index 8254404..dc3f37f 100644 --- a/README.md +++ b/README.md @@ -87,13 +87,19 @@ Output: #### Adding a static delta to an [OSTree][] summary file -Static delta 3... (in hex), between commits 1... and 2...: +Superblock checksum `0...`, between commits `3...` and `6...`: - $ jgvariant ostree summary add-static-delta ./jgvariant-ostree/src/test/resources/ostree/summary 3333333333333333333333333333333333333333333333333333333333333333 2222222222222222222222222222222222222222222222222222222222222222 1111111111111111111111111111111111111111111111111111111111111111 + $ jgvariant ostree summary add-static-delta ./jgvariant-ostree/src/test/resources/ostree/summary 03738040e28e7662e9c9d2599c530ea974e642c9f87e6c00cbaa39a0cdac8d44 66ff167ff35ce87daac817447a9490a262ee75f095f017716a6eb1a9d9eb3350 3d3b3329dca38871f29aeda1bf5854d76c707fa269759a899d0985c91815fe6f -Static delta 3... (in hex), between the empty commit and 2...: +Superblock checksum `f...`, between the empty commit and `3...`: + + $ jgvariant ostree summary add-static-delta ./jgvariant-ostree/src/test/resources/ostree/summary f481144629474bd88c106e45ac405ebd75b324b0655af1aec14b31786ae1fd61 31c8835d5c9d2c6687a50091c85142d1b2d853ff416a9fb81b4ee30754510d52 + +Checksums can be given in either hex (64 digits) or a variant of Base64 (43 +digits) where `/` is replaced by `_`. The latter format is used to identify +the start and end commits of deltas as part of folder names below `deltas/` in +the OSTree repository itself. - $ jgvariant ostree summary add-static-delta ./jgvariant-ostree/src/test/resources/ostree/summary 4444444444444444444444444444444444444444444444444444444444444444 2222222222222222222222222222222222222222222222222222222222222222 ### Building the tool diff --git a/jgvariant-tool/src/main/java/eu/mulk/jgvariant/tool/Main.java b/jgvariant-tool/src/main/java/eu/mulk/jgvariant/tool/Main.java index 744d902..c352e4f 100644 --- a/jgvariant-tool/src/main/java/eu/mulk/jgvariant/tool/Main.java +++ b/jgvariant-tool/src/main/java/eu/mulk/jgvariant/tool/Main.java @@ -61,17 +61,17 @@ import picocli.CommandLine; * *

Adding a static delta to an OSTree summary file

* - *

Static delta 3... (in hex), between commits 1... and 2... + *

Superblock checksum 0..., between commits 3... and 6... * : * * {@snippet lang="sh" : - * $ jgvariant ostree summary add-static-delta ./jgvariant-ostree/src/test/resources/ostree/summary 3333333333333333333333333333333333333333333333333333333333333333 2222222222222222222222222222222222222222222222222222222222222222 1111111111111111111111111111111111111111111111111111111111111111 + * $ jgvariant ostree summary add-static-delta ./jgvariant-ostree/src/test/resources/ostree/summary 03738040e28e7662e9c9d2599c530ea974e642c9f87e6c00cbaa39a0cdac8d44 66ff167ff35ce87daac817447a9490a262ee75f095f017716a6eb1a9d9eb3350 3d3b3329dca38871f29aeda1bf5854d76c707fa269759a899d0985c91815fe6f * } * - *

Static delta 3... (in hex), between the empty commit and 2...: + *

Superblock checksum f..., between the empty commit and 3...: * * {@snippet lang="sh" : - * $ jgvariant ostree summary add-static-delta ./jgvariant-ostree/src/test/resources/ostree/summary 4444444444444444444444444444444444444444444444444444444444444444 2222222222222222222222222222222222222222222222222222222222222222 + * $ jgvariant ostree summary add-static-delta ./jgvariant-ostree/src/test/resources/ostree/summary f481144629474bd88c106e45ac405ebd75b324b0655af1aec14b31786ae1fd61 31c8835d5c9d2c6687a50091c85142d1b2d853ff416a9fb81b4ee30754510d52 * } */ public final class Main { diff --git a/jgvariant-tool/src/main/java/eu/mulk/jgvariant/tool/MainCommand.java b/jgvariant-tool/src/main/java/eu/mulk/jgvariant/tool/MainCommand.java index 2bea23c..db724dd 100644 --- a/jgvariant-tool/src/main/java/eu/mulk/jgvariant/tool/MainCommand.java +++ b/jgvariant-tool/src/main/java/eu/mulk/jgvariant/tool/MainCommand.java @@ -29,6 +29,7 @@ import java.text.ParseException; import java.util.*; import java.util.logging.Logger; import java.util.stream.IntStream; +import org.jetbrains.annotations.Nullable; import org.jetbrains.annotations.VisibleForTesting; import picocli.AutoComplete; import picocli.CommandLine; @@ -37,7 +38,7 @@ import picocli.CommandLine.*; @Command( name = "jgvariant", mixinStandardHelpOptions = true, - description = "Manipulate files in GVariant format.", + header = "Manipulate files in GVariant format.", subcommands = {MainCommand.OstreeCommand.class, AutoComplete.GenerateCompletion.class}) final class MainCommand { @@ -74,35 +75,60 @@ final class MainCommand { @Command( name = "ostree", mixinStandardHelpOptions = true, - description = "Manipulate OSTree files.", + header = "Manipulate OSTree files.", subcommands = {OstreeCommand.SummaryCommand.class}) static final class OstreeCommand { @Command( name = "summary", mixinStandardHelpOptions = true, - description = "Manipulate OSTree summary files.") + header = "Manipulate OSTree summary files.") static final class SummaryCommand extends BaseDecoderCommand

{ - @Command(mixinStandardHelpOptions = true) + @Command( + name = "read", + mixinStandardHelpOptions = true, + header = "Dump an OSTree summary file as human-readable JSON.") void read(@Parameters(paramLabel = "", description = "Summary file to read") File file) throws IOException { read(file, Summary.decoder()); } - @Command(name = "add-static-delta", mixinStandardHelpOptions = true) + @Command( + name = "add-static-delta", + mixinStandardHelpOptions = true, + header = "Add a static delta to an OSTree summary file.", + description = + """ + Checksums can be given in either hex (64 digits) or a variant of Base64 (43 + digits) where '/' is replaced by '_'. + + In the OSTree repository, static deltas are named based on the and + checksums in modified Base64 when stored in the deltas/ directory. The naming + scheme is either /- if is an actual commit + or / if is the empty commit. + + is the SHA256 checksum of the file called 'superblock' that + is part of the static delta and contains its metadata. + """) void addStaticDelta( @Parameters(paramLabel = "", description = "Summary file to manipulate.") File summaryFile, - @Parameters(paramLabel = "", description = "Checksum of the static delta (hex).") - String delta, - @Parameters(paramLabel = "", description = "Commit checksum the delta ends at (hex).") - String toCommit, + @Parameters( + paramLabel = "", + description = "Checksum of the static delta superblock (hex/mbase64).") + String deltaName, + @Parameters( + paramLabel = "", + description = "Commit checksum the delta ends at (hex/mbase64).") + String toCommitName, @Parameters( paramLabel = "", arity = "0..1", - description = "Commit checksum the delta starts from (hex).") - String fromCommit) + description = + "Commit checksum the delta starts from (hex/mbase64). Defaults to the empty commit.") + @Nullable + String fromCommitName) throws IOException, ParseException { var summaryDecoder = Summary.decoder(); @@ -111,6 +137,10 @@ final class MainCommand { var staticDeltaMapSignature = Signature.parse("a{sv}"); var checksumSignature = Signature.parse("ay"); + var delta = parseChecksum(deltaName); + var toCommit = parseChecksum(toCommitName); + var fromCommit = fromCommitName != null ? parseChecksum(fromCommitName) : null; + var metadata = summary.metadata(); var metadataFields = new LinkedHashMap<>(metadata.fields()); metadataFields.compute( @@ -121,8 +151,8 @@ final class MainCommand { ? new LinkedHashMap<>((Map) v.value()) : new LinkedHashMap<>(); staticDeltas.put( - fromCommit != null ? fromCommit + "-" + toCommit : toCommit, - new Variant(checksumSignature, toByteList(ByteString.ofHex(delta).bytes()))); + fromCommit != null ? fromCommit.hex() + "-" + toCommit.hex() : toCommit.hex(), + new Variant(checksumSignature, toByteList(delta.bytes()))); return new Variant(staticDeltaMapSignature, staticDeltas); }); metadata = new Metadata(metadataFields); @@ -131,10 +161,6 @@ final class MainCommand { encodeFile(summaryFile, summaryDecoder, summary); } - private List toByteList(byte[] bytes) { - return IntStream.range(0, bytes.length).mapToObj(i -> bytes[i]).toList(); - } - SummaryCommand() {} } @@ -185,6 +211,27 @@ final class MainCommand { out.write(thingBytes); } } + + protected static ByteString parseChecksum(String name) { + var bytes = + switch (name.length()) { + case 64 -> ByteString.ofHex(name); + case 43 -> ByteString.ofModifiedBase64(name); + default -> + throw new IllegalArgumentException( + "Checksums must be either 64 hex digits or 43 mbase64 digits."); + }; + + if (bytes.size() != 32) { + throw new IllegalArgumentException("Checksums must be 32 bytes long."); + } + + return bytes; + } + + protected static List toByteList(byte[] bytes) { + return IntStream.range(0, bytes.length).mapToObj(i -> bytes[i]).toList(); + } } MainCommand() {} diff --git a/jgvariant-tool/src/main/java/module-info.java b/jgvariant-tool/src/main/java/module-info.java index 6faa226..3f38283 100644 --- a/jgvariant-tool/src/main/java/module-info.java +++ b/jgvariant-tool/src/main/java/module-info.java @@ -55,17 +55,17 @@ * *

Adding a static delta to an OSTree summary file

* - *

Static delta 3... (in hex), between commits 1... and 2... + *

Superblock checksum 0..., between commits 3... and 6... * : * * {@snippet lang="sh" : - * $ jgvariant ostree summary add-static-delta ./jgvariant-ostree/src/test/resources/ostree/summary 3333333333333333333333333333333333333333333333333333333333333333 2222222222222222222222222222222222222222222222222222222222222222 1111111111111111111111111111111111111111111111111111111111111111 + * $ jgvariant ostree summary add-static-delta ./jgvariant-ostree/src/test/resources/ostree/summary 03738040e28e7662e9c9d2599c530ea974e642c9f87e6c00cbaa39a0cdac8d44 66ff167ff35ce87daac817447a9490a262ee75f095f017716a6eb1a9d9eb3350 3d3b3329dca38871f29aeda1bf5854d76c707fa269759a899d0985c91815fe6f * } * - *

Static delta 3... (in hex), between the empty commit and 2...: + *

Superblock checksum f..., between the empty commit and 3...: * * {@snippet lang="sh" : - * $ jgvariant ostree summary add-static-delta ./jgvariant-ostree/src/test/resources/ostree/summary 4444444444444444444444444444444444444444444444444444444444444444 2222222222222222222222222222222222222222222222222222222222222222 + * $ jgvariant ostree summary add-static-delta ./jgvariant-ostree/src/test/resources/ostree/summary f481144629474bd88c106e45ac405ebd75b324b0655af1aec14b31786ae1fd61 31c8835d5c9d2c6687a50091c85142d1b2d853ff416a9fb81b4ee30754510d52 * } */ module eu.mulk.jgvariant.tool { -- cgit v1.2.3