Merge pull request #27156 from rhatdan/inspect

Add artifact fallback to podman inspect command
This commit is contained in:
openshift-merge-bot[bot]
2025-10-02 12:16:11 +00:00
committed by GitHub
7 changed files with 89 additions and 10 deletions

View File

@ -1476,6 +1476,10 @@ func getEntityType(cmd *cobra.Command, args []string, o any) any {
if networks, _ := getNetworks(cmd, args[0], completeDefault); len(networks) > 0 {
return &entities.NetworkInspectReport{}
}
// artifact logic
if artifacts, _ := getArtifacts(cmd, args[0]); len(artifacts) > 0 {
return &entities.ArtifactInspectReport{}
}
return o
}
@ -1641,7 +1645,7 @@ func AutocompleteImageSort(_ *cobra.Command, _ []string, _ string) ([]string, co
// AutocompleteInspectType - Autocomplete inspect type options.
func AutocompleteInspectType(_ *cobra.Command, _ []string, _ string) ([]string, cobra.ShellCompDirective) {
types := []string{AllType, ContainerType, ImageType, NetworkType, PodType, VolumeType}
types := []string{AllType, ArtifactType, ContainerType, ImageType, NetworkType, PodType, VolumeType}
return types, cobra.ShellCompDirectiveNoFileComp
}

View File

@ -3,6 +3,8 @@ package common
const (
// AllType can be of type ImageType or ContainerType.
AllType = "all"
// ArtifactType is the artifact type.
ArtifactType = "artifact"
// ContainerType is the container type.
ContainerType = "container"
// ImageType is the image type.

View File

@ -12,6 +12,7 @@ var (
inspectDescription = `Displays the low-level information on an object identified by name or ID.
For more inspection options, see:
podman artifact inspect
podman container inspect
podman image inspect
podman network inspect
@ -20,7 +21,7 @@ var (
// Command: podman _inspect_ Object_ID
inspectCmd = &cobra.Command{
Use: "inspect [options] {CONTAINER|IMAGE|POD|NETWORK|VOLUME} [...]",
Use: "inspect [options] {ARTIFACT|CONTAINER|IMAGE|POD|NETWORK|VOLUME} [...]",
Short: "Display the configuration of object denoted by ID",
RunE: inspectExec,
Long: inspectDescription,
@ -28,6 +29,7 @@ var (
ValidArgsFunction: common.AutocompleteInspect,
Example: `podman inspect fedora
podman inspect --type image fedora
podman inspect --type artifact quay.io/myimage/myartifact:latest
podman inspect CtrID ImgID
podman inspect --format "imageId: {{.Id}} size: {{.Size}}" fedora`,
}

View File

@ -151,9 +151,18 @@ func (i *inspector) inspect(namesOrIDs []string) error {
for i := range volumeData {
data = append(data, volumeData[i])
}
case common.ArtifactType:
for _, name := range namesOrIDs {
artifactData, err := i.imageEngine.ArtifactInspect(ctx, name, entities.ArtifactInspectOptions{})
if err != nil {
errs = append(errs, err)
continue
}
data = append(data, artifactData)
}
default:
return fmt.Errorf("invalid type %q: must be %q, %q, %q, %q, %q, or %q", i.options.Type,
common.ImageType, common.ContainerType, common.PodType, common.NetworkType, common.VolumeType, common.AllType)
return fmt.Errorf("invalid type %q: must be %q, %q, %q, %q, %q, %q, or %q", i.options.Type,
common.ImageType, common.ContainerType, common.PodType, common.NetworkType, common.VolumeType, common.ArtifactType, common.AllType)
}
// Always print an empty array
if data == nil {
@ -236,6 +245,11 @@ func (i *inspector) inspectAll(ctx context.Context, namesOrIDs []string) ([]any,
data = append(data, podData[0])
continue
}
artifactData, err := i.imageEngine.ArtifactInspect(ctx, name, entities.ArtifactInspectOptions{})
if err == nil {
data = append(data, artifactData)
continue
}
if len(errs) > 0 {
allErrs = append(allErrs, fmt.Errorf("no such object: %q", name))
continue

View File

@ -1,19 +1,20 @@
% podman-inspect 1
## NAME
podman\-inspect - Display a container, image, volume, network, or pod's configuration
podman\-inspect - Display artifact, container, image, volume, network, or pod's configuration
## SYNOPSIS
**podman inspect** [*options*] *name* [...]
## DESCRIPTION
This displays the low-level information on containers and images identified by name or ID. By default, this renders
all results in a JSON array. If the inspect type is all, the order of inspection is: containers, images, volumes, network, pods.
This displays the low-level information on artifacts, containers, and images identified by name or ID. By default, this renders
all results in a JSON array. If the inspect type is all, the order of inspection is: containers, images, volumes, network, pods, artifacts.
If a container has the same name as an image, then the container JSON is returned, and so on.
If a format is specified, the given template is executed for each result.
For more inspection options, see also
[podman-artifact-inspect(1)](podman-artifact-inspect.1.md),
[podman-container-inspect(1)](podman-container-inspect.1.md),
[podman-image-inspect(1)](podman-image-inspect.1.md),
[podman-network-inspect(1)](podman-network-inspect.1.md),
@ -35,7 +36,7 @@ In addition to normal output, display the total file size if the type is a conta
#### **--type**, **-t**=*type*
Return JSON for the specified type. Type can be 'container', 'image', 'volume', 'network', 'pod', or 'all' (default: all)
Return JSON for the specified type. Type can be 'artifact', 'container', 'image', 'volume', 'network', 'pod', or 'all' (default: all)
(Only meaningful when invoked as *podman inspect*)
## EXAMPLES
@ -164,8 +165,22 @@ Inspect the specified network for the `Name` format specifier:
myNetwork
```
Inspect the specified artifact:
```
# podman inspect quay.io/myimage/myartifact:latest --type artifact
{
"Manifest": {
"schemaVersion": 2,
"mediaType": "application/vnd.oci.image.manifest.v1+json",
...
},
"Name": "quay.io/myimage/myartifact:latest",
"Digest": "sha256:..."
}
```
## SEE ALSO
**[podman(1)](podman.1.md)**, **[podman-container-inspect(1)](podman-container-inspect.1.md)**, **[podman-image-inspect(1)](podman-image-inspect.1.md)**, **[podman-network-inspect(1)](podman-network-inspect.1.md)**, **[podman-pod-inspect(1)](podman-pod-inspect.1.md)**, **[podman-volume-inspect(1)](podman-volume-inspect.1.md)**
**[podman(1)](podman.1.md)**, **[podman-artifact-inspect(1)](podman-artifact-inspect.1.md)**, **[podman-container-inspect(1)](podman-container-inspect.1.md)**, **[podman-image-inspect(1)](podman-image-inspect.1.md)**, **[podman-network-inspect(1)](podman-network-inspect.1.md)**, **[podman-pod-inspect(1)](podman-pod-inspect.1.md)**, **[podman-volume-inspect(1)](podman-volume-inspect.1.md)**
## HISTORY
July 2017, Originally compiled by Dan Walsh <dwalsh@redhat.com>

View File

@ -367,7 +367,7 @@ the exit codes follow the `chroot` standard, see below:
| [podman-import(1)](podman-import.1.md) | Import a tarball and save it as a filesystem image. |
| [podman-info(1)](podman-info.1.md) | Display Podman related system information. |
| [podman-init(1)](podman-init.1.md) | Initialize one or more containers |
| [podman-inspect(1)](podman-inspect.1.md) | Display a container, image, volume, network, or pod's configuration. |
| [podman-inspect(1)](podman-inspect.1.md) | Display artifact, container, image, volume, network, or pod's configuration. |
| [podman-kill(1)](podman-kill.1.md) | Kill the main process in one or more containers. |
| [podman-load(1)](podman-load.1.md) | Load image(s) from a tar archive into container storage. |
| [podman-login(1)](podman-login.1.md) | Log in to a container registry. |

View File

@ -597,4 +597,46 @@ var _ = Describe("Podman inspect", func() {
Expect(session.OutputToString()).To(ContainSubstring(commandNotFound))
})
It("podman inspect artifact", func() {
artifactFile, err := createArtifactFile(1024)
Expect(err).ToNot(HaveOccurred())
artifactName := "localhost/test/myartifact"
add := podmanTest.Podman([]string{"artifact", "add", artifactName, artifactFile})
add.WaitWithDefaultTimeout()
Expect(add).Should(ExitCleanly())
// Test explicit artifact type
inspect := podmanTest.Podman([]string{"inspect", "--type", "artifact", artifactName})
inspect.WaitWithDefaultTimeout()
Expect(inspect).Should(ExitCleanly())
Expect(inspect.OutputToString()).To(BeValidJSON())
// Test fallback to artifact when no other object type matches
inspect = podmanTest.Podman([]string{"inspect", artifactName})
inspect.WaitWithDefaultTimeout()
Expect(inspect).Should(ExitCleanly())
Expect(inspect.OutputToString()).To(BeValidJSON())
// Verify that the output contains artifact-specific fields
Expect(inspect.OutputToString()).To(ContainSubstring("Manifest"))
Expect(inspect.OutputToString()).To(ContainSubstring("Digest"))
// Test format with artifact-specific fields
inspect = podmanTest.Podman([]string{"inspect", "--format", "{{.Name}}", artifactName})
inspect.WaitWithDefaultTimeout()
Expect(inspect).Should(ExitCleanly())
Expect(inspect.OutputToString()).To(Equal(artifactName))
inspect2 := podmanTest.Podman([]string{"inspect", "--format", "{{.Digest}}", artifactName})
inspect2.WaitWithDefaultTimeout()
Expect(inspect2).Should(ExitCleanly())
Expect(inspect2.OutputToString()).To(ContainSubstring("sha256:"))
// Clean up
rm := podmanTest.Podman([]string{"artifact", "rm", artifactName})
rm.WaitWithDefaultTimeout()
Expect(rm).Should(ExitCleanly())
})
})