Skip to content

Commit 6405925

Browse files
committed
Add artifact fallback to podman inspect command
This commit implements automatic artifact fallback for the podman inspect command as requested in GitHub issue #27075. Changes made: - Add ArtifactType constant to cmd/podman/common/inspect.go - Update AutocompleteInspectType to include artifact type in completions - Add artifact case to main inspect switch statement for explicit --type artifact - Implement artifact fallback in inspectAll function for automatic detection - Update shell completion to recognize artifacts in getEntityType function - Update command help text, usage, and examples to include artifacts - Update podman-inspect.1.md man page with artifact documentation - Add comprehensive e2e tests for artifact inspect functionality The inspect command now automatically falls back to artifact inspection when no container, image, volume, network, or pod matches the specified name. Users can also explicitly use --type artifact for direct artifact inspection. This maintains backward compatibility while extending functionality to support the artifact object type seamlessly. Examples: podman inspect myartifact # Auto-detects artifact podman inspect --type artifact myartifact # Explicit artifact type podman inspect --format '{{.Name}}' myartifact # Format support Fixes: #27075 Signed-off-by: Daniel J Walsh <[email protected]>
1 parent e47ae67 commit 6405925

File tree

7 files changed

+89
-10
lines changed

7 files changed

+89
-10
lines changed

cmd/podman/common/completion.go

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1476,6 +1476,10 @@ func getEntityType(cmd *cobra.Command, args []string, o any) any {
14761476
if networks, _ := getNetworks(cmd, args[0], completeDefault); len(networks) > 0 {
14771477
return &entities.NetworkInspectReport{}
14781478
}
1479+
// artifact logic
1480+
if artifacts, _ := getArtifacts(cmd, args[0]); len(artifacts) > 0 {
1481+
return &entities.ArtifactInspectReport{}
1482+
}
14791483
return o
14801484
}
14811485

@@ -1641,7 +1645,7 @@ func AutocompleteImageSort(_ *cobra.Command, _ []string, _ string) ([]string, co
16411645

16421646
// AutocompleteInspectType - Autocomplete inspect type options.
16431647
func AutocompleteInspectType(_ *cobra.Command, _ []string, _ string) ([]string, cobra.ShellCompDirective) {
1644-
types := []string{AllType, ContainerType, ImageType, NetworkType, PodType, VolumeType}
1648+
types := []string{AllType, ArtifactType, ContainerType, ImageType, NetworkType, PodType, VolumeType}
16451649
return types, cobra.ShellCompDirectiveNoFileComp
16461650
}
16471651

cmd/podman/common/inspect.go

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,8 @@ package common
33
const (
44
// AllType can be of type ImageType or ContainerType.
55
AllType = "all"
6+
// ArtifactType is the artifact type.
7+
ArtifactType = "artifact"
68
// ContainerType is the container type.
79
ContainerType = "container"
810
// ImageType is the image type.

cmd/podman/inspect.go

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -12,6 +12,7 @@ var (
1212
inspectDescription = `Displays the low-level information on an object identified by name or ID.
1313
For more inspection options, see:
1414
15+
podman artifact inspect
1516
podman container inspect
1617
podman image inspect
1718
podman network inspect
@@ -20,14 +21,15 @@ var (
2021

2122
// Command: podman _inspect_ Object_ID
2223
inspectCmd = &cobra.Command{
23-
Use: "inspect [options] {CONTAINER|IMAGE|POD|NETWORK|VOLUME} [...]",
24+
Use: "inspect [options] {ARTIFACT|CONTAINER|IMAGE|POD|NETWORK|VOLUME} [...]",
2425
Short: "Display the configuration of object denoted by ID",
2526
RunE: inspectExec,
2627
Long: inspectDescription,
2728
TraverseChildren: true,
2829
ValidArgsFunction: common.AutocompleteInspect,
2930
Example: `podman inspect fedora
3031
podman inspect --type image fedora
32+
podman inspect --type artifact quay.io/myimage/myartifact:latest
3133
podman inspect CtrID ImgID
3234
podman inspect --format "imageId: {{.Id}} size: {{.Size}}" fedora`,
3335
}

cmd/podman/inspect/inspect.go

Lines changed: 16 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -151,9 +151,18 @@ func (i *inspector) inspect(namesOrIDs []string) error {
151151
for i := range volumeData {
152152
data = append(data, volumeData[i])
153153
}
154+
case common.ArtifactType:
155+
for _, name := range namesOrIDs {
156+
artifactData, err := i.imageEngine.ArtifactInspect(ctx, name, entities.ArtifactInspectOptions{})
157+
if err != nil {
158+
errs = append(errs, err)
159+
continue
160+
}
161+
data = append(data, artifactData)
162+
}
154163
default:
155-
return fmt.Errorf("invalid type %q: must be %q, %q, %q, %q, %q, or %q", i.options.Type,
156-
common.ImageType, common.ContainerType, common.PodType, common.NetworkType, common.VolumeType, common.AllType)
164+
return fmt.Errorf("invalid type %q: must be %q, %q, %q, %q, %q, %q, or %q", i.options.Type,
165+
common.ImageType, common.ContainerType, common.PodType, common.NetworkType, common.VolumeType, common.ArtifactType, common.AllType)
157166
}
158167
// Always print an empty array
159168
if data == nil {
@@ -236,6 +245,11 @@ func (i *inspector) inspectAll(ctx context.Context, namesOrIDs []string) ([]any,
236245
data = append(data, podData[0])
237246
continue
238247
}
248+
artifactData, err := i.imageEngine.ArtifactInspect(ctx, name, entities.ArtifactInspectOptions{})
249+
if err == nil {
250+
data = append(data, artifactData)
251+
continue
252+
}
239253
if len(errs) > 0 {
240254
allErrs = append(allErrs, fmt.Errorf("no such object: %q", name))
241255
continue

docs/source/markdown/podman-inspect.1.md.in

Lines changed: 20 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -1,19 +1,20 @@
11
% podman-inspect 1
22

33
## NAME
4-
podman\-inspect - Display a container, image, volume, network, or pod's configuration
4+
podman\-inspect - Display artifact, container, image, volume, network, or pod's configuration
55

66
## SYNOPSIS
77
**podman inspect** [*options*] *name* [...]
88

99
## DESCRIPTION
1010

11-
This displays the low-level information on containers and images identified by name or ID. By default, this renders
12-
all results in a JSON array. If the inspect type is all, the order of inspection is: containers, images, volumes, network, pods.
11+
This displays the low-level information on artifacts, containers, and images identified by name or ID. By default, this renders
12+
all results in a JSON array. If the inspect type is all, the order of inspection is: containers, images, volumes, network, pods, artifacts.
1313
If a container has the same name as an image, then the container JSON is returned, and so on.
1414
If a format is specified, the given template is executed for each result.
1515

1616
For more inspection options, see also
17+
[podman-artifact-inspect(1)](podman-artifact-inspect.1.md),
1718
[podman-container-inspect(1)](podman-container-inspect.1.md),
1819
[podman-image-inspect(1)](podman-image-inspect.1.md),
1920
[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
3536

3637
#### **--type**, **-t**=*type*
3738

38-
Return JSON for the specified type. Type can be 'container', 'image', 'volume', 'network', 'pod', or 'all' (default: all)
39+
Return JSON for the specified type. Type can be 'artifact', 'container', 'image', 'volume', 'network', 'pod', or 'all' (default: all)
3940
(Only meaningful when invoked as *podman inspect*)
4041

4142
## EXAMPLES
@@ -164,8 +165,22 @@ Inspect the specified network for the `Name` format specifier:
164165
myNetwork
165166
```
166167

168+
Inspect the specified artifact:
169+
```
170+
# podman inspect quay.io/myimage/myartifact:latest --type artifact
171+
{
172+
"Manifest": {
173+
"schemaVersion": 2,
174+
"mediaType": "application/vnd.oci.image.manifest.v1+json",
175+
...
176+
},
177+
"Name": "quay.io/myimage/myartifact:latest",
178+
"Digest": "sha256:..."
179+
}
180+
```
181+
167182
## SEE ALSO
168-
**[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)**
183+
**[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)**
169184

170185
## HISTORY
171186
July 2017, Originally compiled by Dan Walsh <[email protected]>

docs/source/markdown/podman.1.md

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

test/e2e/inspect_test.go

Lines changed: 42 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -597,4 +597,46 @@ var _ = Describe("Podman inspect", func() {
597597
Expect(session.OutputToString()).To(ContainSubstring(commandNotFound))
598598
})
599599

600+
It("podman inspect artifact", func() {
601+
artifactFile, err := createArtifactFile(1024)
602+
Expect(err).ToNot(HaveOccurred())
603+
604+
artifactName := "localhost/test/myartifact"
605+
add := podmanTest.Podman([]string{"artifact", "add", artifactName, artifactFile})
606+
add.WaitWithDefaultTimeout()
607+
Expect(add).Should(ExitCleanly())
608+
609+
// Test explicit artifact type
610+
inspect := podmanTest.Podman([]string{"inspect", "--type", "artifact", artifactName})
611+
inspect.WaitWithDefaultTimeout()
612+
Expect(inspect).Should(ExitCleanly())
613+
Expect(inspect.OutputToString()).To(BeValidJSON())
614+
615+
// Test fallback to artifact when no other object type matches
616+
inspect = podmanTest.Podman([]string{"inspect", artifactName})
617+
inspect.WaitWithDefaultTimeout()
618+
Expect(inspect).Should(ExitCleanly())
619+
Expect(inspect.OutputToString()).To(BeValidJSON())
620+
621+
// Verify that the output contains artifact-specific fields
622+
Expect(inspect.OutputToString()).To(ContainSubstring("Manifest"))
623+
Expect(inspect.OutputToString()).To(ContainSubstring("Digest"))
624+
625+
// Test format with artifact-specific fields
626+
inspect = podmanTest.Podman([]string{"inspect", "--format", "{{.Name}}", artifactName})
627+
inspect.WaitWithDefaultTimeout()
628+
Expect(inspect).Should(ExitCleanly())
629+
Expect(inspect.OutputToString()).To(Equal(artifactName))
630+
631+
inspect2 := podmanTest.Podman([]string{"inspect", "--format", "{{.Digest}}", artifactName})
632+
inspect2.WaitWithDefaultTimeout()
633+
Expect(inspect2).Should(ExitCleanly())
634+
Expect(inspect2.OutputToString()).To(ContainSubstring("sha256:"))
635+
636+
// Clean up
637+
rm := podmanTest.Podman([]string{"artifact", "rm", artifactName})
638+
rm.WaitWithDefaultTimeout()
639+
Expect(rm).Should(ExitCleanly())
640+
})
641+
600642
})

0 commit comments

Comments
 (0)