rkt: Fix incomplete selinux context string when the option is partial.

Add Getfilecon() into the selinux interface.
pull/6/head
Yifan Gu 2016-06-06 16:23:16 -07:00
parent e49e367cd1
commit 8596d25ad5
6 changed files with 61 additions and 33 deletions

View File

@ -1209,7 +1209,7 @@ func (kl *Kubelet) relabelVolumes(pod *api.Pod, volumes kubecontainer.VolumeMap)
return err
}
chconRunner := selinux.NewChconRunner()
selinuxRunner := selinux.NewSelinuxContextRunner()
// Apply the pod's Level to the rootDirContext
rootDirSELinuxOptions, err := securitycontext.ParseSELinuxOptions(rootDirContext)
if err != nil {
@ -1226,7 +1226,7 @@ func (kl *Kubelet) relabelVolumes(pod *api.Pod, volumes kubecontainer.VolumeMap)
if err != nil {
return err
}
return chconRunner.SetContext(path, volumeContext)
return selinuxRunner.SetContext(path, volumeContext)
})
if err != nil {
return err

View File

@ -58,6 +58,7 @@ import (
"k8s.io/kubernetes/pkg/util/errors"
utilexec "k8s.io/kubernetes/pkg/util/exec"
"k8s.io/kubernetes/pkg/util/flowcontrol"
"k8s.io/kubernetes/pkg/util/selinux"
utilstrings "k8s.io/kubernetes/pkg/util/strings"
utilwait "k8s.io/kubernetes/pkg/util/wait"
)
@ -1002,6 +1003,34 @@ func (r *Runtime) preparePodArgs(manifest *appcschema.PodManifest, manifestFileN
return cmds
}
func (r *Runtime) getSelinuxContext(opt *api.SELinuxOptions) (string, error) {
selinuxRunner := selinux.NewSelinuxContextRunner()
str, err := selinuxRunner.Getfilecon(r.config.Dir)
if err != nil {
return "", err
}
ctx := strings.SplitN(str, ":", 4)
if len(ctx) != 4 {
return "", fmt.Errorf("malformated selinux context")
}
if opt.User != "" {
ctx[0] = opt.User
}
if opt.Role != "" {
ctx[1] = opt.Role
}
if opt.Type != "" {
ctx[2] = opt.Type
}
if opt.Level != "" {
ctx[3] = opt.Level
}
return strings.Join(ctx, ":"), nil
}
// preparePod will:
//
// 1. Invoke 'rkt prepare' to prepare the pod, and get the rkt pod uuid.
@ -1073,7 +1102,11 @@ func (r *Runtime) preparePod(pod *api.Pod, podIP string, pullSecrets []api.Secre
if pod.Spec.SecurityContext != nil && pod.Spec.SecurityContext.SELinuxOptions != nil {
opt := pod.Spec.SecurityContext.SELinuxOptions
selinuxContext := fmt.Sprintf("%s:%s:%s:%s", opt.User, opt.Role, opt.Type, opt.Level)
selinuxContext, err := r.getSelinuxContext(opt)
if err != nil {
glog.Errorf("rkt: Failed to construct selinux context with selinux option %q: %v", opt, err)
return "", nil, err
}
units = append(units, newUnitOption("Service", "SELinuxContext", selinuxContext))
}

View File

@ -1172,27 +1172,6 @@ func TestGenerateRunCommand(t *testing.T) {
nil,
fmt.Sprintf("/bin/rkt/rkt --insecure-options=image,ondisk --local-config=/var/rkt/local/data --dir=/var/data run-prepared --net=host --hostname=%s rkt-uuid-foo", hostName),
},
// Case #5, returns --net=host --no-overlay
{
&api.Pod{
ObjectMeta: api.ObjectMeta{
Name: "pod-name-foo",
},
Spec: api.PodSpec{
SecurityContext: &api.PodSecurityContext{
HostNetwork: true,
SELinuxOptions: &api.SELinuxOptions{},
},
},
},
"rkt-uuid-foo",
"",
[]string{""},
[]string{""},
"pod-hostname-foo",
nil,
fmt.Sprintf("/bin/rkt/rkt --insecure-options=image,ondisk --local-config=/var/rkt/local/data --dir=/var/data run-prepared --no-overlay=true --net=host --hostname=%s rkt-uuid-foo", hostName),
},
}
rkt := &Runtime{

View File

@ -16,12 +16,14 @@ limitations under the License.
package selinux
// chconRunner knows how to chcon a directory.
type ChconRunner interface {
// SelinuxContextRunner knows how to chcon of a directory and
// how to get the selinux context of a file.
type SelinuxContextRunner interface {
SetContext(dir, context string) error
Getfilecon(path string) (string, error)
}
// newChconRunner returns a new chconRunner.
func NewChconRunner() ChconRunner {
return &realChconRunner{}
// NewSelinuxContextRunner returns a new chconRunner.
func NewSelinuxContextRunner() SelinuxContextRunner {
return &realSelinuxContextRunner{}
}

View File

@ -19,12 +19,14 @@ limitations under the License.
package selinux
import (
"fmt"
"github.com/opencontainers/runc/libcontainer/selinux"
)
type realChconRunner struct{}
type realSelinuxContextRunner struct{}
func (_ *realChconRunner) SetContext(dir, context string) error {
func (_ *realSelinuxContextRunner) SetContext(dir, context string) error {
// If SELinux is not enabled, return an empty string
if !selinux.SelinuxEnabled() {
return nil
@ -32,3 +34,10 @@ func (_ *realChconRunner) SetContext(dir, context string) error {
return selinux.Setfilecon(dir, context)
}
func (_ *realSelinuxContextRunner) Getfilecon(path string) (string, error) {
if !selinux.SelinuxEnabled() {
return "", fmt.Errorf("SELinux is not enabled")
}
return selinux.Getfilecon(path)
}

View File

@ -18,9 +18,14 @@ limitations under the License.
package selinux
type realChconRunner struct{}
type realSelinuxContextRunner struct{}
func (_ *realChconRunner) SetContext(dir, context string) error {
func (_ *realSelinuxContextRunner) SetContext(dir, context string) error {
// NOP
return nil
}
func (_ *realSelinuxContextRunner) Getfilecon(path string) (string, error) {
// NOP
return "", nil
}