mirror of
https://github.com/containers/podman.git
synced 2025-05-17 15:18:43 +08:00
Add ability to set layer media type for artifacts
in #25884, it was pointed out that the standard detection used to determine the artifact's file type can be wrong. in those cases, it would be handy for the user to be able to override the media type of the layer. as such, added a new option called `--file-type`, which is optional, and allows users to do just that. `podman artifact add --file-type text/yaml quay.io/artifact/config:latest ./config.yaml ` Fixes: #25884 Signed-off-by: Brent Baude <bbaude@redhat.com>
This commit is contained in:
@ -19,8 +19,10 @@ var (
|
|||||||
RunE: add,
|
RunE: add,
|
||||||
Args: cobra.MinimumNArgs(2),
|
Args: cobra.MinimumNArgs(2),
|
||||||
ValidArgsFunction: common.AutocompleteArtifactAdd,
|
ValidArgsFunction: common.AutocompleteArtifactAdd,
|
||||||
Example: `podman artifact add quay.io/myimage/myartifact:latest /tmp/foobar.txt`,
|
Example: `podman artifact add quay.io/myimage/myartifact:latest /tmp/foobar.txt
|
||||||
Annotations: map[string]string{registry.EngineMode: registry.ABIMode},
|
podman artifact add --file-type text/yaml quay.io/myimage/myartifact:latest /tmp/foobar.yaml
|
||||||
|
podman artifact add --append quay.io/myimage/myartifact:latest /tmp/foobar.tar.gz`,
|
||||||
|
Annotations: map[string]string{registry.EngineMode: registry.ABIMode},
|
||||||
}
|
}
|
||||||
)
|
)
|
||||||
|
|
||||||
@ -28,6 +30,7 @@ type artifactAddOptions struct {
|
|||||||
ArtifactType string
|
ArtifactType string
|
||||||
Annotations []string
|
Annotations []string
|
||||||
Append bool
|
Append bool
|
||||||
|
FileType string
|
||||||
}
|
}
|
||||||
|
|
||||||
var (
|
var (
|
||||||
@ -51,6 +54,10 @@ func init() {
|
|||||||
|
|
||||||
appendFlagName := "append"
|
appendFlagName := "append"
|
||||||
flags.BoolVarP(&addOpts.Append, appendFlagName, "a", false, "Append files to an existing artifact")
|
flags.BoolVarP(&addOpts.Append, appendFlagName, "a", false, "Append files to an existing artifact")
|
||||||
|
|
||||||
|
fileTypeFlagName := "file-type"
|
||||||
|
flags.StringVarP(&addOpts.FileType, fileTypeFlagName, "", "", "Set file type to use for the artifact (layer)")
|
||||||
|
_ = addCmd.RegisterFlagCompletionFunc(fileTypeFlagName, completion.AutocompleteNone)
|
||||||
}
|
}
|
||||||
|
|
||||||
func add(cmd *cobra.Command, args []string) error {
|
func add(cmd *cobra.Command, args []string) error {
|
||||||
@ -63,6 +70,7 @@ func add(cmd *cobra.Command, args []string) error {
|
|||||||
opts.Annotations = annots
|
opts.Annotations = annots
|
||||||
opts.ArtifactType = addOpts.ArtifactType
|
opts.ArtifactType = addOpts.ArtifactType
|
||||||
opts.Append = addOpts.Append
|
opts.Append = addOpts.Append
|
||||||
|
opts.FileType = addOpts.FileType
|
||||||
|
|
||||||
report, err := registry.ImageEngine().ArtifactAdd(registry.Context(), args[0], args[1:], opts)
|
report, err := registry.ImageEngine().ArtifactAdd(registry.Context(), args[0], args[1:], opts)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
|
@ -27,6 +27,10 @@ Note: Set annotations for each file being added.
|
|||||||
|
|
||||||
Append files to an existing artifact. This option cannot be used with the **--type** option.
|
Append files to an existing artifact. This option cannot be used with the **--type** option.
|
||||||
|
|
||||||
|
#### **--file-type**
|
||||||
|
|
||||||
|
Set the media type of the artifact file instead of allowing detection to determine the type
|
||||||
|
|
||||||
#### **--help**
|
#### **--help**
|
||||||
|
|
||||||
Print usage statement.
|
Print usage statement.
|
||||||
@ -55,6 +59,16 @@ Set an annotation for an artifact
|
|||||||
$ podman artifact add --annotation date=2025-01-30 quay.io/myartifact/myml:latest /tmp/foobar1.ml
|
$ podman artifact add --annotation date=2025-01-30 quay.io/myartifact/myml:latest /tmp/foobar1.ml
|
||||||
```
|
```
|
||||||
|
|
||||||
|
Append a file to an existing artifact
|
||||||
|
```
|
||||||
|
$ podman artifact add --append quay.io/myartifact/tarballs:latest /tmp/foobar.tar.gz
|
||||||
|
```
|
||||||
|
|
||||||
|
Override the media type of the artifact being added
|
||||||
|
```
|
||||||
|
$ podman artifact add --file-type text/yaml quay.io/myartifact/descriptors:latest /tmp/info.yaml
|
||||||
|
```
|
||||||
|
|
||||||
|
|
||||||
## SEE ALSO
|
## SEE ALSO
|
||||||
**[podman(1)](podman.1.md)**, **[podman-artifact(1)](podman-artifact.1.md)**
|
**[podman(1)](podman.1.md)**, **[podman-artifact(1)](podman-artifact.1.md)**
|
||||||
|
@ -13,6 +13,7 @@ type ArtifactAddOptions struct {
|
|||||||
Annotations map[string]string
|
Annotations map[string]string
|
||||||
ArtifactType string
|
ArtifactType string
|
||||||
Append bool
|
Append bool
|
||||||
|
FileType string
|
||||||
}
|
}
|
||||||
|
|
||||||
type ArtifactExtractOptions struct {
|
type ArtifactExtractOptions struct {
|
||||||
|
@ -192,6 +192,7 @@ func (ir *ImageEngine) ArtifactAdd(ctx context.Context, name string, paths []str
|
|||||||
Annotations: opts.Annotations,
|
Annotations: opts.Annotations,
|
||||||
ArtifactType: opts.ArtifactType,
|
ArtifactType: opts.ArtifactType,
|
||||||
Append: opts.Append,
|
Append: opts.Append,
|
||||||
|
FileType: opts.FileType,
|
||||||
}
|
}
|
||||||
|
|
||||||
artifactDigest, err := artStore.Add(ctx, name, paths, &addOptions)
|
artifactDigest, err := artStore.Add(ctx, name, paths, &addOptions)
|
||||||
|
@ -251,20 +251,26 @@ func (as ArtifactStore) Add(ctx context.Context, dest string, paths []string, op
|
|||||||
// ImageDestination, in general, requires the caller to write a full image; here we may write only the added layers.
|
// ImageDestination, in general, requires the caller to write a full image; here we may write only the added layers.
|
||||||
// This works for the oci/layout transport we hard-code.
|
// This works for the oci/layout transport we hard-code.
|
||||||
for _, path := range paths {
|
for _, path := range paths {
|
||||||
|
mediaType := options.FileType
|
||||||
// get the new artifact into the local store
|
// get the new artifact into the local store
|
||||||
newBlobDigest, newBlobSize, err := layout.PutBlobFromLocalFile(ctx, imageDest, path)
|
newBlobDigest, newBlobSize, err := layout.PutBlobFromLocalFile(ctx, imageDest, path)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
detectedType, err := determineManifestType(path)
|
|
||||||
if err != nil {
|
// If we did not receive an override for the layer's mediatype, use
|
||||||
return nil, err
|
// detection to determine it.
|
||||||
|
if len(mediaType) < 1 {
|
||||||
|
mediaType, err = determineManifestType(path)
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
annotations := maps.Clone(options.Annotations)
|
annotations := maps.Clone(options.Annotations)
|
||||||
annotations[specV1.AnnotationTitle] = filepath.Base(path)
|
annotations[specV1.AnnotationTitle] = filepath.Base(path)
|
||||||
newLayer := specV1.Descriptor{
|
newLayer := specV1.Descriptor{
|
||||||
MediaType: detectedType,
|
MediaType: mediaType,
|
||||||
Digest: newBlobDigest,
|
Digest: newBlobDigest,
|
||||||
Size: newBlobSize,
|
Size: newBlobSize,
|
||||||
Annotations: annotations,
|
Annotations: annotations,
|
||||||
|
@ -10,6 +10,9 @@ type AddOptions struct {
|
|||||||
ArtifactType string `json:",omitempty"`
|
ArtifactType string `json:",omitempty"`
|
||||||
// append option is not compatible with ArtifactType option
|
// append option is not compatible with ArtifactType option
|
||||||
Append bool `json:",omitempty"`
|
Append bool `json:",omitempty"`
|
||||||
|
// FileType describes the media type for the layer. It is an override
|
||||||
|
// for the standard detection
|
||||||
|
FileType string `json:",omitempty"`
|
||||||
}
|
}
|
||||||
|
|
||||||
// FilterBlobOptions options used to filter for a single blob in an artifact
|
// FilterBlobOptions options used to filter for a single blob in an artifact
|
||||||
|
@ -88,6 +88,7 @@ var _ = Describe("Podman artifact", func() {
|
|||||||
})
|
})
|
||||||
|
|
||||||
It("podman artifact add with options", func() {
|
It("podman artifact add with options", func() {
|
||||||
|
yamlType := "text/yaml"
|
||||||
artifact1Name := "localhost/test/artifact1"
|
artifact1Name := "localhost/test/artifact1"
|
||||||
artifact1File, err := createArtifactFile(1024)
|
artifact1File, err := createArtifactFile(1024)
|
||||||
Expect(err).ToNot(HaveOccurred())
|
Expect(err).ToNot(HaveOccurred())
|
||||||
@ -96,13 +97,14 @@ var _ = Describe("Podman artifact", func() {
|
|||||||
annotation1 := "color=blue"
|
annotation1 := "color=blue"
|
||||||
annotation2 := "flavor=lemon"
|
annotation2 := "flavor=lemon"
|
||||||
|
|
||||||
podmanTest.PodmanExitCleanly("artifact", "add", "--type", artifactType, "--annotation", annotation1, "--annotation", annotation2, artifact1Name, artifact1File)
|
podmanTest.PodmanExitCleanly("artifact", "add", "--file-type", yamlType, "--type", artifactType, "--annotation", annotation1, "--annotation", annotation2, artifact1Name, artifact1File)
|
||||||
|
|
||||||
a := podmanTest.InspectArtifact(artifact1Name)
|
a := podmanTest.InspectArtifact(artifact1Name)
|
||||||
Expect(a.Name).To(Equal(artifact1Name))
|
Expect(a.Name).To(Equal(artifact1Name))
|
||||||
Expect(a.Manifest.ArtifactType).To(Equal(artifactType))
|
Expect(a.Manifest.ArtifactType).To(Equal(artifactType))
|
||||||
Expect(a.Manifest.Layers[0].Annotations["color"]).To(Equal("blue"))
|
Expect(a.Manifest.Layers[0].Annotations["color"]).To(Equal("blue"))
|
||||||
Expect(a.Manifest.Layers[0].Annotations["flavor"]).To(Equal("lemon"))
|
Expect(a.Manifest.Layers[0].Annotations["flavor"]).To(Equal("lemon"))
|
||||||
|
Expect(a.Manifest.Layers[0].MediaType).To(Equal(yamlType))
|
||||||
|
|
||||||
failSession := podmanTest.Podman([]string{"artifact", "add", "--annotation", "org.opencontainers.image.title=foobar", "foobar", artifact1File})
|
failSession := podmanTest.Podman([]string{"artifact", "add", "--annotation", "org.opencontainers.image.title=foobar", "foobar", artifact1File})
|
||||||
failSession.WaitWithDefaultTimeout()
|
failSession.WaitWithDefaultTimeout()
|
||||||
|
Reference in New Issue
Block a user