Skip to content

Commit

Permalink
Merge pull request containers#11777 from cdoern/podVolumesFrom
Browse files Browse the repository at this point in the history
Pod Volumes From Support
  • Loading branch information
openshift-merge-robot authored Oct 1, 2021
2 parents 9dddd6a + 6da97c8 commit 1de96f2
Show file tree
Hide file tree
Showing 8 changed files with 122 additions and 25 deletions.
15 changes: 7 additions & 8 deletions cmd/podman/common/create.go
Original file line number Diff line number Diff line change
Expand Up @@ -656,14 +656,6 @@ func DefineCreateFlags(cmd *cobra.Command, cf *entities.ContainerCreateOptions,
)
_ = cmd.RegisterFlagCompletionFunc(mountFlagName, AutocompleteMountFlag)

volumesFromFlagName := "volumes-from"
createFlags.StringArrayVar(
&cf.VolumesFrom,
volumesFromFlagName, []string{},
"Mount volumes from the specified container(s)",
)
_ = cmd.RegisterFlagCompletionFunc(volumesFromFlagName, AutocompleteContainers)

workdirFlagName := "workdir"
createFlags.StringVarP(
&cf.Workdir,
Expand Down Expand Up @@ -877,4 +869,11 @@ func DefineCreateFlags(cmd *cobra.Command, cf *entities.ContainerCreateOptions,
"Limit read rate (bytes per second) from a device (e.g. --device-read-bps=/dev/sda:1mb)",
)
_ = cmd.RegisterFlagCompletionFunc(deviceReadBpsFlagName, completion.AutocompleteDefault)
volumesFromFlagName := "volumes-from"
createFlags.StringArrayVar(
&cf.VolumesFrom,
volumesFromFlagName, []string{},
"Mount volumes from the specified container(s)",
)
_ = cmd.RegisterFlagCompletionFunc(volumesFromFlagName, AutocompleteContainers)
}
33 changes: 33 additions & 0 deletions docs/source/markdown/podman-pod-create.1.md
Original file line number Diff line number Diff line change
Expand Up @@ -381,6 +381,39 @@ change propagation properties of source mount. Say `/` is source mount for
Note: if the user only has access rights via a group, accessing the volume
from inside a rootless pod will fail.

#### **--volumes-from**[=*CONTAINER*[:*OPTIONS*]]

Mount volumes from the specified container(s). Used to share volumes between
containers and pods. The *options* is a comma-separated list with the following available elements:

* **rw**|**ro**
* **z**

Mounts already mounted volumes from a source container into another
pod. You must supply the source's container-id or container-name.
To share a volume, use the --volumes-from option when running
the target container. You can share volumes even if the source container
is not running.

By default, Podman mounts the volumes in the same mode (read-write or
read-only) as it is mounted in the source container.
You can change this by adding a `ro` or `rw` _option_.

Labeling systems like SELinux require that proper labels are placed on volume
content mounted into a pod. Without a label, the security system might
prevent the processes running inside the container from using the content. By
default, Podman does not change the labels set by the OS.

To change a label in the pod context, you can add `z` to the volume mount.
This suffix tells Podman to relabel file objects on the shared volumes. The `z`
option tells Podman that two entities share the volume content. As a result,
Podman labels the content with a shared content label. Shared volume labels allow
all containers to read/write content.

If the location of the volume from the source container overlaps with
data residing on a target pod, then the volume hides
that data on the target.


## EXAMPLES

Expand Down
2 changes: 2 additions & 0 deletions libpod/define/pod_inspect.go
Original file line number Diff line number Diff line change
Expand Up @@ -63,6 +63,8 @@ type InspectPodData struct {
Devices []InspectDevice `json:"devices,omitempty"`
// BlkioDeviceReadBps contains the Read/Access limit for the pod's devices
BlkioDeviceReadBps []InspectBlkioThrottleDevice `json:"device_read_bps,omitempty"`
// VolumesFrom contains the containers that the pod inherits mounts from
VolumesFrom []string `json:"volumes_from,omitempty"`
}

// InspectPodInfraConfig contains the configuration of the pod's infra
Expand Down
16 changes: 16 additions & 0 deletions libpod/pod.go
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@ import (
"context"
"fmt"
"sort"
"strings"
"time"

"github.com/containers/podman/v3/libpod/define"
Expand Down Expand Up @@ -200,6 +201,21 @@ func (p *Pod) UserNSMode() string {
return ""
}

// CPUQuota returns the pod CPU quota
func (p *Pod) VolumesFrom() []string {
if p.state.InfraContainerID == "" {
return nil
}
infra, err := p.runtime.GetContainer(p.state.InfraContainerID)
if err != nil {
return nil
}
if ctrs, ok := infra.config.Spec.Annotations[define.InspectAnnotationVolumesFrom]; ok {
return strings.Split(ctrs, ",")
}
return nil
}

// Labels returns the pod's labels
func (p *Pod) Labels() map[string]string {
labels := make(map[string]string)
Expand Down
1 change: 1 addition & 0 deletions libpod/pod_api.go
Original file line number Diff line number Diff line change
Expand Up @@ -668,6 +668,7 @@ func (p *Pod) Inspect() (*define.InspectPodData, error) {
Mounts: inspectMounts,
Devices: devices,
BlkioDeviceReadBps: deviceLimits,
VolumesFrom: p.VolumesFrom(),
}

return &inspectData, nil
Expand Down
4 changes: 3 additions & 1 deletion pkg/domain/entities/pods.go
Original file line number Diff line number Diff line change
Expand Up @@ -135,6 +135,7 @@ type PodCreateOptions struct {
CpusetCpus string `json:"cpuset_cpus,omitempty"`
Userns specgen.Namespace `json:"-"`
Volume []string `json:"volume,omitempty"`
VolumesFrom []string `json:"volumes_from,omitempty"`
}

// PodLogsOptions describes the options to extract pod logs.
Expand Down Expand Up @@ -251,7 +252,7 @@ type ContainerCreateOptions struct {
UTS string
Mount []string
Volume []string `json:"volume,omitempty"`
VolumesFrom []string
VolumesFrom []string `json:"volumes_from,omitempty"`
Workdir string
SeccompPolicy string
PidFile string
Expand Down Expand Up @@ -308,6 +309,7 @@ func ToPodSpecGen(s specgen.PodSpecGenerator, p *PodCreateOptions) (*specgen.Pod
s.InfraImage = p.InfraImage
s.SharedNamespaces = p.Share
s.PodCreateCommand = p.CreateCommand
s.VolumesFrom = p.VolumesFrom

// Networking config

Expand Down
43 changes: 27 additions & 16 deletions pkg/specgen/podspecgen.go
Original file line number Diff line number Diff line change
Expand Up @@ -72,22 +72,6 @@ type PodBasicConfig struct {
// Any containers created within the pod will inherit the pod's userns settings.
// Optional
Userns Namespace `json:"userns,omitempty"`
// Mounts are mounts that will be added to the pod.
// These will supersede Image Volumes and VolumesFrom (WIP) volumes where
// there are conflicts.
// Optional.
Mounts []spec.Mount `json:"mounts,omitempty"`
// Volumes are named volumes that will be added to the pod.
// These will supersede Image Volumes and VolumesFrom (WIP) volumes where
// there are conflicts.
// Optional.
Volumes []*NamedVolume `json:"volumes,omitempty"`
// Overlay volumes are named volumes that will be added to the pod.
// Optional.
OverlayVolumes []*OverlayVolume `json:"overlay_volumes,omitempty"`
// Image volumes bind-mount a container-image mount into the pod's infra container.
// Optional.
ImageVolumes []*ImageVolume `json:"image_volumes,omitempty"`
// Devices contains user specified Devices to be added to the Pod
Devices []string `json:"pod_devices,omitempty"`
}
Expand Down Expand Up @@ -174,6 +158,32 @@ type PodNetworkConfig struct {
NetworkOptions map[string][]string `json:"network_options,omitempty"`
}

// PodStorageConfig contains all of the storage related options for the pod and its infra container.
type PodStorageConfig struct {
// Mounts are mounts that will be added to the pod.
// These will supersede Image Volumes and VolumesFrom volumes where
// there are conflicts.
// Optional.
Mounts []spec.Mount `json:"mounts,omitempty"`
// Volumes are named volumes that will be added to the pod.
// These will supersede Image Volumes and VolumesFrom volumes where
// there are conflicts.
// Optional.
Volumes []*NamedVolume `json:"volumes,omitempty"`
// Overlay volumes are named volumes that will be added to the pod.
// Optional.
OverlayVolumes []*OverlayVolume `json:"overlay_volumes,omitempty"`
// Image volumes bind-mount a container-image mount into the pod's infra container.
// Optional.
ImageVolumes []*ImageVolume `json:"image_volumes,omitempty"`
// VolumesFrom is a set of containers whose volumes will be added to
// this pod. The name or ID of the container must be provided, and
// may optionally be followed by a : and then one or more
// comma-separated options. Valid options are 'ro', 'rw', and 'z'.
// Options will be used for all volumes sourced from the container.
VolumesFrom []string `json:"volumes_from,omitempty"`
}

// PodCgroupConfig contains configuration options about a pod's cgroups.
// This will be expanded in future updates to pods.
type PodCgroupConfig struct {
Expand All @@ -191,6 +201,7 @@ type PodSpecGenerator struct {
PodNetworkConfig
PodCgroupConfig
PodResourceConfig
PodStorageConfig
InfraContainerSpec *SpecGenerator `json:"-"`
}

Expand Down
33 changes: 33 additions & 0 deletions test/e2e/pod_create_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -924,4 +924,37 @@ ENTRYPOINT ["sleep","99999"]
}
})

It("podman pod create --volumes-from", func() {
volName := "testVol"
volCreate := podmanTest.Podman([]string{"volume", "create", volName})
volCreate.WaitWithDefaultTimeout()
Expect(volCreate).Should(Exit(0))
ctrName := "testCtr"
ctrCreate := podmanTest.Podman([]string{"create", "--volume", volName + ":/tmp1", "--name", ctrName, ALPINE})
ctrCreate.WaitWithDefaultTimeout()
Expect(ctrCreate).Should(Exit(0))
ctrInspect := podmanTest.Podman([]string{"inspect", ctrName})
ctrInspect.WaitWithDefaultTimeout()
Expect(ctrInspect).Should(Exit(0))
data := ctrInspect.InspectContainerToJSON()
Expect(data[0].Mounts[0].Name).To(Equal(volName))
podName := "testPod"
podCreate := podmanTest.Podman([]string{"pod", "create", "--volumes-from", ctrName, "--name", podName})
podCreate.WaitWithDefaultTimeout()
Expect(podCreate).Should(Exit(0))
podInspect := podmanTest.Podman([]string{"pod", "inspect", podName})
podInspect.WaitWithDefaultTimeout()
Expect(podInspect).Should(Exit(0))
podData := podInspect.InspectPodToJSON()
Expect(podData.Mounts[0].Name).To(Equal(volName))

ctr2 := podmanTest.Podman([]string{"run", "--pod", podName, ALPINE, "sh", "-c", "echo hello >> " + "/tmp1/test"})
ctr2.WaitWithDefaultTimeout()
Expect(ctr2).Should(Exit(0))

ctr3 := podmanTest.Podman([]string{"run", "--pod", podName, ALPINE, "cat", "/tmp1/test"})
ctr3.WaitWithDefaultTimeout()
Expect(ctr3.OutputToString()).To(ContainSubstring("hello"))
})

})

0 comments on commit 1de96f2

Please sign in to comment.