mirror of
https://github.com/containers/podman.git
synced 2025-10-17 03:04:21 +08:00
Merge pull request #27156 from rhatdan/inspect
Add artifact fallback to podman inspect command
This commit is contained in:
@ -1476,6 +1476,10 @@ func getEntityType(cmd *cobra.Command, args []string, o any) any {
|
|||||||
if networks, _ := getNetworks(cmd, args[0], completeDefault); len(networks) > 0 {
|
if networks, _ := getNetworks(cmd, args[0], completeDefault); len(networks) > 0 {
|
||||||
return &entities.NetworkInspectReport{}
|
return &entities.NetworkInspectReport{}
|
||||||
}
|
}
|
||||||
|
// artifact logic
|
||||||
|
if artifacts, _ := getArtifacts(cmd, args[0]); len(artifacts) > 0 {
|
||||||
|
return &entities.ArtifactInspectReport{}
|
||||||
|
}
|
||||||
return o
|
return o
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -1641,7 +1645,7 @@ func AutocompleteImageSort(_ *cobra.Command, _ []string, _ string) ([]string, co
|
|||||||
|
|
||||||
// AutocompleteInspectType - Autocomplete inspect type options.
|
// AutocompleteInspectType - Autocomplete inspect type options.
|
||||||
func AutocompleteInspectType(_ *cobra.Command, _ []string, _ string) ([]string, cobra.ShellCompDirective) {
|
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
|
return types, cobra.ShellCompDirectiveNoFileComp
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -3,6 +3,8 @@ package common
|
|||||||
const (
|
const (
|
||||||
// AllType can be of type ImageType or ContainerType.
|
// AllType can be of type ImageType or ContainerType.
|
||||||
AllType = "all"
|
AllType = "all"
|
||||||
|
// ArtifactType is the artifact type.
|
||||||
|
ArtifactType = "artifact"
|
||||||
// ContainerType is the container type.
|
// ContainerType is the container type.
|
||||||
ContainerType = "container"
|
ContainerType = "container"
|
||||||
// ImageType is the image type.
|
// ImageType is the image type.
|
||||||
|
@ -12,6 +12,7 @@ var (
|
|||||||
inspectDescription = `Displays the low-level information on an object identified by name or ID.
|
inspectDescription = `Displays the low-level information on an object identified by name or ID.
|
||||||
For more inspection options, see:
|
For more inspection options, see:
|
||||||
|
|
||||||
|
podman artifact inspect
|
||||||
podman container inspect
|
podman container inspect
|
||||||
podman image inspect
|
podman image inspect
|
||||||
podman network inspect
|
podman network inspect
|
||||||
@ -20,7 +21,7 @@ var (
|
|||||||
|
|
||||||
// Command: podman _inspect_ Object_ID
|
// Command: podman _inspect_ Object_ID
|
||||||
inspectCmd = &cobra.Command{
|
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",
|
Short: "Display the configuration of object denoted by ID",
|
||||||
RunE: inspectExec,
|
RunE: inspectExec,
|
||||||
Long: inspectDescription,
|
Long: inspectDescription,
|
||||||
@ -28,6 +29,7 @@ var (
|
|||||||
ValidArgsFunction: common.AutocompleteInspect,
|
ValidArgsFunction: common.AutocompleteInspect,
|
||||||
Example: `podman inspect fedora
|
Example: `podman inspect fedora
|
||||||
podman inspect --type image fedora
|
podman inspect --type image fedora
|
||||||
|
podman inspect --type artifact quay.io/myimage/myartifact:latest
|
||||||
podman inspect CtrID ImgID
|
podman inspect CtrID ImgID
|
||||||
podman inspect --format "imageId: {{.Id}} size: {{.Size}}" fedora`,
|
podman inspect --format "imageId: {{.Id}} size: {{.Size}}" fedora`,
|
||||||
}
|
}
|
||||||
|
@ -151,9 +151,18 @@ func (i *inspector) inspect(namesOrIDs []string) error {
|
|||||||
for i := range volumeData {
|
for i := range volumeData {
|
||||||
data = append(data, volumeData[i])
|
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:
|
default:
|
||||||
return fmt.Errorf("invalid type %q: must be %q, %q, %q, %q, %q, or %q", i.options.Type,
|
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.AllType)
|
common.ImageType, common.ContainerType, common.PodType, common.NetworkType, common.VolumeType, common.ArtifactType, common.AllType)
|
||||||
}
|
}
|
||||||
// Always print an empty array
|
// Always print an empty array
|
||||||
if data == nil {
|
if data == nil {
|
||||||
@ -236,6 +245,11 @@ func (i *inspector) inspectAll(ctx context.Context, namesOrIDs []string) ([]any,
|
|||||||
data = append(data, podData[0])
|
data = append(data, podData[0])
|
||||||
continue
|
continue
|
||||||
}
|
}
|
||||||
|
artifactData, err := i.imageEngine.ArtifactInspect(ctx, name, entities.ArtifactInspectOptions{})
|
||||||
|
if err == nil {
|
||||||
|
data = append(data, artifactData)
|
||||||
|
continue
|
||||||
|
}
|
||||||
if len(errs) > 0 {
|
if len(errs) > 0 {
|
||||||
allErrs = append(allErrs, fmt.Errorf("no such object: %q", name))
|
allErrs = append(allErrs, fmt.Errorf("no such object: %q", name))
|
||||||
continue
|
continue
|
||||||
|
@ -1,19 +1,20 @@
|
|||||||
% podman-inspect 1
|
% podman-inspect 1
|
||||||
|
|
||||||
## NAME
|
## 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
|
## SYNOPSIS
|
||||||
**podman inspect** [*options*] *name* [...]
|
**podman inspect** [*options*] *name* [...]
|
||||||
|
|
||||||
## DESCRIPTION
|
## DESCRIPTION
|
||||||
|
|
||||||
This displays the low-level information on containers and images identified by name or ID. By default, this renders
|
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.
|
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 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.
|
If a format is specified, the given template is executed for each result.
|
||||||
|
|
||||||
For more inspection options, see also
|
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-container-inspect(1)](podman-container-inspect.1.md),
|
||||||
[podman-image-inspect(1)](podman-image-inspect.1.md),
|
[podman-image-inspect(1)](podman-image-inspect.1.md),
|
||||||
[podman-network-inspect(1)](podman-network-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*
|
#### **--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*)
|
(Only meaningful when invoked as *podman inspect*)
|
||||||
|
|
||||||
## EXAMPLES
|
## EXAMPLES
|
||||||
@ -164,8 +165,22 @@ Inspect the specified network for the `Name` format specifier:
|
|||||||
myNetwork
|
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
|
## 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
|
## HISTORY
|
||||||
July 2017, Originally compiled by Dan Walsh <dwalsh@redhat.com>
|
July 2017, Originally compiled by Dan Walsh <dwalsh@redhat.com>
|
||||||
|
@ -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-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-info(1)](podman-info.1.md) | Display Podman related system information. |
|
||||||
| [podman-init(1)](podman-init.1.md) | Initialize one or more containers |
|
| [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-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-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. |
|
| [podman-login(1)](podman-login.1.md) | Log in to a container registry. |
|
||||||
|
@ -597,4 +597,46 @@ var _ = Describe("Podman inspect", func() {
|
|||||||
Expect(session.OutputToString()).To(ContainSubstring(commandNotFound))
|
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())
|
||||||
|
})
|
||||||
|
|
||||||
})
|
})
|
||||||
|
Reference in New Issue
Block a user