1
0
Fork 0
mirror of https://github.com/moby/moby.git synced 2022-11-09 12:21:53 -05:00

apply selinux labels volume patch on volumes refactor

Signed-off-by: Jessica Frazelle <princess@docker.com>
This commit is contained in:
Jessica Frazelle 2015-05-24 18:39:31 -07:00
parent 160dc79db0
commit af7d17a6c9
3 changed files with 86 additions and 41 deletions

View file

@ -6,11 +6,14 @@ import (
"io/ioutil"
"os"
"path/filepath"
"runtime"
"strings"
"github.com/Sirupsen/logrus"
"github.com/docker/docker/pkg/chrootarchive"
"github.com/docker/docker/runconfig"
"github.com/docker/docker/volume"
"github.com/docker/libcontainer/label"
)
type mountPoint struct {
@ -50,7 +53,7 @@ func (m *mountPoint) Path() string {
return m.Source
}
func parseBindMount(spec string, config *runconfig.Config) (*mountPoint, error) {
func parseBindMount(spec string, mountLabel string, config *runconfig.Config) (*mountPoint, error) {
bind := &mountPoint{
RW: true,
}
@ -61,10 +64,17 @@ func parseBindMount(spec string, config *runconfig.Config) (*mountPoint, error)
bind.Destination = arr[1]
case 3:
bind.Destination = arr[1]
if !validMountMode(arr[2]) {
return nil, fmt.Errorf("invalid mode for volumes-from: %s", arr[2])
mode := arr[2]
if !validMountMode(mode) {
return nil, fmt.Errorf("invalid mode for volumes-from: %s", mode)
}
bind.RW = rwModes[mode]
// check if we need to apply a SELinux label
if strings.ContainsAny(mode, "zZ") {
if err := label.Relabel(bind.Source, mountLabel, mode); err != nil {
return nil, err
}
}
bind.RW = arr[2] == "rw"
default:
return nil, fmt.Errorf("Invalid volume specification: %s", spec)
}
@ -106,12 +116,28 @@ func parseVolumesFrom(spec string) (string, string, error) {
return id, mode, nil
}
// read-write modes
var rwModes = map[string]bool{
"rw": true,
"rw,Z": true,
"rw,z": true,
"z,rw": true,
"Z,rw": true,
"Z": true,
"z": true,
}
// read-only modes
var roModes = map[string]bool{
"ro": true,
"ro,Z": true,
"ro,z": true,
"z,ro": true,
"Z,ro": true,
}
func validMountMode(mode string) bool {
validModes := map[string]bool{
"rw": true,
"ro": true,
}
return validModes[mode]
return roModes[mode] || rwModes[mode]
}
func copyExistingContents(source, destination string) error {
@ -177,10 +203,13 @@ func (daemon *Daemon) registerMountPoints(container *Container, hostConfig *runc
}
}
// lock for labels
runtime.LockOSThread()
defer runtime.UnlockOSThread()
// 3. Read bind mounts
for _, b := range hostConfig.Binds {
// #10618
bind, err := parseBindMount(b, container.Config)
bind, err := parseBindMount(b, container.MountLabel, container.Config)
if err != nil {
return err
}
@ -190,11 +219,26 @@ func (daemon *Daemon) registerMountPoints(container *Container, hostConfig *runc
}
if len(bind.Name) > 0 && len(bind.Driver) > 0 {
// set the label
if err := label.SetFileCreateLabel(container.MountLabel); err != nil {
return fmt.Errorf("Unable to setup default labeling for volume creation %s: %v", bind.Source, err)
}
// create the volume
v, err := createVolume(bind.Name, bind.Driver)
if err != nil {
// reset the label
if e := label.SetFileCreateLabel(""); e != nil {
logrus.Errorf("Unable to reset labeling for volume creation %s: %v", bind.Source, e)
}
return err
}
bind.Volume = v
// reset the label
if err := label.SetFileCreateLabel(""); err != nil {
return fmt.Errorf("Unable to reset labeling for volume creation %s: %v", bind.Source, err)
}
}
binds[bind.Destination] = true
@ -250,7 +294,6 @@ func (daemon *Daemon) verifyOldVolumesInfo(container *Container) error {
func createVolume(name, driverName string) (volume.Volume, error) {
vd, err := getVolumeDriver(driverName)
if err != nil {
return nil, err
}

View file

@ -34,28 +34,29 @@ func TestGetVolumeDriver(t *testing.T) {
func TestParseBindMount(t *testing.T) {
cases := []struct {
bind string
driver string
expDest string
expSource string
expName string
expDriver string
expRW bool
fail bool
bind string
driver string
expDest string
expSource string
expName string
expDriver string
mountLabel string
expRW bool
fail bool
}{
{"/tmp:/tmp", "", "/tmp", "/tmp", "", "", true, false},
{"/tmp:/tmp:ro", "", "/tmp", "/tmp", "", "", false, false},
{"/tmp:/tmp:rw", "", "/tmp", "/tmp", "", "", true, false},
{"/tmp:/tmp:foo", "", "/tmp", "/tmp", "", "", false, true},
{"name:/tmp", "", "/tmp", "", "name", "local", true, false},
{"name:/tmp", "external", "/tmp", "", "name", "external", true, false},
{"name:/tmp:ro", "local", "/tmp", "", "name", "local", false, false},
{"local/name:/tmp:rw", "", "/tmp", "", "local/name", "local", true, false},
{"/tmp:/tmp", "", "/tmp", "/tmp", "", "", "", true, false},
{"/tmp:/tmp:ro", "", "/tmp", "/tmp", "", "", "", false, false},
{"/tmp:/tmp:rw", "", "/tmp", "/tmp", "", "", "", true, false},
{"/tmp:/tmp:foo", "", "/tmp", "/tmp", "", "", "", false, true},
{"name:/tmp", "", "/tmp", "", "name", "local", "", true, false},
{"name:/tmp", "external", "/tmp", "", "name", "external", "", true, false},
{"name:/tmp:ro", "local", "/tmp", "", "name", "local", "", false, false},
{"local/name:/tmp:rw", "", "/tmp", "", "local/name", "local", "", true, false},
}
for _, c := range cases {
conf := &runconfig.Config{VolumeDriver: c.driver}
m, err := parseBindMount(c.bind, conf)
m, err := parseBindMount(c.bind, c.mountLabel, conf)
if c.fail {
if err == nil {
t.Fatalf("Expected error, was nil, for spec %s\n", c.bind)

View file

@ -37,24 +37,25 @@ func TestGetVolumeDefaultDriver(t *testing.T) {
func TestParseBindMount(t *testing.T) {
cases := []struct {
bind string
expDest string
expSource string
expName string
expRW bool
fail bool
bind string
expDest string
expSource string
expName string
mountLabel string
expRW bool
fail bool
}{
{"/tmp:/tmp", "/tmp", "/tmp", "", true, false},
{"/tmp:/tmp:ro", "/tmp", "/tmp", "", false, false},
{"/tmp:/tmp:rw", "/tmp", "/tmp", "", true, false},
{"/tmp:/tmp:foo", "/tmp", "/tmp", "", false, true},
{"name:/tmp", "", "", "", false, true},
{"local/name:/tmp:rw", "", "", "", true, true},
{"/tmp:/tmp", "/tmp", "/tmp", "", "", true, false},
{"/tmp:/tmp:ro", "/tmp", "/tmp", "", "", false, false},
{"/tmp:/tmp:rw", "/tmp", "/tmp", "", "", true, false},
{"/tmp:/tmp:foo", "/tmp", "/tmp", "", "", false, true},
{"name:/tmp", "", "", "", "", false, true},
{"local/name:/tmp:rw", "", "", "", "", true, true},
}
for _, c := range cases {
conf := &runconfig.Config{}
m, err := parseBindMount(c.bind, conf)
m, err := parseBindMount(c.bind, c.mountLabel, conf)
if c.fail {
if err == nil {
t.Fatalf("Expected error, was nil, for spec %s\n", c.bind)