mirror of
https://github.com/containers/podman.git
synced 2025-07-04 18:27:33 +08:00
artifact mount: add new name option to specify filename
An artifact without the title annoation just gets the digest as name which is less than ideal. While it is a decent default to avoid conflicts users would like to configure the name. With the name=abc option we will call the file abc in case of a signle artifact and otherwise we use abc-x where x is the layer index starting at 0 to avoid conflicts. Signed-off-by: Paul Holzinger <pholzing@redhat.com>
This commit is contained in:
@ -32,6 +32,12 @@ Options specific to type=**artifact**:
|
|||||||
- *title*: If the artifact source contains multiple blobs a title can be set
|
- *title*: If the artifact source contains multiple blobs a title can be set
|
||||||
which is compared against `org.opencontainers.image.title` annotation.
|
which is compared against `org.opencontainers.image.title` annotation.
|
||||||
|
|
||||||
|
- *name*: This can be used to overwrite the filename we use inside the container
|
||||||
|
for mounting. On a single blob artifact the name is used as is if *dst* is a
|
||||||
|
directory and otherwise ignored. With a multi blob artifact the name will be
|
||||||
|
used with an index suffix `<name>-x` where x is the layer index in the artifact
|
||||||
|
starting with 0.
|
||||||
|
|
||||||
The *src* argument contains the name of the artifact, which must already exist locally.
|
The *src* argument contains the name of the artifact, which must already exist locally.
|
||||||
The *dst* argument contains the target path, if the path in the container is a
|
The *dst* argument contains the target path, if the path in the container is a
|
||||||
directory the blob title (`org.opencontainers.image.title` annotation) will be used as
|
directory the blob title (`org.opencontainers.image.title` annotation) will be used as
|
||||||
|
@ -300,6 +300,11 @@ type ContainerArtifactVolume struct {
|
|||||||
// the title annotation exist.
|
// the title annotation exist.
|
||||||
// Optional. Conflicts with Title.
|
// Optional. Conflicts with Title.
|
||||||
Digest string `json:"digest"`
|
Digest string `json:"digest"`
|
||||||
|
// Name is the name that should be used for the path inside the container. When a single blob
|
||||||
|
// is mounted the name is used as is. If multiple blobs are mounted then mount them as
|
||||||
|
// "<name>-x" where x is a 0 indexed integer based on the layer order.
|
||||||
|
// Optional.
|
||||||
|
Name string `json:"name,omitempty"`
|
||||||
}
|
}
|
||||||
|
|
||||||
// ContainerSecret is a secret that is mounted in a container
|
// ContainerSecret is a secret that is mounted in a container
|
||||||
|
@ -564,12 +564,21 @@ func (c *Container) generateSpec(ctx context.Context) (s *spec.Spec, cleanupFunc
|
|||||||
return nil, nil, fmt.Errorf("artifact %q contains more than one blob and container path %q is a file", artifactMount.Source, artifactMount.Dest)
|
return nil, nil, fmt.Errorf("artifact %q contains more than one blob and container path %q is a file", artifactMount.Source, artifactMount.Dest)
|
||||||
}
|
}
|
||||||
|
|
||||||
for _, path := range paths {
|
for i, path := range paths {
|
||||||
var dest string
|
var dest string
|
||||||
if destIsFile {
|
if destIsFile {
|
||||||
dest = artifactMount.Dest
|
dest = artifactMount.Dest
|
||||||
} else {
|
} else {
|
||||||
dest = filepath.Join(artifactMount.Dest, path.Name)
|
var filename string
|
||||||
|
if artifactMount.Name != "" {
|
||||||
|
filename = artifactMount.Name
|
||||||
|
if len(paths) > 1 {
|
||||||
|
filename += "-" + strconv.Itoa(i)
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
filename = path.Name
|
||||||
|
}
|
||||||
|
dest = filepath.Join(artifactMount.Dest, filename)
|
||||||
}
|
}
|
||||||
|
|
||||||
logrus.Debugf("Mounting artifact %q in container %s, mount blob %q to %q", artifactMount.Source, c.ID(), path.SourcePath, dest)
|
logrus.Debugf("Mounting artifact %q in container %s, mount blob %q to %q", artifactMount.Source, c.ID(), path.SourcePath, dest)
|
||||||
|
@ -515,6 +515,7 @@ func createContainerOptions(rt *libpod.Runtime, s *specgen.SpecGenerator, pod *l
|
|||||||
Source: v.Source,
|
Source: v.Source,
|
||||||
Digest: v.Digest,
|
Digest: v.Digest,
|
||||||
Title: v.Title,
|
Title: v.Title,
|
||||||
|
Name: v.Name,
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
options = append(options, libpod.WithArtifactVolumes(vols))
|
options = append(options, libpod.WithArtifactVolumes(vols))
|
||||||
|
@ -78,6 +78,11 @@ type ArtifactVolume struct {
|
|||||||
// the title annotation exist.
|
// the title annotation exist.
|
||||||
// Optional. Conflicts with Title.
|
// Optional. Conflicts with Title.
|
||||||
Digest string `json:"digest,omitempty"`
|
Digest string `json:"digest,omitempty"`
|
||||||
|
// Name is the name that should be used for the path inside the container. When a single blob
|
||||||
|
// is mounted the name is used as is. If multiple blobs are mounted then mount them as
|
||||||
|
// "<name>-x" where x is a 0 indexed integer based on the layer order.
|
||||||
|
// Optional.
|
||||||
|
Name string `json:"name,omitempty"`
|
||||||
}
|
}
|
||||||
|
|
||||||
// GenVolumeMounts parses user input into mounts, volumes and overlay volumes
|
// GenVolumeMounts parses user input into mounts, volumes and overlay volumes
|
||||||
|
@ -747,6 +747,11 @@ func getArtifactVolume(args []string) (*specgen.ArtifactVolume, error) {
|
|||||||
return nil, fmt.Errorf("%v: %w", name, errOptionArg)
|
return nil, fmt.Errorf("%v: %w", name, errOptionArg)
|
||||||
}
|
}
|
||||||
newVolume.Digest = value
|
newVolume.Digest = value
|
||||||
|
case "name":
|
||||||
|
if !hasValue {
|
||||||
|
return nil, fmt.Errorf("%v: %w", name, errOptionArg)
|
||||||
|
}
|
||||||
|
newVolume.Name = value
|
||||||
default:
|
default:
|
||||||
return nil, fmt.Errorf("%s: %w", name, util.ErrBadMntOption)
|
return nil, fmt.Errorf("%s: %w", name, util.ErrBadMntOption)
|
||||||
}
|
}
|
||||||
|
@ -46,6 +46,11 @@ var _ = Describe("Podman artifact mount", func() {
|
|||||||
mountOpts: "dst=/data,digest=sha256:e9510923578af3632946ecf5ae479c1b5f08b47464e707b5cbab9819272a9752",
|
mountOpts: "dst=/data,digest=sha256:e9510923578af3632946ecf5ae479c1b5f08b47464e707b5cbab9819272a9752",
|
||||||
containerFile: "/data",
|
containerFile: "/data",
|
||||||
},
|
},
|
||||||
|
{
|
||||||
|
name: "single artifact mount with name",
|
||||||
|
mountOpts: "dst=/tmp,name=abcd",
|
||||||
|
containerFile: "/tmp/abcd",
|
||||||
|
},
|
||||||
}
|
}
|
||||||
|
|
||||||
for _, tt := range tests {
|
for _, tt := range tests {
|
||||||
@ -133,6 +138,20 @@ var _ = Describe("Podman artifact mount", func() {
|
|||||||
},
|
},
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
|
{
|
||||||
|
name: "multi blob with name",
|
||||||
|
mountOpts: "src=" + ARTIFACT_MULTI + ",dst=/test,name=myname",
|
||||||
|
containerFiles: []expectedFiles{
|
||||||
|
{
|
||||||
|
file: "/test/myname-0",
|
||||||
|
content: artifactContent1,
|
||||||
|
},
|
||||||
|
{
|
||||||
|
file: "/test/myname-1",
|
||||||
|
content: artifactContent2,
|
||||||
|
},
|
||||||
|
},
|
||||||
|
},
|
||||||
}
|
}
|
||||||
for _, tt := range tests {
|
for _, tt := range tests {
|
||||||
By(tt.name)
|
By(tt.name)
|
||||||
|
Reference in New Issue
Block a user