Skip to content

Commit a3f3230

Browse files
authored
docs: improve formatted output for oras discover (#1625)
Signed-off-by: feynmanzhou <feynmanzhou@microsoft.com>
1 parent 756d60f commit a3f3230

1 file changed

Lines changed: 202 additions & 23 deletions

File tree

docs/proposals/formatted-output.md

Lines changed: 202 additions & 23 deletions
Original file line numberDiff line numberDiff line change
@@ -234,7 +234,7 @@ For example, pull an artifact that contains multiple layers (files) and show the
234234
oras pull $REGISTRY/$REPO:$TAG --format go-template='{{toRawJson .}}'
235235
```
236236

237-
```
237+
```console
238238
{"reference":"localhost:5000/oras@sha256:7414904f07f515f48fe4afeaf876e3151039a81e7177b9c66e9e7ed6dd186111","files":[{"path":"/home/user/oras-install/sbom.spdx","reference":"localhost:5000/oras@sha256:7414904f07f515f48fe4afeaf876e3151039a81e7177b9c66e9e7ed6dd186222","mediaType":"application/vnd.oci.image.manifest.v1+json","digest":"sha256:7414904f07f515f48fe4afeaf876e3151039a81e7177b9c66e9e7ed6dd186222","size":820},{"path":"/home/user/oras-install/vul-scan.json","reference":"localhost:5000/oras@sha256:7414904f07f515f48fe4afeaf876e3151039a81e7177b9c66e9e7ed6dd18669b","mediaType":"application/vnd.oci.image.manifest.v1+json","digest":"sha256:7414904f07f515f48fe4afeaf876e3151039a81e7177b9c66e9e7ed6dd18669b","size":820}]}
239239
```
240240

@@ -318,6 +318,8 @@ oras attach $REGISTRY/$REPO:$TAG --artifact-type example/report-and-sbom vul-rep
318318

319319
### oras discover
320320

321+
#### Tree format of `oras discover` output
322+
321323
View an artifact's referrers. The default output should be listed in a tree view.
322324

323325
```bash
@@ -332,57 +334,234 @@ $REGISTRY/$REPO@sha256:a3785f78ab8547ae2710c89e627783cfa7ee7824d3468cae6835c9f4e
332334
└── sha256:50fd0dc107d84b5e7b402688000a7ed3aaf8a2692d5cb74da5277fa3c4cecf15
333335
```
334336

335-
View an artifact's referrers manifest in pretty JSON output. The following fields should be outputted:
337+
> [!NOTE]
338+
> The `--output` flag will be replaced by the `--format` flag. The `--output` flag SHOULD be marked as "deprecated" in ORAS with a warning message and will be removed in future releases.
339+
340+
If the referrers have child referrers, ORAS SHOULD show the manifest content of the subject image and all referrers recursively in all formatted outputs (`tree`, `JSON`, `go-template`). It ensures data consistency of different data formats in the output.
341+
342+
#### JSON output of `oras discover`
336343

337-
- `manifests`: the list of referrers
344+
When showing the subject image and all referrers' manifests recursively in a formatted JSON output, include the following fields:
345+
346+
- `reference`: full reference by digest of the subject image
347+
- `mediaType`: media type of the subject image
348+
- `digest`: digest of the subject image
349+
- `size`: subject image size in bytes
350+
- `referrers`: the list of referrers' manifest
338351
- `reference`: full reference by digest of the referrer
339352
- `mediaType`: media type of the referrer
340-
- `size`: referrer file size in bytes
341353
- `digest`: digest of the referrer
354+
- `size`: referrer file size in bytes
342355
- `artifactType`: artifact type of a referrer
343356
- `annotations`: contains arbitrary metadata in a referrer
357+
- `referrers`: the list of referrers' manifest
344358

345-
See an example:
359+
Here is the JSON Schema to describe the required fields of JSON output:
360+
361+
```json
362+
{
363+
"$schema": "https://json-schema.org/draft/2020-12/schema",
364+
"title": "JSON Output of Subject Image and All Referrers",
365+
"type": "object",
366+
"properties": {
367+
"reference": {
368+
"type": "string",
369+
"description": "Full reference by digest of the subject image"
370+
},
371+
"mediaType": {
372+
"type": "string",
373+
"description": "Media type of the subject image"
374+
},
375+
"digest": {
376+
"type": "string",
377+
"description": "Digest of the subject image"
378+
},
379+
"size": {
380+
"type": "integer",
381+
"minimum": 0,
382+
"description": "Size of the subject image in bytes"
383+
},
384+
"referrers": {
385+
"type": "array",
386+
"description": "List of referrers' manifests",
387+
"items": {
388+
"type": "object",
389+
"properties": {
390+
"reference": {
391+
"type": "string",
392+
"description": "Full reference by digest of the referrer"
393+
},
394+
"mediaType": {
395+
"type": "string",
396+
"description": "Media type of the referrer"
397+
},
398+
"digest": {
399+
"type": "string",
400+
"description": "Digest of the referrer"
401+
},
402+
"size": {
403+
"type": "integer",
404+
"minimum": 0,
405+
"description": "Referrer file size in bytes"
406+
},
407+
"artifactType": {
408+
"type": "string",
409+
"description": "Artifact type of the referrer"
410+
},
411+
"annotations": {
412+
"type": "object",
413+
"description": "Arbitrary metadata in a referrer",
414+
"additionalProperties": {
415+
"type": "string"
416+
}
417+
},
418+
"referrers": {
419+
"type": "array",
420+
"description": "List of nested referrers' manifests",
421+
"items": {
422+
"$ref": "#/properties/referrers/items"
423+
}
424+
}
425+
},
426+
"required": [
427+
"reference",
428+
"mediaType",
429+
"digest",
430+
"size",
431+
"artifactType"
432+
]
433+
}
434+
}
435+
},
436+
"required": ["reference", "mediaType", "digest", "size"],
437+
"additionalProperties": false
438+
}
439+
```
440+
441+
Here is the sample of a formatted JSON output:
346442

347443
```bash
348-
oras discover $REGISTRY/$REPO:v1 --format json
444+
oras discover localhost:5000/kubernetes/kubectl@sha256:bece4f4746a39cb39e38451c70fa5a1e5ea4fa20d4cca40136b51d9557918b01 --format json
349445
```
350446

351447
```json
352-
{
353-
"manifests": [
448+
"reference": "localhost:5000/kubernetes/kubectl@sha256:bece4f4746a39cb39e38451c70fa5a1e5ea4fa20d4cca40136b51d9557918b01",
449+
"mediaType": "application/vnd.docker.distribution.manifest.list.v2+json",
450+
"digest": "sha256:bece4f4746a39cb39e38451c70fa5a1e5ea4fa20d4cca40136b51d9557918b01",
451+
"size": 1788,
452+
"referrers": [
354453
{
355-
"reference": "$REGISTRY/$REPO@sha256:8dee8cb9a1334595545e3baf15c3eeed13c4b35ae08e3ab32e1df31fb152dc1d",
454+
"reference": "localhost:5000/kubernetes/kubectl@sha256:325129be79f416fe11a9ec44233cfa57f5d89434e6d37170f97e48f7904983e3",
356455
"mediaType": "application/vnd.oci.image.manifest.v1+json",
357-
"digest": "sha256:8dee8cb9a1334595545e3baf15c3eeed13c4b35ae08e3ab32e1df31fb152dc1d",
358-
"size": 739,
456+
"digest": "sha256:325129be79f416fe11a9ec44233cfa57f5d89434e6d37170f97e48f7904983e3",
457+
"size": 788,
359458
"annotations": {
360-
"io.cncf.notary.x509chain.thumbprint#S256": "[\"79e91aa1e109a16df87d200e493fd3d33c67253f76d41334d7f7c29c00ba55b3\"]",
361-
"org.opencontainers.image.created": "2024-01-01T10:32:55Z"
459+
"org.opencontainers.image.created": "2024-03-15T22:49:10Z",
460+
"vnd.oci.artifact.lifecycle.end-of-life.date": "2024-03-15"
362461
},
363-
"artifactType": "application/vnd.cncf.notary.signature"
462+
"artifactType": "application/vnd.oci.artifact.lifecycle",
463+
"referrers": [
464+
{
465+
"reference": "localhost:5000/kubernetes/kubectl@sha256:f520330e9f43c05859c532e67a25c9c765b144782ae7b872656192c27fd4e2dd",
466+
"mediaType": "application/vnd.oci.image.manifest.v1+json",
467+
"digest": "sha256:f520330e9f43c05859c532e67a25c9c765b144782ae7b872656192c27fd4e2dd",
468+
"size": 1080,
469+
"annotations": {
470+
"io.cncf.notary.x509chain.thumbprint#S256": "[430ecf0685f8018443f8418f5d7134b146f28862116114925713635d5703fb69,9b1894f223d934cbd6575af3c6e1f6096b9221a7da132185f5a5cdc92235b5dc,23ffe2b8bdb9a1711515d4cffda04bc7f793d513c76c243f1020507d8669b7db]",
471+
"org.opencontainers.image.created": "2024-03-15T22:54:42Z"
472+
},
473+
"artifactType": "application/vnd.cncf.notary.signature"
474+
}
475+
]
364476
},
365477
{
366-
"reference": "$REGISTRY/$REPO@sha256:50fd0dc107d84b5e7b402688000a7ed3aaf8a2692d5cb74da5277fa3c4cecf15",
478+
"reference": "localhost:5000/kubernetes/kubectl@sha256:a811606b09341bab4bbc0a4deb2c0cb709ec9702635cbe2d36b77d58359ec046",
367479
"mediaType": "application/vnd.oci.image.manifest.v1+json",
368-
"digest": "sha256:50fd0dc107d84b5e7b402688000a7ed3aaf8a2692d5cb74da5277fa3c4cecf15",
369-
"size": 739,
480+
"digest": "sha256:a811606b09341bab4bbc0a4deb2c0cb709ec9702635cbe2d36b77d58359ec046",
481+
"size": 747,
370482
"annotations": {
371-
"org.opencontainers.image.created": "2024-01-01T07:57:10Z"
483+
"org.opencontainers.image.created": "2024-01-18T18:12:41Z"
372484
},
373-
"artifactType": "sbom/example"
485+
"artifactType": "application/vnd.in-toto+json",
486+
"referrers": [
487+
{
488+
"reference": "localhost:5000/kubernetes/kubectl@sha256:04723fd7d00df77c6f226b907667396554bf9418dc48a7a04feb5ff24aa0b9ec",
489+
"mediaType": "application/vnd.oci.image.manifest.v1+json",
490+
"digest": "sha256:04723fd7d00df77c6f226b907667396554bf9418dc48a7a04feb5ff24aa0b9ec",
491+
"size": 1080,
492+
"annotations": {
493+
"io.cncf.notary.x509chain.thumbprint#S256": "[430ecf0685f8018443f8418f5d7134b146f28862116114925713635d5703fb69,9b1894f223d934cbd6575af3c6e1f6096b9221a7da132185f5a5cdc92235b5dc,23ffe2b8bdb9a1711515d4cffda04bc7f793d513c76c243f1020507d8669b7db]",
494+
"org.opencontainers.image.created": "2024-01-18T18:20:09Z"
495+
},
496+
"artifactType": "application/vnd.cncf.notary.signature"
497+
}
498+
]
374499
}
375500
]
376-
}
377501
```
378502

379-
> [!NOTE]
380-
> The `--format` flag will replace the existing `--output` flag. The `--output` will be marked as "deprecated" in ORAS v1.2.0 and will be removed in the future releases.
503+
#### Table format of `oras discover` output
504+
505+
The `oras discover --format table` command currently lists only direct referrers in a table format. This table view has limitations: it does not effectively represent the hierarchical artifact reference relationships of all referrers. Users can't differentiate the reference relationship between each referrer in a table format output. See current sample output as follows:
506+
507+
```console
508+
$ oras discover localhost:5000/kubectl:v1.29.1 --format table
509+
Discovered 4 artifacts referencing localhost:5000/kubectl:v1.29.1
510+
Digest: sha256:bece4f4746a39cb39e38451c70fa5a1e5ea4fa20d4cca40136b51d9557918b01
511+
512+
Artifact Type Digest
513+
application/vnd.microsoft.artifact.lifecycle sha256:325129be79f416fe11a9ec44233cfa57f5d89434e6d37170f97e48f7904983e3
514+
application/vnd.cncf.notary.signature sha256:f520330e9f43c05859c532e67a25c9c765b144782ae7b872656192c27fd4e2dd
515+
application/vnd.in-toto+json sha256:a811606b09341bab4bbc0a4deb2c0cb709ec9702635cbe2d36b77d58359ec046
516+
application/vnd.cncf.notary.signature sha256:f2098a230b6311edeb44ab2d6e5789372300d9b98be34c4d9477d3b9638a3bb1
517+
```
518+
519+
In contrast, the tree view offers a more structured and human-readable output by visually displaying relationships of each referrer. Given this advantage, the table view no longer provides significant value to users. This document proposes deprecating the `--format table` option. When user specifies `--format table` flag with `oras discover`, the warning message SHOULD be printed out as follows:
520+
521+
```console
522+
$ oras discover localhost:5000/kubectl:v1.29.1 --format table
523+
Warning: "table" option has been deprecated in the "--format" flag, and will be removed in a future release. Please switch to either JSON or tree format for more structured output.
524+
Discovered 4 artifacts referencing localhost:5000/kubectl:v1.29.1
525+
Digest: sha256:bece4f4746a39cb39e38451c70fa5a1e5ea4fa20d4cca40136b51d9557918b01
526+
527+
Artifact Type Digest
528+
application/vnd.microsoft.artifact.lifecycle sha256:325129be79f416fe11a9ec44233cfa57f5d89434e6d37170f97e48f7904983e3
529+
application/vnd.cncf.notary.signature sha256:f520330e9f43c05859c532e67a25c9c765b144782ae7b872656192c27fd4e2dd
530+
application/vnd.in-toto+json sha256:a811606b09341bab4bbc0a4deb2c0cb709ec9702635cbe2d36b77d58359ec046
531+
application/vnd.cncf.notary.signature sha256:f2098a230b6311edeb44ab2d6e5789372300d9b98be34c4d9477d3b9638a3bb1
532+
```
533+
#### Set the depth of listed referrers
534+
535+
By default, ORAS displays all referrers of a subject image. However, when a subject image has a complex referrer graph, this can lead to throttling or performance issues. To mitigate this, ORAS SHOULD introduce an experimental `--depth` flag for `oras discover`, allowing users to specify the maximum depth of referrers in the formatted output.
536+
537+
Assume there is a sample image with referrers spanning four levels. By using the `--depth` flag, you can display only the referrers within the third level in a tree view. This command will display the referrers up to the third level only, helping to limit the scope and improve performance when dealing with complex referrer graphs.
538+
539+
```bash
540+
oras discover localhost:5000/kubernetes/kubectl@sha256:bece4f4746a39cb39e38451c70fa5a1e5ea4fa20d4cca40136b51d9557918b01 --format tree --depth 3
541+
```
542+
543+
```console
544+
localhost:5000/kubernetes/kubectl@sha256:bece4f4746a39cb39e38451c70fa5a1e5ea4fa20d4cca40136b51d9557918b01
545+
├── application/vnd.oci.artifact.lifecycle
546+
│ └── sha256:325129be79f416fe11a9ec44233cfa57f5d89434e6d37170f97e48f7904983e3
547+
│ └── application/vnd.cncf.notary.signature
548+
│ └── sha256:f520330e9f43c05859c532e67a25c9c765b144782ae7b872656192c27fd4e2dd
549+
│ └── vnd/test-annotations
550+
│ └── sha256:d2cb66a53e4d77488df1f15701554ebb11ffa1cf6eb90f79afa33d3b172f11d2
551+
└── application/vnd.in-toto+json
552+
└── sha256:a811606b09341bab4bbc0a4deb2c0cb709ec9702635cbe2d36b77d58359ec046
553+
└── application/vnd.cncf.notary.signature
554+
└── sha256:04723fd7d00df77c6f226b907667396554bf9418dc48a7a04feb5ff24aa0b9ec
555+
└── vnd/test-annotations
556+
└── sha256:d2cb66a53e4d77488df1f15701554ebb11ffa1cf6eb90f79afa33d3b172f11d2
557+
```
381558

382559
## FAQ
383560

384561
**Q:** Why choose to use `--format` flag to enable JSON formatted output instead of extending the existing `--output` flag?
562+
385563
**A:** ORAS follows [GNU](https://www.gnu.org/prep/standards/html_node/Option-Table.html#Option-Table) design principles. ORAS uses `--output` to specify a file or directory content should be created within and `--format` to format the output into JSON or using the given Go template. Popular tools, like Docker, Podman, and Skopeo also follow this design principle within their formatted output feature.
386564

387565
**Q:** Why ORAS chooses [Go template](https://pkg.go.dev/text/template)?
388-
**A:** Go template is a powerful method to allow users to manipulate and customize output you want. It provides access to data objects and additional functions that are passed into the template engine programmatically. It also has some useful libraries that have strong functions for Go’s template language to manipulate the output data, such as [Sprig](https://masterminds.github.io/sprig/). The basic usage of Go template functions are easy to use.
566+
567+
**A:** Go template is a powerful method to allow users to manipulate and customize output you want. It provides access to data objects and additional functions that are passed into the template engine programmatically. It also has some useful libraries that have strong functions for Go’s template language to manipulate the output data, such as [Sprig](https://masterminds.github.io/sprig/). The basic usage of Go template functions are easy to use.

0 commit comments

Comments
 (0)