1
1
Fork 0
mirror of https://github.com/NixOS/nix.git synced 2025-11-08 19:46:02 +01:00

Convert store path info JSON docs to formal JSON Schema, and test

This continues the work for formalizing our current JSON docs. Note that
in the process, a few bugs were caught:

 - `closureSize` was repeated twice, forgot `closureDownloadSize`

 - `file*` fields should be `download*`. They are in fact called that in
   the line-oriented `.narinfo` file, but were renamed in the JSON
   format.
This commit is contained in:
John Ericson 2025-10-28 13:24:05 -04:00
parent f1d4fab1e5
commit 6280905638
13 changed files with 327 additions and 90 deletions

View file

@ -38,6 +38,8 @@ mkMesonDerivation (finalAttrs: {
../../src/libstore-tests/data/content-address ../../src/libstore-tests/data/content-address
../../src/libstore-tests/data/store-path ../../src/libstore-tests/data/store-path
../../src/libstore-tests/data/derived-path ../../src/libstore-tests/data/derived-path
../../src/libstore-tests/data/path-info
../../src/libstore-tests/data/nar-info
# Too many different types of files to filter for now # Too many different types of files to filter for now
../../doc/manual ../../doc/manual
./. ./.

View file

@ -1,6 +1,6 @@
{{#include derivation-v3-fixed.md}} {{#include derivation-v3-fixed.md}}
<!-- <!-- need to convert YAML to JSON first
## Raw Schema ## Raw Schema
[JSON Schema for Derivation v3](schema/derivation-v3.json) [JSON Schema for Derivation v3](schema/derivation-v3.json)

View file

@ -26,7 +26,7 @@
{{#include schema/hash-v1/blake3-base64.json}} {{#include schema/hash-v1/blake3-base64.json}}
``` ```
<!-- <!-- need to convert YAML to JSON first
## Raw Schema ## Raw Schema
[JSON Schema for Hash v1](schema/hash-v1.json) [JSON Schema for Hash v1](schema/hash-v1.json)

View file

@ -12,6 +12,7 @@ schemas = [
'hash-v1', 'hash-v1',
'content-address-v1', 'content-address-v1',
'store-path-v1', 'store-path-v1',
'store-object-info-v1',
'derivation-v3', 'derivation-v3',
'deriving-path-v1', 'deriving-path-v1',
] ]

View file

@ -0,0 +1 @@
../../../../../../src/libstore-tests/data/nar-info

View file

@ -0,0 +1 @@
../../../../../../src/libstore-tests/data/path-info

View file

@ -0,0 +1,235 @@
"$schema": "http://json-schema.org/draft-07/schema"
"$id": "https://nix.dev/manual/nix/latest/protocols/json/schema/store-object-info-v1.json"
title: Store Object Info
description: |
Information about a [store object](@docroot@/store/store-object.md).
This schema describes the JSON representation of store object metadata as returned by commands like [`nix path-info --json`](@docroot@/command-ref/new-cli/nix3-path-info.md).
> **Warning**
>
> This JSON format is currently
> [**experimental**](@docroot@/development/experimental-features.md#xp-feature-nix-command)
> and subject to change.
### Field Categories
Store object information can come in a few different variations.
Firstly, "impure" fields, which contain non-intrinsic information about the store object, may or may not be included.
Second, binary cache stores have extra non-intrinsic infomation about the store objects they contain.
Thirdly, [`nix path-info --json --closure-size`](@docroot@/command-ref/new-cli/nix3-path-info.html#opt-closure-size) can compute some extra information about not just the single store object in question, but the store object and its [closure](@docroot@/glossary.md#gloss-closure).
The impure and NAR fields are grouped into separate variants below.
See their descriptions for additional information.
The closure fields however as just included as optional fields, to avoid a combinatorial explosion of variants.
oneOf:
- $ref: "#/$defs/base"
- $ref: "#/$defs/impure"
- $ref: "#/$defs/narInfo"
$defs:
base:
title: Store Object Info
description: |
Basic store object metadata containing only intrinsic properties.
This is the minimal set of fields that describe what a store object contains.
type: object
required:
- narHash
- narSize
- references
- ca
properties:
path:
type: string
title: Store Path
description: |
[Store path](@docroot@/store/store-path.md) to the given store object.
Note: This field may not be present in all contexts, such as when the path is used as the key and the the store object info the value in map.
narHash:
type: string
title: NAR Hash
description: |
Hash of the [file system object](@docroot@/store/file-system-object.md) part of the store object when serialized as a [Nix Archive](@docroot@/store/file-system-object/content-address.md#serial-nix-archive).
narSize:
type: integer
minimum: 0
title: NAR Size
description: |
Size of the [file system object](@docroot@/store/file-system-object.md) part of the store object when serialized as a [Nix Archive](@docroot@/store/file-system-object/content-address.md#serial-nix-archive).
references:
type: array
title: References
description: |
An array of [store paths](@docroot@/store/store-path.md), possibly including this one.
items:
type: string
ca:
type: ["string", "null"]
title: Content Address
description: |
If the store object is [content-addressed](@docroot@/store/store-object/content-address.md),
this is the content address of this store object's file system object, used to compute its store path.
Otherwise (i.e. if it is [input-addressed](@docroot@/glossary.md#gloss-input-addressed-store-object)), this is `null`.
additionalProperties: false
impure:
title: Store Object Info with Impure Fields
description: |
Store object metadata including impure fields that are not *intrinsic* properties.
In other words, the same store object in different stores could have different values for these impure fields.
type: object
required:
- narHash
- narSize
- references
- ca
# impure
- deriver
- registrationTime
- ultimate
- signatures
properties:
path: { $ref: "#/$defs/base/properties/path" }
narHash: { $ref: "#/$defs/base/properties/narHash" }
narSize: { $ref: "#/$defs/base/properties/narSize" }
references: { $ref: "#/$defs/base/properties/references" }
ca: { $ref: "#/$defs/base/properties/ca" }
deriver:
type: ["string", "null"]
title: Deriver
description: |
If known, the path to the [store derivation](@docroot@/glossary.md#gloss-store-derivation) from which this store object was produced.
Otherwise `null`.
> This is an "impure" field that may not be included in certain contexts.
registrationTime:
type: ["integer", "null"]
title: Registration Time
description: |
If known, when this derivation was added to the store (Unix timestamp).
Otherwise `null`.
> This is an "impure" field that may not be included in certain contexts.
ultimate:
type: boolean
title: Ultimate
description: |
Whether this store object is trusted because we built it ourselves, rather than substituted a build product from elsewhere.
> This is an "impure" field that may not be included in certain contexts.
signatures:
type: array
title: Signatures
description: |
Signatures claiming that this store object is what it claims to be.
Not relevant for [content-addressed](@docroot@/store/store-object/content-address.md) store objects,
but useful for [input-addressed](@docroot@/glossary.md#gloss-input-addressed-store-object) store objects.
> This is an "impure" field that may not be included in certain contexts.
items:
type: string
# Computed closure fields
closureSize:
type: integer
minimum: 0
title: Closure Size
description: |
The total size of this store object and every other object in its [closure](@docroot@/glossary.md#gloss-closure).
> This field is not stored at all, but computed by traversing the other fields across all the store objects in a closure.
additionalProperties: false
narInfo:
title: Store Object Info with Impure fields and NAR Info
description: |
The store object info in the "binary cache" family of Nix store type contain extra information pertaining to *downloads* of the store object in question.
(This store info is called "NAR info", since the downloads take the form of [Nix Archives](@docroot@/store/file-system-object/content-address.md#serial-nix-archive, and the metadata is served in a file with a `.narinfo` extension.)
This download information, being specific to how the store object happens to be stored and transferred, is also considered to be non-intrinsic / impure.
type: object
required:
- narHash
- narSize
- references
- ca
# impure
- deriver
- registrationTime
- ultimate
- signatures
# nar
- url
- compression
- downloadHash
- downloadSize
properties:
path: { $ref: "#/$defs/base/properties/path" }
narHash: { $ref: "#/$defs/base/properties/narHash" }
narSize: { $ref: "#/$defs/base/properties/narSize" }
references: { $ref: "#/$defs/base/properties/references" }
ca: { $ref: "#/$defs/base/properties/ca" }
deriver: { $ref: "#/$defs/impure/properties/deriver" }
registrationTime: { $ref: "#/$defs/impure/properties/registrationTime" }
ultimate: { $ref: "#/$defs/impure/properties/ultimate" }
signatures: { $ref: "#/$defs/impure/properties/signatures" }
closureSize: { $ref: "#/$defs/impure/properties/closureSize" }
url:
type: string
title: URL
description: |
Where to download a compressed archive of the file system objects of this store object.
> This is an impure "`.narinfo`" field that may not be included in certain contexts.
compression:
type: string
title: Compression
description: |
The compression format that the archive is in.
> This is an impure "`.narinfo`" field that may not be included in certain contexts.
downloadHash:
type: string
title: Download Hash
description: |
A digest for the compressed archive itself, as opposed to the data contained within.
> This is an impure "`.narinfo`" field that may not be included in certain contexts.
downloadSize:
type: integer
minimum: 0
title: Download Size
description: |
The size of the compressed archive itself.
> This is an impure "`.narinfo`" field that may not be included in certain contexts.
closureDownloadSize:
type: integer
minimum: 0
title: Closure Download Size
description: |
The total size of the compressed archive itself for this object, and the compressed archive of every object in this object's [closure](@docroot@/glossary.md#gloss-closure).
> This is an impure "`.narinfo`" field that may not be included in certain contexts.
> This field is not stored at all, but computed by traversing the other fields across all the store objects in a closure.
additionalProperties: false

View file

@ -1,102 +1,45 @@
# Store object info JSON format {{#include store-object-info-v1-fixed.md}}
> **Warning** ## Examples
>
> This JSON format is currently
> [**experimental**](@docroot@/development/experimental-features.md#xp-feature-nix-command)
> and subject to change.
Info about a [store object]. ### Minimal store object (content-addressed)
* `path`: ```json
{{#include schema/store-object-info-v1/pure.json}}
```
[Store path][store path] to the given store object. ### Store object with impure fields
* `narHash`: ```json
{{#include schema/store-object-info-v1/impure.json}}
```
Hash of the [file system object] part of the store object when serialized as a [Nix Archive]. ### Minimal store object (empty)
* `narSize`: ```json
{{#include schema/store-object-info-v1/empty_pure.json}}
```
Size of the [file system object] part of the store object when serialized as a [Nix Archive]. ### Store object with all impure fields
* `references`: ```json
{{#include schema/store-object-info-v1/empty_impure.json}}
```
An array of [store paths][store path], possibly including this one. ### NAR info (minimal)
* `ca`: ```json
{{#include schema/nar-info-v1/pure.json}}
```
If the store object is [content-addressed], ### NAR info (with binary cache fields)
this is the content address of this store object's file system object, used to compute its store path.
Otherwise (i.e. if it is [input-addressed]), this is `null`.
[store path]: @docroot@/store/store-path.md ```json
[file system object]: @docroot@/store/file-system-object.md {{#include schema/nar-info-v1/impure.json}}
[Nix Archive]: @docroot@/store/file-system-object/content-address.md#serial-nix-archive ```
## Impure fields <!-- need to convert YAML to JSON first
## Raw Schema
These are not intrinsic properties of the store object. [JSON Schema for Store Object Info v1](schema/store-object-info-v1.json)
In other words, the same store object residing in different store could have different values for these properties. -->
* `deriver`:
If known, the path to the [store derivation] from which this store object was produced.
Otherwise `null`.
[store derivation]: @docroot@/glossary.md#gloss-store-derivation
* `registrationTime` (optional):
If known, when this derivation was added to the store.
Otherwise `null`.
* `ultimate`:
Whether this store object is trusted because we built it ourselves, rather than substituted a build product from elsewhere.
* `signatures`:
Signatures claiming that this store object is what it claims to be.
Not relevant for [content-addressed] store objects,
but useful for [input-addressed] store objects.
[content-addressed]: @docroot@/store/store-object/content-address.md
[input-addressed]: @docroot@/glossary.md#gloss-input-addressed-store-object
### `.narinfo` extra fields
This meta data is specific to the "binary cache" family of Nix store types.
This information is not intrinsic to the store object, but about how it is stored.
* `url`:
Where to download a compressed archive of the file system objects of this store object.
* `compression`:
The compression format that the archive is in.
* `fileHash`:
A digest for the compressed archive itself, as opposed to the data contained within.
* `fileSize`:
The size of the compressed archive itself.
## Computed closure fields
These fields are not stored at all, but computed by traversing the other fields across all the store objects in a [closure].
* `closureSize`:
The total size of the compressed archive itself for this object, and the compressed archive of every object in this object's [closure].
### `.narinfo` extra fields
* `closureSize`:
The total size of this store object and every other object in its [closure].
[closure]: @docroot@/glossary.md#gloss-closure

View file

@ -8,7 +8,7 @@
{{#include schema/store-path-v1/simple.json}} {{#include schema/store-path-v1/simple.json}}
``` ```
<!-- <!-- need to convert YAML to JSON first
## Raw Schema ## Raw Schema
[JSON Schema for Store Path v1](schema/store-path-v1.json) [JSON Schema for Store Path v1](schema/store-path-v1.json)

View file

@ -76,6 +76,56 @@ schemas = [
'single_built_built.json', 'single_built_built.json',
], ],
}, },
# Match overall
{
'stem' : 'store-object-info',
'schema' : schema_dir / 'store-object-info-v1.yaml',
'files' : [
'pure.json',
'impure.json',
'empty_pure.json',
'empty_impure.json',
],
},
{
'stem' : 'nar-info',
'schema' : schema_dir / 'store-object-info-v1.yaml',
'files' : [
'pure.json',
'impure.json',
],
},
# Match exact variant
{
'stem' : 'store-object-info',
'schema' : schema_dir / 'store-object-info-v1.yaml#/$defs/base',
'files' : [
'pure.json',
'empty_pure.json',
],
},
{
'stem' : 'store-object-info',
'schema' : schema_dir / 'store-object-info-v1.yaml#/$defs/impure',
'files' : [
'impure.json',
'empty_impure.json',
],
},
{
'stem' : 'nar-info',
'schema' : schema_dir / 'store-object-info-v1.yaml#/$defs/base',
'files' : [
'pure.json',
],
},
{
'stem' : 'nar-info',
'schema' : schema_dir / 'store-object-info-v1.yaml#/$defs/narInfo',
'files' : [
'impure.json',
],
},
] ]
# Validate each example against the schema # Validate each example against the schema

View file

@ -0,0 +1 @@
../../src/libstore-tests/data/nar-info

View file

@ -25,6 +25,8 @@ mkMesonDerivation (finalAttrs: {
../../src/libstore-tests/data/store-path ../../src/libstore-tests/data/store-path
../../src/libstore-tests/data/derivation ../../src/libstore-tests/data/derivation
../../src/libstore-tests/data/derived-path ../../src/libstore-tests/data/derived-path
../../src/libstore-tests/data/path-info
../../src/libstore-tests/data/nar-info
./. ./.
]; ];

View file

@ -0,0 +1 @@
../../src/libstore-tests/data/path-info