mirror of
https://github.com/containers/podman.git
synced 2025-08-06 19:44:14 +08:00
Merge pull request #24449 from ygalblum/quadlet-mount-image
Quadlet - support image file based mount in container file
This commit is contained in:
@ -657,10 +657,11 @@ Attach a filesystem mount to the container.
|
|||||||
This is equivalent to the Podman `--mount` option, and
|
This is equivalent to the Podman `--mount` option, and
|
||||||
generally has the form `type=TYPE,TYPE-SPECIFIC-OPTION[,...]`.
|
generally has the form `type=TYPE,TYPE-SPECIFIC-OPTION[,...]`.
|
||||||
|
|
||||||
As a special case, for `type=volume` if `source` ends with `.volume`, a Podman named volume called
|
There are two special cases.
|
||||||
`systemd-$name` is used as the source, and the generated systemd service contains
|
1. For `type=volume`, if `source` ends with `.volume`, the Podman named volume generated by the corresponding `.volume` file is used.
|
||||||
a dependency on the `$name-volume.service`. Such a volume can be automatically be lazily
|
2. For `type=image`, if `source` ends with `.image`, the image generated by the corresponding `.image` file is used.
|
||||||
created by using a `$name.volume` Quadlet file.
|
|
||||||
|
In both cases, the generated systemd service will contain a dependency on the service generated for the corresponding unit.
|
||||||
|
|
||||||
This key can be listed multiple times.
|
This key can be listed multiple times.
|
||||||
|
|
||||||
|
@ -1874,7 +1874,7 @@ func handleLogOpt(unitFile *parser.UnitFile, groupName string, podman *PodmanCmd
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
func handleStorageSource(quadletUnitFile, serviceUnitFile *parser.UnitFile, source string, unitsInfoMap map[string]*UnitInfo) (string, error) {
|
func handleStorageSource(quadletUnitFile, serviceUnitFile *parser.UnitFile, source string, unitsInfoMap map[string]*UnitInfo, checkImage bool) (string, error) {
|
||||||
if source[0] == '.' {
|
if source[0] == '.' {
|
||||||
var err error
|
var err error
|
||||||
source, err = getAbsolutePath(quadletUnitFile, source)
|
source, err = getAbsolutePath(quadletUnitFile, source)
|
||||||
@ -1885,18 +1885,18 @@ func handleStorageSource(quadletUnitFile, serviceUnitFile *parser.UnitFile, sour
|
|||||||
if source[0] == '/' {
|
if source[0] == '/' {
|
||||||
// Absolute path
|
// Absolute path
|
||||||
serviceUnitFile.Add(UnitGroup, "RequiresMountsFor", source)
|
serviceUnitFile.Add(UnitGroup, "RequiresMountsFor", source)
|
||||||
} else if strings.HasSuffix(source, ".volume") {
|
} else if strings.HasSuffix(source, ".volume") || (checkImage && strings.HasSuffix(source, ".image")) {
|
||||||
volumeUnitInfo, ok := unitsInfoMap[source]
|
sourceUnitInfo, ok := unitsInfoMap[source]
|
||||||
if !ok {
|
if !ok {
|
||||||
return "", fmt.Errorf("requested Quadlet image %s was not found", source)
|
return "", fmt.Errorf("requested Quadlet source %s was not found", source)
|
||||||
}
|
}
|
||||||
|
|
||||||
// the systemd unit name is $serviceName.service
|
// the systemd unit name is $serviceName.service
|
||||||
volumeServiceName := volumeUnitInfo.ServiceFileName()
|
sourceServiceName := sourceUnitInfo.ServiceFileName()
|
||||||
serviceUnitFile.Add(UnitGroup, "Requires", volumeServiceName)
|
serviceUnitFile.Add(UnitGroup, "Requires", sourceServiceName)
|
||||||
serviceUnitFile.Add(UnitGroup, "After", volumeServiceName)
|
serviceUnitFile.Add(UnitGroup, "After", sourceServiceName)
|
||||||
|
|
||||||
source = volumeUnitInfo.ResourceName
|
source = sourceUnitInfo.ResourceName
|
||||||
}
|
}
|
||||||
|
|
||||||
return source, nil
|
return source, nil
|
||||||
@ -2053,7 +2053,13 @@ func resolveContainerMountParams(containerUnitFile, serviceUnitFile *parser.Unit
|
|||||||
}
|
}
|
||||||
|
|
||||||
// Source resolution is required only for these types of mounts
|
// Source resolution is required only for these types of mounts
|
||||||
if !(mountType == "volume" || mountType == "bind" || mountType == "glob") {
|
sourceResultionRequired := map[string]struct{}{
|
||||||
|
"volume": {},
|
||||||
|
"bind": {},
|
||||||
|
"glob": {},
|
||||||
|
"image": {},
|
||||||
|
}
|
||||||
|
if _, ok := sourceResultionRequired[mountType]; !ok {
|
||||||
return mount, nil
|
return mount, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -2070,7 +2076,7 @@ func resolveContainerMountParams(containerUnitFile, serviceUnitFile *parser.Unit
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
resolvedSource, err := handleStorageSource(containerUnitFile, serviceUnitFile, originalSource, unitsInfoMap)
|
resolvedSource, err := handleStorageSource(containerUnitFile, serviceUnitFile, originalSource, unitsInfoMap, true)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return "", err
|
return "", err
|
||||||
}
|
}
|
||||||
@ -2158,7 +2164,7 @@ func addVolumes(quadletUnitFile, serviceUnitFile *parser.UnitFile, groupName str
|
|||||||
|
|
||||||
if source != "" {
|
if source != "" {
|
||||||
var err error
|
var err error
|
||||||
source, err = handleStorageSource(quadletUnitFile, serviceUnitFile, source, unitsInfoMap)
|
source, err = handleStorageSource(quadletUnitFile, serviceUnitFile, source, unitsInfoMap, false)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
|
@ -9,13 +9,15 @@ Mount=type=bind,src=/path/on/host,dst=/path/in/container,relabel=shared,U=true
|
|||||||
## assert-podman-args-key-val "--mount" "," "type=volume,source=vol1,destination=/path/in/container,ro=true"
|
## assert-podman-args-key-val "--mount" "," "type=volume,source=vol1,destination=/path/in/container,ro=true"
|
||||||
Mount=type=volume,source=vol1,destination=/path/in/container,ro=true
|
Mount=type=volume,source=vol1,destination=/path/in/container,ro=true
|
||||||
## assert-podman-args-key-val "--mount" "," "type=volume,source=systemd-basic,destination=/path/in/container,ro=true"
|
## assert-podman-args-key-val "--mount" "," "type=volume,source=systemd-basic,destination=/path/in/container,ro=true"
|
||||||
## assert-key-is "Unit" "Requires" "basic-volume.service"
|
## assert-key-is "Unit" "Requires" "basic-volume.service" "basic-image.service"
|
||||||
## assert-key-is-regex "Unit" "After" "network-online.target|podman-user-wait-network-online.service" "basic-volume.service"
|
## assert-key-is-regex "Unit" "After" "network-online.target|podman-user-wait-network-online.service" "basic-volume.service" "basic-image.service"
|
||||||
Mount=type=volume,source=basic.volume,destination=/path/in/container,ro=true
|
Mount=type=volume,source=basic.volume,destination=/path/in/container,ro=true
|
||||||
## assert-podman-args-key-val "--mount" "," "type=tmpfs,tmpfs-size=512M,destination=/path/in/container"
|
## assert-podman-args-key-val "--mount" "," "type=tmpfs,tmpfs-size=512M,destination=/path/in/container"
|
||||||
Mount=type=tmpfs,tmpfs-size=512M,destination=/path/in/container
|
Mount=type=tmpfs,tmpfs-size=512M,destination=/path/in/container
|
||||||
## assert-podman-args-key-val "--mount" "," "type=image,source=fedora,destination=/fedora-image,rw=true"
|
## assert-podman-args-key-val "--mount" "," "type=image,source=fedora,destination=/fedora-image,rw=true"
|
||||||
Mount=type=image,source=fedora,destination=/fedora-image,rw=true
|
Mount=type=image,source=fedora,destination=/fedora-image,rw=true
|
||||||
|
## assert-podman-args-key-val "--mount" "," "type=image,source=localhost/imagename,destination=/fedora-image,rw=true"
|
||||||
|
Mount=type=image,source=basic.image,destination=/fedora-image,rw=true
|
||||||
## assert-podman-args-key-val "--mount" "," "type=devpts,destination=/dev/pts"
|
## assert-podman-args-key-val "--mount" "," "type=devpts,destination=/dev/pts"
|
||||||
Mount=type=devpts,destination=/dev/pts
|
Mount=type=devpts,destination=/dev/pts
|
||||||
## assert-podman-args-key-val-regex "--mount" "," "type=bind,source=.*/podman-e2e-.*/subtest-.*/quadlet/path/on/host,destination=/path/in/container"
|
## assert-podman-args-key-val-regex "--mount" "," "type=bind,source=.*/podman-e2e-.*/subtest-.*/quadlet/path/on/host,destination=/path/in/container"
|
||||||
|
@ -1094,7 +1094,7 @@ BOGUS=foo
|
|||||||
|
|
||||||
runSuccessQuadletTestCase(fileName)
|
runSuccessQuadletTestCase(fileName)
|
||||||
},
|
},
|
||||||
Entry("Container - Mount", "mount.container", []string{"basic.volume"}),
|
Entry("Container - Mount", "mount.container", []string{"basic.image", "basic.volume"}),
|
||||||
Entry("Container - Quadlet Network", "network.quadlet.container", []string{"basic.network"}),
|
Entry("Container - Quadlet Network", "network.quadlet.container", []string{"basic.network"}),
|
||||||
Entry("Container - Quadlet Volume", "volume.container", []string{"basic.volume"}),
|
Entry("Container - Quadlet Volume", "volume.container", []string{"basic.volume"}),
|
||||||
Entry("Container - Mount overriding service name", "mount.servicename.container", []string{"service-name.volume"}),
|
Entry("Container - Mount overriding service name", "mount.servicename.container", []string{"service-name.volume"}),
|
||||||
|
Reference in New Issue
Block a user