Skip to content

Commit

Permalink
feature: namespace options and supplemental groups for cri manager
Browse files Browse the repository at this point in the history
Signed-off-by: YaoZengzeng <[email protected]>
  • Loading branch information
YaoZengzeng committed Mar 5, 2018
1 parent 905dcfe commit 4aaf513
Show file tree
Hide file tree
Showing 11 changed files with 163 additions and 18 deletions.
2 changes: 2 additions & 0 deletions cli/common_flags.go
Original file line number Diff line number Diff line change
Expand Up @@ -69,6 +69,8 @@ func addCommonFlags(flagSet *pflag.FlagSet) *container {
// user
flagSet.StringVarP(&c.user, "user", "u", "", "UID")

flagSet.StringSliceVar(&c.groupAdd, "group-add", nil, "Add additional groups to join")

flagSet.StringVar(&c.utsMode, "uts", "", "UTS namespace to use")

flagSet.StringSliceVarP(&c.volume, "volume", "v", nil, "Bind mount volumes to container")
Expand Down
2 changes: 2 additions & 0 deletions cli/container.go
Original file line number Diff line number Diff line change
Expand Up @@ -23,6 +23,7 @@ type container struct {
entrypoint string
workdir string
user string
groupAdd []string
hostname string
cpushare int64
cpusetcpus string
Expand Down Expand Up @@ -177,6 +178,7 @@ func (c *container) config() (*types.ContainerCreateConfig, error) {
IpcMode: c.ipcMode,
PidMode: c.pidMode,
UTSMode: c.utsMode,
GroupAdd: c.groupAdd,
Sysctls: sysctls,
SecurityOpt: c.securityOpt,
NetworkMode: networkMode,
Expand Down
1 change: 0 additions & 1 deletion cri/stream/httpstream/spdy/upgrade.go
Original file line number Diff line number Diff line change
Expand Up @@ -76,7 +76,6 @@ func (u responseUpgrader) UpgradeResponse(w http.ResponseWriter, req *http.Reque
w.Header().Add(httpstream.HeaderUpgrade, HeaderSpdy31)
w.WriteHeader(http.StatusSwitchingProtocols)

// 获取底层的连接
conn, bufrw, err := hijacker.Hijack()
if err != nil {
logrus.Errorf("unable to upgrade: error hijacking response: %v", err)
Expand Down
1 change: 0 additions & 1 deletion cri/stream/request_cache.go
Original file line number Diff line number Diff line change
Expand Up @@ -62,7 +62,6 @@ func (c *requestCache) Insert(req request) (token string, err error) {
if err != nil {
return "", err
}
// 将cache entry加入list
ele := c.ll.PushFront(&cacheEntry{token, req, time.Now().Add(CacheTTL)})

c.tokens[token] = ele
Expand Down
3 changes: 3 additions & 0 deletions daemon/mgr/cri.go
Original file line number Diff line number Diff line change
Expand Up @@ -48,6 +48,9 @@ const (
// TODO: specify them in the parameters of pouchd.
streamServerAddress = ""
streamServerPort = "10010"

namespaceModeHost = "host"
namespaceModeNone = "none"
)

var (
Expand Down
86 changes: 82 additions & 4 deletions daemon/mgr/cri_utils.go
Original file line number Diff line number Diff line change
Expand Up @@ -157,12 +157,59 @@ func parseSandboxName(name string) (*runtime.PodSandboxMetadata, error) {
}, nil
}

func modifySandboxNamespaceOptions(nsOpts *runtime.NamespaceOption, hostConfig *apitypes.HostConfig) {
if nsOpts == nil {
return
}
if nsOpts.HostPid {
hostConfig.PidMode = namespaceModeHost
}
if nsOpts.HostIpc {
hostConfig.IpcMode = namespaceModeHost
}
if nsOpts.HostNetwork {
hostConfig.NetworkMode = namespaceModeHost
}
}

func applySandboxSecurityContext(lc *runtime.LinuxPodSandboxConfig, config *apitypes.ContainerConfig, hc *apitypes.HostConfig) error {
if lc == nil {
return nil
}

var sc *runtime.LinuxContainerSecurityContext
if lc.SecurityContext != nil {
sc = &runtime.LinuxContainerSecurityContext{
SupplementalGroups: lc.SecurityContext.SupplementalGroups,
RunAsUser: lc.SecurityContext.RunAsUser,
ReadonlyRootfs: lc.SecurityContext.ReadonlyRootfs,
SelinuxOptions: lc.SecurityContext.SelinuxOptions,
NamespaceOptions: lc.SecurityContext.NamespaceOptions,
}
}

modifyContainerConfig(sc, config)
err := modifyHostConfig(sc, hc)
if err != nil {
return err
}
modifySandboxNamespaceOptions(sc.GetNamespaceOptions(), hc)

return nil
}

// applySandboxLinuxOptions applies LinuxPodSandboxConfig to pouch's HostConfig and ContainerCreateConfig.
func applySandboxLinuxOptions(hc *apitypes.HostConfig, lc *runtime.LinuxPodSandboxConfig, createConfig *apitypes.ContainerCreateConfig, image string) error {
if lc == nil {
return nil
}

// Apply security context.
err := applySandboxSecurityContext(lc, &createConfig.ContainerConfig, hc)
if err != nil {
return err
}

// Set sysctls.
hc.Sysctls = lc.Sysctls
return nil
Expand Down Expand Up @@ -292,10 +339,36 @@ func parseContainerName(name string) (*runtime.ContainerMetadata, error) {
func modifyContainerNamespaceOptions(nsOpts *runtime.NamespaceOption, podSandboxID string, hostConfig *apitypes.HostConfig) {
sandboxNSMode := fmt.Sprintf("container:%v", podSandboxID)

hostConfig.PidMode = sandboxNSMode
hostConfig.NetworkMode = sandboxNSMode
hostConfig.IpcMode = sandboxNSMode
hostConfig.UTSMode = sandboxNSMode
if nsOpts == nil {
hostConfig.PidMode = sandboxNSMode
hostConfig.IpcMode = sandboxNSMode
hostConfig.NetworkMode = sandboxNSMode
return
}

for _, n := range []struct {
hostMode bool
nsMode *string
}{
{
hostMode: nsOpts.HostPid,
nsMode: &hostConfig.PidMode,
},
{
hostMode: nsOpts.HostIpc,
nsMode: &hostConfig.IpcMode,
},
{
hostMode: nsOpts.HostNetwork,
nsMode: &hostConfig.NetworkMode,
},
} {
if n.hostMode {
*n.nsMode = namespaceModeHost
} else {
*n.nsMode = sandboxNSMode
}
}
}

// getAppArmorSecurityOpts gets appArmor options from container config.
Expand Down Expand Up @@ -346,6 +419,11 @@ func modifyHostConfig(sc *runtime.LinuxContainerSecurityContext, hostConfig *api
return nil
}

// Apply supplemental groups.
for _, group := range sc.SupplementalGroups {
hostConfig.GroupAdd = append(hostConfig.GroupAdd, strconv.FormatInt(group, 10))
}

// TODO: apply other security options.

// Apply capability options.
Expand Down
30 changes: 20 additions & 10 deletions daemon/mgr/spec_process.go
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@ import (
"strings"

specs "github.com/opencontainers/runtime-spec/specs-go"
"github.com/sirupsen/logrus"
)

func setupCap(ctx context.Context, c *ContainerMeta, spec *SpecWrapper) error {
Expand Down Expand Up @@ -62,21 +63,30 @@ func setupProcessTTY(ctx context.Context, c *ContainerMeta, spec *SpecWrapper) e
}

func setupProcessUser(ctx context.Context, c *ContainerMeta, spec *SpecWrapper) (err error) {
user := specs.User{}

// The user option is complicated, now we only handle case "uid".
// TODO: handle other cases like "user", "uid:gid", etc.
if c.Config.User == "" {
return nil
if c.Config.User != "" {
fields := strings.Split(c.Config.User, ":")
var u string
u = fields[0]
if uid, err := strconv.Atoi(u); err == nil {
user.UID = uint32(uid)
} else {
user.Username = u
}
}

fields := strings.Split(c.Config.User, ":")
var u string
u = fields[0]
user := specs.User{}
if uid, err := strconv.Atoi(u); err == nil {
user.UID = uint32(uid)
} else {
user.Username = u
for _, group := range c.HostConfig.GroupAdd {
gid, err := strconv.ParseUint(group, 10, 32)
if err != nil {
logrus.Errorf("failed to parse supplemental group id %s: %v", group, err)
continue
}
user.AdditionalGids = append(user.AdditionalGids, uint32(gid))
}

spec.s.Process.User = user

return nil
Expand Down
4 changes: 2 additions & 2 deletions hack/cri-test/test-cri.sh
Original file line number Diff line number Diff line change
Expand Up @@ -23,10 +23,10 @@ POUCH_SOCK="/var/run/pouchcri.sock"

# CRI_FOCUS focuses the test to run.
# With the CRI manager completes its function, we may need to expand this field.
CRI_FOCUS=${CRI_FOCUS:-"PodSandbox|AppArmor|Privileged is true|basic operations on container|Runtime info|mount propagation|volume and device|RunAsUser|container port|exec|attach"}
CRI_FOCUS=${CRI_FOCUS:-"PodSandbox|AppArmor|Privileged is true|basic operations on container|Runtime info|mount propagation|volume and device|RunAsUser|container port|exec|attach|NamespaceOption|SupplementalGroups"}

# CRI_SKIP skips the test to skip.
CRI_SKIP=${CRI_SKIP:-"RunAsUserName"}
CRI_SKIP=${CRI_SKIP:-"RunAsUserName|HostNetwork"}
# REPORT_DIR is the the directory to store test logs.
REPORT_DIR=${REPORT_DIR:-"/tmp/test-cri"}

Expand Down
25 changes: 25 additions & 0 deletions test/cli_create_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -358,6 +358,31 @@ func (suite *PouchCreateSuite) TestCreateWithUser(c *check.C) {
c.Assert(result.Config.User, check.Equals, user)
}

// TestCreateWithSupplementalGroups tests creating container with supplemental groups.
func (suite *PouchCreateSuite) TestCreateWithSupplementalGroups(c *check.C) {
name := "TestCreateWithSupplementalGroups"
group := "777"

res := command.PouchRun("create", "--name", name, "--group-add", group, busyboxImage)
res.Assert(c, icmd.Success)

output := command.PouchRun("inspect", name).Stdout()

result := &types.ContainerJSON{}
if err := json.Unmarshal([]byte(output), result); err != nil {
c.Errorf("failed to decode inspect output: %v", err)
}

exist := false
for _, g := range result.HostConfig.GroupAdd {
if group == g {
exist = true
}
}

c.Assert(exist, check.Equals, true)
}

// TestCreateWithIntelRdt tests creating container with Intel Rdt.
func (suite *PouchCreateSuite) TestCreateWithIntelRdt(c *check.C) {
name := "TestCreateWithIntelRdt"
Expand Down
15 changes: 15 additions & 0 deletions test/cli_run_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -283,6 +283,21 @@ func (suite *PouchRunSuite) TestRunWithUser(c *check.C) {
command.PouchRun("rm", "-f", name).Assert(c, icmd.Success)
}

// TestRunWithSupplementalGroups is to verify run container with supplemental groups.
func (suite *PouchRunSuite) TestRunWithSupplementalGroups(c *check.C) {
group := "777"
name := "run-supplemental-group"

res := command.PouchRun("run", "--name", name, "--group-add", group, busyboxImage)
res.Assert(c, icmd.Success)

output := command.PouchRun("exec", name, "id", "-G").Stdout()
if !strings.Contains(output, user) {
c.Fatalf("failed to run a container with supplemental groups: %s", output)
}
command.PouchRun("rm", "-f", name).Assert(c, icmd.Success)
}

// TestRunWithAppArmor is to verify run container with security option AppArmor.
func (suite *PouchRunSuite) TestRunWithAppArmor(c *check.C) {
appArmor := "apparmor=unconfined"
Expand Down
12 changes: 12 additions & 0 deletions test/cli_start_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -138,6 +138,18 @@ func (suite *PouchStartSuite) TestStartWithUser(c *check.C) {
}
}

// TestStartWithSupplementalGroups starts a container with supplemental groups.
func (suite *PouchStartSuite) TestStartWithSupplementalGroups(c *check.C) {
name := "start-supplement-groups"
group := "777"

command.PouchRun("create", "--name", name, "--group-add", group, busyboxImage, "id", "-G")
output := command.PouchRun("start", "-a", name).Stdout()
if !strings.Contains(output, group) {
c.Errorf("failed to start a container with supplemental groups: %s", output)
}
}

// TestStartWithHostname starts a container with hostname.
func (suite *PouchStartSuite) TestStartWithHostname(c *check.C) {
name := "start-hostname"
Expand Down

0 comments on commit 4aaf513

Please sign in to comment.