// relabelVolumes relabels SELinux volumes to match the pod's
// SELinuxOptions specification. This is only needed if the pod uses
// hostPID or hostIPC. Otherwise relabeling is delegated to docker.
func (kl *Kubelet) relabelVolumes(pod *api.Pod, volumes kubecontainer.VolumeMap) error {
	if pod.Spec.SecurityContext.SELinuxOptions == nil {
		return nil
	}

	rootDirContext, err := kl.getRootDirContext()
	if err != nil {
		return err
	}

	selinuxRunner := selinux.NewSelinuxContextRunner()
	// Apply the pod's Level to the rootDirContext
	rootDirSELinuxOptions, err := securitycontext.ParseSELinuxOptions(rootDirContext)
	if err != nil {
		return err
	}

	rootDirSELinuxOptions.Level = pod.Spec.SecurityContext.SELinuxOptions.Level
	volumeContext := fmt.Sprintf("%s:%s:%s:%s", rootDirSELinuxOptions.User, rootDirSELinuxOptions.Role, rootDirSELinuxOptions.Type, rootDirSELinuxOptions.Level)

	for _, vol := range volumes {
		if vol.Mounter.GetAttributes().Managed && vol.Mounter.GetAttributes().SupportsSELinux {
			// Relabel the volume and its content to match the 'Level' of the pod
			path, err := volume.GetPath(vol.Mounter)
			if err != nil {
				return err
			}
			err = filepath.Walk(path, func(path string, info os.FileInfo, err error) error {
				if err != nil {
					return err
				}
				return selinuxRunner.SetContext(path, volumeContext)
			})
			if err != nil {
				return err
			}
			vol.SELinuxLabeled = true
		}
	}
	return nil
}
// determineEffectiveSELinuxOptions determines the effective SELinux options
// that should be used for a particular plugin.
func (ed *emptyDir) determineEffectiveSELinuxOptions() (string, error) {
	glog.V(4).Infof("Determining effective SELinux context for pod %v/%v", ed.pod.Namespace, ed.pod.Name)
	var opts *api.SELinuxOptions
	if ed.pod != nil {
		// Use the security context, if defined, of the first
		// container in the pod to mount this volume
		for _, container := range ed.pod.Spec.Containers {
			if !volumeutil.ContainerHasVolumeMountForName(&container, ed.volName) {
				continue
			}

			if container.SecurityContext != nil &&
				container.SecurityContext.SELinuxOptions != nil {
				opts = container.SecurityContext.SELinuxOptions
				break
			}
		}
	}

	if opts == nil {
		return ed.rootContext, nil
	}

	glog.V(4).Infof("Specified security context for pod %v/%v: %v", ed.pod.Namespace, ed.pod.Name, securitycontext.SELinuxOptionsString(opts))

	rootContextOpts, err := securitycontext.ParseSELinuxOptions(ed.rootContext)
	if err != nil {
		return "", err
	}

	effectiveOpts := securitycontext.ProjectSELinuxOptions(opts, rootContextOpts)

	glog.V(4).Infof("Effective SELinux context for pod %v/%v: %v", ed.pod.Namespace, ed.pod.Name, securitycontext.SELinuxOptionsString(effectiveOpts))

	return securitycontext.SELinuxOptionsString(effectiveOpts), nil
}