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

Add Getfilecon() into the selinux interface.
This commit is contained in:
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 return err
} }
chconRunner := selinux.NewChconRunner() selinuxRunner := selinux.NewSelinuxContextRunner()
// Apply the pod's Level to the rootDirContext // Apply the pod's Level to the rootDirContext
rootDirSELinuxOptions, err := securitycontext.ParseSELinuxOptions(rootDirContext) rootDirSELinuxOptions, err := securitycontext.ParseSELinuxOptions(rootDirContext)
if err != nil { if err != nil {
@ -1226,7 +1226,7 @@ func (kl *Kubelet) relabelVolumes(pod *api.Pod, volumes kubecontainer.VolumeMap)
if err != nil { if err != nil {
return err return err
} }
return chconRunner.SetContext(path, volumeContext) return selinuxRunner.SetContext(path, volumeContext)
}) })
if err != nil { if err != nil {
return err return err

View File

@ -58,6 +58,7 @@ import (
"k8s.io/kubernetes/pkg/util/errors" "k8s.io/kubernetes/pkg/util/errors"
utilexec "k8s.io/kubernetes/pkg/util/exec" utilexec "k8s.io/kubernetes/pkg/util/exec"
"k8s.io/kubernetes/pkg/util/flowcontrol" "k8s.io/kubernetes/pkg/util/flowcontrol"
"k8s.io/kubernetes/pkg/util/selinux"
utilstrings "k8s.io/kubernetes/pkg/util/strings" utilstrings "k8s.io/kubernetes/pkg/util/strings"
utilwait "k8s.io/kubernetes/pkg/util/wait" utilwait "k8s.io/kubernetes/pkg/util/wait"
) )
@ -1002,6 +1003,34 @@ func (r *Runtime) preparePodArgs(manifest *appcschema.PodManifest, manifestFileN
return cmds 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: // preparePod will:
// //
// 1. Invoke 'rkt prepare' to prepare the pod, and get the rkt pod uuid. // 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 { if pod.Spec.SecurityContext != nil && pod.Spec.SecurityContext.SELinuxOptions != nil {
opt := pod.Spec.SecurityContext.SELinuxOptions 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)) units = append(units, newUnitOption("Service", "SELinuxContext", selinuxContext))
} }

View File

@ -1172,27 +1172,6 @@ func TestGenerateRunCommand(t *testing.T) {
nil, 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), 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{ rkt := &Runtime{

View File

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

View File

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