From e0c9e21930d7958555702da6c7acb1768246e8a6 Mon Sep 17 00:00:00 2001 From: John Ericson Date: Tue, 9 Apr 2024 17:07:39 -0400 Subject: [PATCH] Document store object content addressing & improve JSON format The JSON format no longer uses the legacy ATerm `r:` prefixing nonsese, but separate fields. Progress on #9866 --- doc/manual/src/SUMMARY.md.in | 1 + .../src/language/advanced-attributes.md | 36 ++-- doc/manual/src/protocols/json/derivation.md | 27 ++- doc/manual/src/protocols/store-path.md | 25 ++- .../file-system-object/content-address.md | 9 +- .../src/store/store-object/content-address.md | 160 ++++++++++++++++++ src/libcmd/misc-store-flags.cc | 12 +- src/libstore/derivations.cc | 24 +-- src/nix/flake.md | 10 +- src/nix/nar-cat.md | 3 +- src/nix/nar-dump-path.md | 6 +- src/nix/nar-ls.md | 6 +- src/nix/nar.md | 9 +- src/nix/store-dump-path.md | 4 +- src/nix/verify.md | 2 + .../data/derivation/output-caFixedFlat.json | 1 + .../data/derivation/output-caFixedNAR.json | 3 +- .../data/derivation/output-caFixedText.json | 3 +- .../data/derivation/output-caFloating.json | 3 +- .../data/derivation/output-impure.json | 5 +- 20 files changed, 286 insertions(+), 63 deletions(-) create mode 100644 doc/manual/src/store/store-object/content-address.md diff --git a/doc/manual/src/SUMMARY.md.in b/doc/manual/src/SUMMARY.md.in index d1c0ad12abfd..52e6354c6c86 100644 --- a/doc/manual/src/SUMMARY.md.in +++ b/doc/manual/src/SUMMARY.md.in @@ -20,6 +20,7 @@ - [File System Object](store/file-system-object.md) - [Content-Addressing File System Objects](store/file-system-object/content-address.md) - [Store Object](store/store-object.md) + - [Content-Addressing Store Objects](store/store-object/content-address.md) - [Store Path](store/store-path.md) - [Store Types](store/types/index.md) {{#include ./store/types/SUMMARY.md}} diff --git a/doc/manual/src/language/advanced-attributes.md b/doc/manual/src/language/advanced-attributes.md index 3b8e485545b4..56fd4ba6b82e 100644 --- a/doc/manual/src/language/advanced-attributes.md +++ b/doc/manual/src/language/advanced-attributes.md @@ -197,30 +197,32 @@ Derivations can declare some infrequently used optional attributes. `outputHashAlgo` can only be `null` when `outputHash` follows the SRI format. The `outputHashMode` attribute determines how the hash is computed. - It must be one of the following two values: + It must be one of the following values: - + - [`"flat"`](@docroot@/store/store-object/content-address.md#method-flat) - - `"flat"` + This is the default. - The output must be a non-executable regular file; if it isn’t, the build fails. - The hash is - [simply computed over the contents of that file](@docroot@/store/file-system-object/content-address.md#serial-flat) - (so it’s equal to what Unix commands like `sha256sum` or `sha1sum` produce). + - [`"recursive"` or `"nar"`](@docroot@/store/store-object/content-address.md#method-nix-archive) - This is the default. + > **Compatibility** + > + > `"recursive"` is the traditional way of indicating this, + > and is supported since 2005 (virtually the entire history of Nix). + > `"nar"` is more clear, and consistent with other parts of Nix (such as the CLI), + > however support for it is only added in Nix version 2.21. + + - [`"text"`](@docroot@/store/store-object/content-address.md#method-text) - - `"recursive"` or `"nar"` + > **Warning** + > + > The use of this method for derivation outputs is part of the [`dynamic-derivations`][xp-feature-dynamic-derivations] experimental feature. - The hash is computed over the - [Nix Archive (NAR)](@docroot@/store/file-system-object/content-address.md#serial-nix-archive) - dump of the output (i.e., the result of [`nix-store --dump`](@docroot@/command-ref/nix-store/dump.md)). - In this case, the output is allowed to be any [file system object], including directories and more. + - [`"git"`](@docroot@/store/store-object/content-address.md#method-git) - `"recursive"` is the traditional way of indicating this, - and is supported since 2005 (virtually the entire history of Nix). - `"nar"` is more clear, and consistent with other parts of Nix (such as the CLI), - however support for it is only added in Nix version 2.21. + > **Warning** + > + > This method is part of the [`git-hashing`][xp-feature-git-hashing] experimental feature. - [`__contentAddressed`]{#adv-attr-__contentAddressed} > **Warning** diff --git a/doc/manual/src/protocols/json/derivation.md b/doc/manual/src/protocols/json/derivation.md index 649d543ccf30..f881dd703814 100644 --- a/doc/manual/src/protocols/json/derivation.md +++ b/doc/manual/src/protocols/json/derivation.md @@ -18,10 +18,30 @@ is a JSON object with the following fields: Information about the output paths of the derivation. This is a JSON object with one member per output, where the key is the output name and the value is a JSON object with these fields: - * `path`: The output path. + * `path`: + The output path, if it is known in advanced. + Otherwise, `null`. + + + * `method`: + For an output which will be [content addresed], a string representing the [method](@docroot@/store/store-object/content-address.md) of content addressing that is chosen. + Valid method strings are: + + - [`flat`](@docroot@/store/store-object/content-address.md#method-flat) + - [`nar`](@docroot@/store/store-object/content-address.md#method-nix-archive) + - [`text`](@docroot@/store/store-object/content-address.md#method-text) + - [`git`](@docroot@/store/store-object/content-address.md#method-git) + + Otherwise, `null`. * `hashAlgo`: - For fixed-output derivations, the hashing algorithm (e.g. `sha256`), optionally prefixed by `r:` if `hash` denotes a NAR hash rather than a flat file hash. + For an output which will be [content addresed], the name of the hash algorithm used. + Valid algorithm strings are: + + - `md5` + - `sha1` + - `sha256` + - `sha512` * `hash`: For fixed-output derivations, the expected content hash in base-16. @@ -32,7 +52,8 @@ is a JSON object with the following fields: > "outputs": { > "out": { > "path": "/nix/store/2543j7c6jn75blc3drf4g5vhb1rhdq29-source", - > "hashAlgo": "r:sha256", + > "method": "nar", + > "hashAlgo": "sha256", > "hash": "6fc80dcc62179dbc12fc0b5881275898f93444833d21b89dfe5f7fbcbb1d0d62" > } > } diff --git a/doc/manual/src/protocols/store-path.md b/doc/manual/src/protocols/store-path.md index 65777423801e..52352d358a15 100644 --- a/doc/manual/src/protocols/store-path.md +++ b/doc/manual/src/protocols/store-path.md @@ -36,18 +36,23 @@ where - `type` = one of: - ```ebnf - | "text" ( ":" store-path )* + | "text" { ":" store-path } ``` - for encoded derivations written to the store. + This is for the + ["Text"](@docroot@/store/store-object/content-address.md#method-text) + method of content addressing store objects. The optional trailing store paths are the references of the store object. - ```ebnf - | "source" ( ":" store-path )* + | "source" { ":" store-path } [ ":self" ] ``` - For paths copied to the store and hashed via a [Nix Archive (NAR)] and [SHA-256][sha-256]. - Just like in the text case, we can have the store objects referenced by their paths. + This is for the + ["Nix Archive"](@docroot@/store/store-object/content-address.md#method-nix-archive) + method of content addressing store objects, + if the hash algorithm is [SHA-256]. + Just like in the "Text" case, we can have the store objects referenced by their paths. Additionally, we can have an optional `:self` label to denote self reference. - ```ebnf @@ -55,8 +60,12 @@ where ``` For either the outputs built from derivations, - paths copied to the store hashed that area single file hashed directly, or the via a hash algorithm other than [SHA-256][sha-256]. - (in that case "source" is used; this is only necessary for compatibility). + or content-addressed store objects that are not using one of the two above cases. + To be explicit about the latter, that is currently these methods: + + - ["Flat"](@docroot@/store/store-object/content-address.md#method-flat) + - ["Git"](@docroot@/store/store-object/content-address.md#method-git) + - ["Nix Archive"](@docroot@/store/store-object/content-address.md#method-nix-archive) if the hash algorithm is not [SHA-256]. `id` is the name of the output (usually, "out"). For content-addressed store objects, `id`, is always "out". @@ -116,7 +125,7 @@ where Also note that NAR + SHA-256 must not use this case, and instead must use the `type` = `"source:" ...` case. [Nix Archive (NAR)]: @docroot@/store/file-system-object/content-address.md#serial-nix-archive -[sha-256]: https://en.m.wikipedia.org/wiki/SHA-256 +[SHA-256]: https://en.m.wikipedia.org/wiki/SHA-256 ### Historical Note diff --git a/doc/manual/src/store/file-system-object/content-address.md b/doc/manual/src/store/file-system-object/content-address.md index fc5be8c673dd..1c63c52ebda7 100644 --- a/doc/manual/src/store/file-system-object/content-address.md +++ b/doc/manual/src/store/file-system-object/content-address.md @@ -1,7 +1,9 @@ # Content-Addressing File System Objects For many operations, Nix needs to calculate [a content addresses](@docroot@/glossary.md#gloss-content-address) of [a file system object][file system object]. -Usually this is needed as part of content addressing [store objects], since store objects always have a root file system object. +Usually this is needed as part of +[content addressing store objects](../store-object/content-address.md), +since store objects always have a root file system object. But some command-line utilities also just work on "raw" file system objects, not part of any store object. Every content addressing scheme Nix uses ultimately involves feeding data into a [hash function](https://en.wikipedia.org/wiki/Hash_function), and getting back an opaque fixed-size digest which is deemed a content address. @@ -18,6 +20,9 @@ A single file object can just be hashed by its contents. This is not enough information to encode the fact that the file system object is a file, but if we *already* know that the FSO is a single non-executable file by other means, it is sufficient. +Because the hashed data is just the raw file, as is, this choice is good for compatibility with other systems. +For example, Unix commands like `sha256sum` or `sha1sum` will produce hashes for single files that match this. + ### Nix Archive (NAR) { #serial-nix-archive } For the other cases of [file system objects][file system object], especially directories with arbitrary descendents, we need a more complex serialisation format. @@ -69,7 +74,7 @@ every non-directory object is owned by a parent directory, and the entry that re However, if the root object is not a directory, then we have no way of knowing which one of an executable file, non-executable file, or symlink it is supposed to be. In response to this, we have decided to treat a bare file as non-executable file. -This is similar to do what we do with [flat serialisation](#flat), which also lacks this information. +This is similar to do what we do with [flat serialisation](#serial-flat), which also lacks this information. To avoid an address collision, attempts to hash a bare executable file or symlink will result in an error (just as would happen for flat serialisation also). Thus, Git can encode some, but not all of Nix's "File System Objects", and this sort of content-addressing is likewise partial. diff --git a/doc/manual/src/store/store-object/content-address.md b/doc/manual/src/store/store-object/content-address.md new file mode 100644 index 000000000000..2412faedd159 --- /dev/null +++ b/doc/manual/src/store/store-object/content-address.md @@ -0,0 +1,160 @@ +# Content-Addressing Store Objects + +Just [like][fso-ca] [File System Objects][File System Object], +[Store Objects][Store Object] can also be [content addressed](@docroot@/glossary.md#gloss-content-addressed). + +For store objects, the content address we produce will take the form of a [Store Path] rather than regular hash. +In particular, the content-addressing scheme will ensure that the digest of the store path is solely computed from the + +- file system object graph (the root one and its children, if it has any) +- references +- [store directory](../store-path.md#store-directory) +- name + +of the store object, and not any other information, which would not be an intrinsic property of that store object. + +For the full specification of the algorithms involved, see the [specification of store path digests][sp-spec]. + +[File System Object]: ../file-system-object.md +[Store Object]: ../store-object.md +[Store Path]: ../store-path.md + +## Content addressing each part of a store object + +### File System Objects + +With all currently supported store object content addressing methods, the file system object is always content-addressed first, and then that hash incorporated in further calculations. +As such, the conte-addressing of the file system objects part of a store object is exactly as described in the [section on content-addressing file system objects][fso-ca]. + +### References + +With all currently supported store object content addressing methods, +other objects are referred to by their regular (string-encoded-) [store paths][Store Path]. + +Self-references however cannot be referred to by their path, because we are in the midst of describing how to compute that path! + +> The alternative would require finding as hash function fixed point, i.e. the solution to an equation in the form +> ``` +> digest = hash(..... || digest || ....) +> ``` +> which is computationally infeasible, being no easier than finding a hash collision. + +Instead we just have a "has self reference" boolean, which will end up effecting the digest. + +### Name and Store Directory + +These two items affect the digest in a way that is standard for store path digest computations and not specific to content-addressing. +Consult the [specification of store path digests][sp-spec] for further details. + +## Content addressing Methods + +For historical reasons, we don't support all features in all combinations. +Each currently supported method of content addressing chooses a single method of file system object hashing, and may offer some restrictions on references. +The names and store directories are unrestricted however. + +### Flat { #method-flat } + +This uses the corresponding [Flat](../file-system-object/content-address.md#serial-flat) method of file system object content addressing. + +References are not supported. + +### Text { #method-text } + +This also uses the corresponding [Flat](../file-system-object/content-address.md#serial-flat) method of file system object content addressing. + +References to other store objects are supported, but not self reference are not. + +This is the only store-object content-addressing method that is not named identically with a corresponding file system object method. +It is somewhat obscure, mainly used for "drv files" +(derivations serialized as store objects in their ["ATerm" file format](@docroot@/protocols/derivation-aterm.md)). +Prefer using another method if possible. + +### Nix Archive { #method-nix-archive } + +This uses the corresponding [Nix Archive](../file-system-object/content-address.md#serial-nix-archive) method of file system object content addressing. + +References (to other store objects and self references alike) are supported so long as the hash algorithm in use is [SHA-256], but not (neither kind) otherwise. + +[SHA-256]: https://en.m.wikipedia.org/wiki/SHA-256 + +### Git { #method-git } + +> **Warning** +> +> This method is part of the [`git-hashing`][xp-feature-git-hashing] experimental feature. + +This uses the corresponding [Git](../file-system-object/content-address.md#serial-git) method of file system object content addressing. + +References are not supported. + +Only [SHA-1] is supported at this time. +If SHA-256-based Git becomes more widespread, this restriction would be revisited. + +[SHA-1]: https://en.m.wikipedia.org/wiki/SHA-1 + +The resulting abstract syntax is this: + +```idris +data HashType + = MD5 + | SHA-1 + | SHA-256 + | SHA-512 + +record Hash where + type : HashType + hash : Bytes[hashSize type] + +data Method + = NixArchive + | FlatFile + +data ContentAddress + = Text { + hash : Hash, + references : Set StorePath + } + | Fixed { + method : Method, + hash : Hash, + references : Set StorePath + hasSelfReference : Bool + } -- has side condition +``` + +Firstly, note that "text" hashing supports references to other paths, but no "has self reference" boolean: +texted-hashed store object must not have a self reference. +Only regular "fixed" hashing supports the boolean is thus allowed to represent store paths. + +There is an additional side condition that a regular "fixed" output addressing only supports references (to self or other objects) if the method is NAR and the hash type is SHA-256. + +### Reproducibility + +The above system is rather more complex than it needs to be, owning to accretion of features over time. +Still, the fundamental property remains that if one knows how a store object is supposed to be hashed +--- all the non-Hash, non-references information above +--- one can recompute a store object's store path just from that metadata and its content proper (its references and file system objects). +Collectively, we can call this information the "content address method". + +By storing the "Content address method" extra information as part of store object +--- making it data not metadata +--- we achieve the key property of making content-addressed store objects *trustless*. + +What this is means is that they are just plain old data, not containing any "claim" that could be false. +All this information is free to vary, and if any of it varies one gets (ignoring the possibility of hash collisions, as usual) a different store path. +Store paths referring to content-addressed store objects uniquely identify a store object, and given that object, one can recompute the store path. +Any content-addressed store object purporting to be the referee of a store object can be readily verified to see whether it in fact does without any extra information. +No other party claiming a store object corresponds to a store path need be trusted because this verification can be done instead. + +Content addressing currently is used when adding data like source code to the store. +Such data are "basal inputs", not produced from any other derivation (to our knowledge). +Content addressing is thus the only way to address them of our two options. +([Input addressing](@docroot@/glossary.md#gloss-input-addressed-store-object), is only valid for store paths produced from derivations.) + +Additionally, content addressing is also used for the outputs of certain sorts of derivations. +It is very nice to be able to uniformly content-address all data rather than rely on a mix of content addressing and input addressing. +This however, is in some cases still experimental, so in practice input addressing is still (as of 2022) widely used. + +[fso-ca]: ../file-system-object/content-address.md + +[sp-spec]: @docroot@/protocols/store-path.md diff --git a/src/libcmd/misc-store-flags.cc b/src/libcmd/misc-store-flags.cc index 063a9dd9ec2a..06552c032231 100644 --- a/src/libcmd/misc-store-flags.cc +++ b/src/libcmd/misc-store-flags.cc @@ -103,27 +103,27 @@ Args::Flag contentAddressMethod(ContentAddressMethod * method) return Args::Flag { .longName = "mode", // FIXME indentation carefully made for context, this is messed up. - /* FIXME link to store object content-addressing not file system - object content addressing once we have that page. */ .description = R"( How to compute the content-address of the store object. One of: - - `nar` (the default): + - [`nar`](@docroot@/store/store-object/content-address.md#method-nix-archive) + (the default): Serialises the input as a [Nix Archive](@docroot@/store/file-system-object/content-address.md#serial-nix-archive) and passes that to the hash function. - - `flat`: + - [`flat`](@docroot@/store/store-object/content-address.md#method-flat): Assumes that the input is a single file and [directly passes](@docroot@/store/file-system-object/content-address.md#serial-flat) it to the hash function. - - `text`: Like `flat`, but used for + - [`text`](@docroot@/store/store-object/content-address.md#method-text): + Like `flat`, but used for [derivations](@docroot@/glossary.md#store-derivation) serialized in store object and [`builtins.toFile`](@docroot@/language/builtins.html#builtins-toFile). For advanced use-cases only; - for regular usage prefer `nar` and `flat. + for regular usage prefer `nar` and `flat`. )", .labels = {"content-address-method"}, .handler = {[method](std::string s) { diff --git a/src/libstore/derivations.cc b/src/libstore/derivations.cc index fcf813a37d4a..e1370591175e 100644 --- a/src/libstore/derivations.cc +++ b/src/libstore/derivations.cc @@ -1216,16 +1216,19 @@ nlohmann::json DerivationOutput::toJSON( }, [&](const DerivationOutput::CAFixed & dof) { res["path"] = store.printStorePath(dof.path(store, drvName, outputName)); - res["hashAlgo"] = dof.ca.printMethodAlgo(); + res["method"] = std::string { dof.ca.method.render() }; + res["hashAlgo"] = printHashAlgo(dof.ca.hash.algo); res["hash"] = dof.ca.hash.to_string(HashFormat::Base16, false); // FIXME print refs? }, [&](const DerivationOutput::CAFloating & dof) { - res["hashAlgo"] = std::string { dof.method.renderPrefix() } + printHashAlgo(dof.hashAlgo); + res["method"] = std::string { dof.method.render() }; + res["hashAlgo"] = printHashAlgo(dof.hashAlgo); }, [&](const DerivationOutput::Deferred &) {}, [&](const DerivationOutput::Impure & doi) { - res["hashAlgo"] = std::string { doi.method.renderPrefix() } + printHashAlgo(doi.hashAlgo); + res["method"] = std::string { doi.method.render() }; + res["hashAlgo"] = printHashAlgo(doi.hashAlgo); res["impure"] = true; }, }, raw); @@ -1245,12 +1248,13 @@ DerivationOutput DerivationOutput::fromJSON( keys.insert(key); auto methodAlgo = [&]() -> std::pair { - auto & str = getString(valueAt(json, "hashAlgo")); - std::string_view s = str; - ContentAddressMethod method = ContentAddressMethod::parsePrefix(s); + auto & method_ = getString(valueAt(json, "method")); + ContentAddressMethod method = ContentAddressMethod::parse(method_); if (method == TextIngestionMethod {}) xpSettings.require(Xp::DynamicDerivations); - auto hashAlgo = parseHashAlgo(s); + + auto & hashAlgo_ = getString(valueAt(json, "hashAlgo")); + auto hashAlgo = parseHashAlgo(hashAlgo_); return { std::move(method), std::move(hashAlgo) }; }; @@ -1260,7 +1264,7 @@ DerivationOutput DerivationOutput::fromJSON( }; } - else if (keys == (std::set { "path", "hashAlgo", "hash" })) { + else if (keys == (std::set { "path", "method", "hashAlgo", "hash" })) { auto [method, hashAlgo] = methodAlgo(); auto dof = DerivationOutput::CAFixed { .ca = ContentAddress { @@ -1273,7 +1277,7 @@ DerivationOutput DerivationOutput::fromJSON( return dof; } - else if (keys == (std::set { "hashAlgo" })) { + else if (keys == (std::set { "method", "hashAlgo" })) { xpSettings.require(Xp::CaDerivations); auto [method, hashAlgo] = methodAlgo(); return DerivationOutput::CAFloating { @@ -1286,7 +1290,7 @@ DerivationOutput DerivationOutput::fromJSON( return DerivationOutput::Deferred {}; } - else if (keys == (std::set { "hashAlgo", "impure" })) { + else if (keys == (std::set { "method", "hashAlgo", "impure" })) { xpSettings.require(Xp::ImpureDerivations); auto [method, hashAlgo] = methodAlgo(); return DerivationOutput::Impure { diff --git a/src/nix/flake.md b/src/nix/flake.md index 661dd2f73335..2f43d02640d7 100644 --- a/src/nix/flake.md +++ b/src/nix/flake.md @@ -134,7 +134,9 @@ The following generic flake reference attributes are supported: repository or tarball. The default is the root directory of the flake. -* `narHash`: The hash of the NAR serialisation (in SRI format) of the +* `narHash`: The hash of the + [Nix Archive (NAR) serialisation][Nix Archive] + (in SRI format) of the contents of the flake. This is useful for flake types such as tarballs that lack a unique content identifier such as a Git commit hash. @@ -423,8 +425,9 @@ The following attributes are supported in `flake.nix`: * `lastModified`: The commit time of the revision `rev` as an integer denoting the number of seconds since 1970. - * `narHash`: The SHA-256 (in SRI format) of the NAR serialization of - the flake's source tree. + * `narHash`: The SHA-256 (in SRI format) of the + [Nix Archive (NAR) serialisation][Nix Archive] + NAR serialization of the flake's source tree. The value returned by the `outputs` function must be an attribute set. The attributes can have arbitrary values; however, various @@ -703,4 +706,5 @@ will not look at the lock files of dependencies. However, lock file generation itself *does* use the lock files of dependencies by default. +[Nix Archive]: @docroot@/store/file-system-object/content-address.md#serial-nix-archive )"" diff --git a/src/nix/nar-cat.md b/src/nix/nar-cat.md index 55c481a28c5c..1131eb2bf136 100644 --- a/src/nix/nar-cat.md +++ b/src/nix/nar-cat.md @@ -2,7 +2,7 @@ R""( # Examples -* List a file in a NAR and pipe it through `gunzip`: +* List a file in a [Nix Archive (NAR)][Nix Archive] and pipe it through `gunzip`: ```console # nix nar cat ./hello.nar /share/man/man1/hello.1.gz | gunzip @@ -16,4 +16,5 @@ R""( This command prints on standard output the contents of the regular file *path* inside the NAR file *nar*. +[Nix Archive]: @docroot@/store/file-system-object/content-address.md#serial-nix-archive )"" diff --git a/src/nix/nar-dump-path.md b/src/nix/nar-dump-path.md index de82202decd0..4676e4fef9d0 100644 --- a/src/nix/nar-dump-path.md +++ b/src/nix/nar-dump-path.md @@ -2,7 +2,7 @@ R""( # Examples -* To serialise directory `foo` as a NAR: +* To serialise directory `foo` as a [Nix Archive (NAR)][Nix Archive]: ```console # nix nar pack ./foo > foo.nar @@ -10,8 +10,10 @@ R""( # Description -This command generates a NAR file containing the serialisation of +This command generates a [Nix Archive (NAR)][Nix Archive] file containing the serialisation of *path*, which must contain only regular files, directories and symbolic links. The NAR is written to standard output. +[Nix Archive]: @docroot@/store/file-system-object/content-address.md#serial-nix-archive + )"" diff --git a/src/nix/nar-ls.md b/src/nix/nar-ls.md index 5a03c5d828e7..27c4b97e62ad 100644 --- a/src/nix/nar-ls.md +++ b/src/nix/nar-ls.md @@ -2,7 +2,7 @@ R""( # Examples -* To list a specific file in a NAR: +* To list a specific file in a [NAR][Nix Archive]: ```console # nix nar ls --long ./hello.nar /bin/hello @@ -19,6 +19,8 @@ R""( # Description -This command shows information about a *path* inside NAR file *nar*. +This command shows information about a *path* inside [Nix Archive (NAR)][Nix Archive] file *nar*. + +[Nix Archive]: @docroot@/store/file-system-object/content-address.md#serial-nix-archive )"" diff --git a/src/nix/nar.md b/src/nix/nar.md index a83b5c7647db..b0f70ce93a3d 100644 --- a/src/nix/nar.md +++ b/src/nix/nar.md @@ -3,11 +3,14 @@ R""( # Description `nix nar` provides several subcommands for creating and inspecting -*Nix Archives* (NARs). +[*Nix Archives* (NARs)][Nix Archive]. # File format -For the definition of the NAR file format, see Figure 5.2 in -https://edolstra.github.io/pubs/phd-thesis.pdf. +For the definition of the Nix Archive file format, see +[within the protocols chapter](@docroot@/protocols/nix-archive.md) +of the manual. + +[Nix Archive]: @docroot@/store/file-system-object/content-address.md#serial-nix-archive )"" diff --git a/src/nix/store-dump-path.md b/src/nix/store-dump-path.md index 56e2174b6a8c..21467ff329ec 100644 --- a/src/nix/store-dump-path.md +++ b/src/nix/store-dump-path.md @@ -17,7 +17,9 @@ R""( # Description -This command generates a NAR file containing the serialisation of the +This command generates a [Nix Archive (NAR)][Nix Archive] file containing the serialisation of the store path [*installable*](./nix.md#installables). The NAR is written to standard output. +[Nix Archive]: @docroot@/store/file-system-object/content-address.md#serial-nix-archive + )"" diff --git a/src/nix/verify.md b/src/nix/verify.md index e1d55eab4577..ae0b0acd68a2 100644 --- a/src/nix/verify.md +++ b/src/nix/verify.md @@ -46,4 +46,6 @@ The exit status of this command is the sum of the following values: * **4** if any path couldn't be verified for any other reason (such as an I/O error). +[Nix Archive]: @docroot@/store/file-system-object/content-address.md#serial-nix-archive + )"" diff --git a/tests/unit/libstore/data/derivation/output-caFixedFlat.json b/tests/unit/libstore/data/derivation/output-caFixedFlat.json index fe000ea36e3d..7001ea0a9fbe 100644 --- a/tests/unit/libstore/data/derivation/output-caFixedFlat.json +++ b/tests/unit/libstore/data/derivation/output-caFixedFlat.json @@ -1,5 +1,6 @@ { "hash": "894517c9163c896ec31a2adbd33c0681fd5f45b2c0ef08a64c92a03fb97f390f", "hashAlgo": "sha256", + "method": "flat", "path": "/nix/store/rhcg9h16sqvlbpsa6dqm57sbr2al6nzg-drv-name-output-name" } diff --git a/tests/unit/libstore/data/derivation/output-caFixedNAR.json b/tests/unit/libstore/data/derivation/output-caFixedNAR.json index 1afd602236bd..54eb306e672f 100644 --- a/tests/unit/libstore/data/derivation/output-caFixedNAR.json +++ b/tests/unit/libstore/data/derivation/output-caFixedNAR.json @@ -1,5 +1,6 @@ { "hash": "894517c9163c896ec31a2adbd33c0681fd5f45b2c0ef08a64c92a03fb97f390f", - "hashAlgo": "r:sha256", + "hashAlgo": "sha256", + "method": "nar", "path": "/nix/store/c015dhfh5l0lp6wxyvdn7bmwhbbr6hr9-drv-name-output-name" } diff --git a/tests/unit/libstore/data/derivation/output-caFixedText.json b/tests/unit/libstore/data/derivation/output-caFixedText.json index 0b2cc8bbc423..e8a65186049d 100644 --- a/tests/unit/libstore/data/derivation/output-caFixedText.json +++ b/tests/unit/libstore/data/derivation/output-caFixedText.json @@ -1,5 +1,6 @@ { "hash": "894517c9163c896ec31a2adbd33c0681fd5f45b2c0ef08a64c92a03fb97f390f", - "hashAlgo": "text:sha256", + "hashAlgo": "sha256", + "method": "text", "path": "/nix/store/6s1zwabh956jvhv4w9xcdb5jiyanyxg1-drv-name-output-name" } diff --git a/tests/unit/libstore/data/derivation/output-caFloating.json b/tests/unit/libstore/data/derivation/output-caFloating.json index 9115de851a11..8b9b5f68196c 100644 --- a/tests/unit/libstore/data/derivation/output-caFloating.json +++ b/tests/unit/libstore/data/derivation/output-caFloating.json @@ -1,3 +1,4 @@ { - "hashAlgo": "r:sha256" + "hashAlgo": "sha256", + "method": "nar" } diff --git a/tests/unit/libstore/data/derivation/output-impure.json b/tests/unit/libstore/data/derivation/output-impure.json index 62b61cdcae71..bec03702b16b 100644 --- a/tests/unit/libstore/data/derivation/output-impure.json +++ b/tests/unit/libstore/data/derivation/output-impure.json @@ -1,4 +1,5 @@ { - "hashAlgo": "r:sha256", - "impure": true + "hashAlgo": "sha256", + "impure": true, + "method": "nar" }