Merge pull request #7973 from mxpv/backport
Backport changes to sandboxed CRI
This commit is contained in:
		@@ -804,6 +804,182 @@ func TestPidNamespace(t *testing.T) {
 | 
			
		||||
	}
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
func TestUserNamespace(t *testing.T) {
 | 
			
		||||
	testID := "test-id"
 | 
			
		||||
	testPid := uint32(1234)
 | 
			
		||||
	testSandboxID := "sandbox-id"
 | 
			
		||||
	testContainerName := "container-name"
 | 
			
		||||
	idMap := runtime.IDMapping{
 | 
			
		||||
		HostId:      1000,
 | 
			
		||||
		ContainerId: 1000,
 | 
			
		||||
		Length:      10,
 | 
			
		||||
	}
 | 
			
		||||
	otherIDMap := runtime.IDMapping{
 | 
			
		||||
		HostId:      2000,
 | 
			
		||||
		ContainerId: 2000,
 | 
			
		||||
		Length:      10,
 | 
			
		||||
	}
 | 
			
		||||
	expIDMap := runtimespec.LinuxIDMapping{
 | 
			
		||||
		HostID:      1000,
 | 
			
		||||
		ContainerID: 1000,
 | 
			
		||||
		Size:        10,
 | 
			
		||||
	}
 | 
			
		||||
	containerConfig, sandboxConfig, imageConfig, _ := getCreateContainerTestData()
 | 
			
		||||
	ociRuntime := config.Runtime{}
 | 
			
		||||
	c := newTestCRIService()
 | 
			
		||||
	for desc, test := range map[string]struct {
 | 
			
		||||
		userNS        *runtime.UserNamespace
 | 
			
		||||
		sandboxUserNS *runtime.UserNamespace
 | 
			
		||||
		expNS         *runtimespec.LinuxNamespace
 | 
			
		||||
		expNotNS      *runtimespec.LinuxNamespace // Does NOT contain this namespace
 | 
			
		||||
		expUIDMapping []runtimespec.LinuxIDMapping
 | 
			
		||||
		expGIDMapping []runtimespec.LinuxIDMapping
 | 
			
		||||
		err           bool
 | 
			
		||||
	}{
 | 
			
		||||
		"node namespace mode": {
 | 
			
		||||
			userNS: &runtime.UserNamespace{Mode: runtime.NamespaceMode_NODE},
 | 
			
		||||
			// Expect userns to NOT be present.
 | 
			
		||||
			expNotNS: &runtimespec.LinuxNamespace{
 | 
			
		||||
				Type: runtimespec.UserNamespace,
 | 
			
		||||
				Path: opts.GetUserNamespace(testPid),
 | 
			
		||||
			},
 | 
			
		||||
		},
 | 
			
		||||
		"node namespace mode with mappings": {
 | 
			
		||||
			userNS: &runtime.UserNamespace{
 | 
			
		||||
				Mode: runtime.NamespaceMode_NODE,
 | 
			
		||||
				Uids: []*runtime.IDMapping{&idMap},
 | 
			
		||||
				Gids: []*runtime.IDMapping{&idMap},
 | 
			
		||||
			},
 | 
			
		||||
			err: true,
 | 
			
		||||
		},
 | 
			
		||||
		"container namespace mode": {
 | 
			
		||||
			userNS: &runtime.UserNamespace{Mode: runtime.NamespaceMode_CONTAINER},
 | 
			
		||||
			err:    true,
 | 
			
		||||
		},
 | 
			
		||||
		"target namespace mode": {
 | 
			
		||||
			userNS: &runtime.UserNamespace{Mode: runtime.NamespaceMode_TARGET},
 | 
			
		||||
			err:    true,
 | 
			
		||||
		},
 | 
			
		||||
		"unknown namespace mode": {
 | 
			
		||||
			userNS: &runtime.UserNamespace{Mode: runtime.NamespaceMode(100)},
 | 
			
		||||
			err:    true,
 | 
			
		||||
		},
 | 
			
		||||
		"pod namespace mode": {
 | 
			
		||||
			userNS: &runtime.UserNamespace{
 | 
			
		||||
				Mode: runtime.NamespaceMode_POD,
 | 
			
		||||
				Uids: []*runtime.IDMapping{&idMap},
 | 
			
		||||
				Gids: []*runtime.IDMapping{&idMap},
 | 
			
		||||
			},
 | 
			
		||||
			expNS: &runtimespec.LinuxNamespace{
 | 
			
		||||
				Type: runtimespec.UserNamespace,
 | 
			
		||||
				Path: opts.GetUserNamespace(testPid),
 | 
			
		||||
			},
 | 
			
		||||
			expUIDMapping: []runtimespec.LinuxIDMapping{expIDMap},
 | 
			
		||||
			expGIDMapping: []runtimespec.LinuxIDMapping{expIDMap},
 | 
			
		||||
		},
 | 
			
		||||
		"pod namespace mode with inconsistent sandbox config (different GIDs)": {
 | 
			
		||||
			userNS: &runtime.UserNamespace{
 | 
			
		||||
				Mode: runtime.NamespaceMode_POD,
 | 
			
		||||
				Uids: []*runtime.IDMapping{&idMap},
 | 
			
		||||
				Gids: []*runtime.IDMapping{&idMap},
 | 
			
		||||
			},
 | 
			
		||||
			sandboxUserNS: &runtime.UserNamespace{
 | 
			
		||||
				Mode: runtime.NamespaceMode_POD,
 | 
			
		||||
				Uids: []*runtime.IDMapping{&idMap},
 | 
			
		||||
				Gids: []*runtime.IDMapping{&otherIDMap},
 | 
			
		||||
			},
 | 
			
		||||
			err: true,
 | 
			
		||||
		},
 | 
			
		||||
		"pod namespace mode with inconsistent sandbox config (different UIDs)": {
 | 
			
		||||
			userNS: &runtime.UserNamespace{
 | 
			
		||||
				Mode: runtime.NamespaceMode_POD,
 | 
			
		||||
				Uids: []*runtime.IDMapping{&idMap},
 | 
			
		||||
				Gids: []*runtime.IDMapping{&idMap},
 | 
			
		||||
			},
 | 
			
		||||
			sandboxUserNS: &runtime.UserNamespace{
 | 
			
		||||
				Mode: runtime.NamespaceMode_POD,
 | 
			
		||||
				Uids: []*runtime.IDMapping{&otherIDMap},
 | 
			
		||||
				Gids: []*runtime.IDMapping{&idMap},
 | 
			
		||||
			},
 | 
			
		||||
			err: true,
 | 
			
		||||
		},
 | 
			
		||||
		"pod namespace mode with inconsistent sandbox config (different len)": {
 | 
			
		||||
			userNS: &runtime.UserNamespace{
 | 
			
		||||
				Mode: runtime.NamespaceMode_POD,
 | 
			
		||||
				Uids: []*runtime.IDMapping{&idMap},
 | 
			
		||||
				Gids: []*runtime.IDMapping{&idMap},
 | 
			
		||||
			},
 | 
			
		||||
			sandboxUserNS: &runtime.UserNamespace{
 | 
			
		||||
				Mode: runtime.NamespaceMode_POD,
 | 
			
		||||
				Uids: []*runtime.IDMapping{&idMap, &idMap},
 | 
			
		||||
				Gids: []*runtime.IDMapping{&idMap, &idMap},
 | 
			
		||||
			},
 | 
			
		||||
			err: true,
 | 
			
		||||
		},
 | 
			
		||||
		"pod namespace mode with inconsistent sandbox config (different mode)": {
 | 
			
		||||
			userNS: &runtime.UserNamespace{
 | 
			
		||||
				Mode: runtime.NamespaceMode_POD,
 | 
			
		||||
				Uids: []*runtime.IDMapping{&idMap},
 | 
			
		||||
				Gids: []*runtime.IDMapping{&idMap},
 | 
			
		||||
			},
 | 
			
		||||
			sandboxUserNS: &runtime.UserNamespace{
 | 
			
		||||
				Mode: runtime.NamespaceMode_NODE,
 | 
			
		||||
				Uids: []*runtime.IDMapping{&idMap},
 | 
			
		||||
				Gids: []*runtime.IDMapping{&idMap},
 | 
			
		||||
			},
 | 
			
		||||
			err: true,
 | 
			
		||||
		},
 | 
			
		||||
		"pod namespace mode with several mappings": {
 | 
			
		||||
			userNS: &runtime.UserNamespace{
 | 
			
		||||
				Mode: runtime.NamespaceMode_POD,
 | 
			
		||||
				Uids: []*runtime.IDMapping{&idMap, &idMap},
 | 
			
		||||
				Gids: []*runtime.IDMapping{&idMap, &idMap},
 | 
			
		||||
			},
 | 
			
		||||
			err: true,
 | 
			
		||||
		},
 | 
			
		||||
		"pod namespace mode with uneven mappings": {
 | 
			
		||||
			userNS: &runtime.UserNamespace{
 | 
			
		||||
				Mode: runtime.NamespaceMode_POD,
 | 
			
		||||
				Uids: []*runtime.IDMapping{&idMap, &idMap},
 | 
			
		||||
				Gids: []*runtime.IDMapping{&idMap},
 | 
			
		||||
			},
 | 
			
		||||
			err: true,
 | 
			
		||||
		},
 | 
			
		||||
	} {
 | 
			
		||||
		desc := desc
 | 
			
		||||
		test := test
 | 
			
		||||
		t.Run(desc, func(t *testing.T) {
 | 
			
		||||
			containerConfig.Linux.SecurityContext.NamespaceOptions = &runtime.NamespaceOption{UsernsOptions: test.userNS}
 | 
			
		||||
			// By default, set sandbox and container config to the same (this is
 | 
			
		||||
			// required by containerSpec). However, if the test wants to test for what
 | 
			
		||||
			// happens when they don't match, the test.sandboxUserNS should be set and
 | 
			
		||||
			// we just use that.
 | 
			
		||||
			sandboxUserns := test.userNS
 | 
			
		||||
			if test.sandboxUserNS != nil {
 | 
			
		||||
				sandboxUserns = test.sandboxUserNS
 | 
			
		||||
			}
 | 
			
		||||
			sandboxConfig.Linux.SecurityContext.NamespaceOptions = &runtime.NamespaceOption{UsernsOptions: sandboxUserns}
 | 
			
		||||
			spec, err := c.buildContainerSpec(currentPlatform, testID, testSandboxID, testPid, "", testContainerName, testImageName, containerConfig, sandboxConfig, imageConfig, nil, ociRuntime)
 | 
			
		||||
 | 
			
		||||
			if test.err {
 | 
			
		||||
				require.Error(t, err)
 | 
			
		||||
				assert.Nil(t, spec)
 | 
			
		||||
				return
 | 
			
		||||
			}
 | 
			
		||||
			require.NoError(t, err)
 | 
			
		||||
			assert.Equal(t, spec.Linux.UIDMappings, test.expUIDMapping)
 | 
			
		||||
			assert.Equal(t, spec.Linux.GIDMappings, test.expGIDMapping)
 | 
			
		||||
 | 
			
		||||
			if test.expNS != nil {
 | 
			
		||||
				assert.Contains(t, spec.Linux.Namespaces, *test.expNS)
 | 
			
		||||
			}
 | 
			
		||||
			if test.expNotNS != nil {
 | 
			
		||||
				assert.NotContains(t, spec.Linux.Namespaces, *test.expNotNS)
 | 
			
		||||
			}
 | 
			
		||||
		})
 | 
			
		||||
	}
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
func TestNoDefaultRunMount(t *testing.T) {
 | 
			
		||||
	testID := "test-id"
 | 
			
		||||
	testPid := uint32(1234)
 | 
			
		||||
 
 | 
			
		||||
@@ -478,7 +478,7 @@ func copyResourcesToStatus(spec *runtimespec.Spec, status containerstore.Status)
 | 
			
		||||
		}
 | 
			
		||||
 | 
			
		||||
		if spec.Linux.Resources.HugepageLimits != nil {
 | 
			
		||||
			hugepageLimits := make([]*runtime.HugepageLimit, len(spec.Linux.Resources.HugepageLimits))
 | 
			
		||||
			hugepageLimits := make([]*runtime.HugepageLimit, 0)
 | 
			
		||||
			for _, l := range spec.Linux.Resources.HugepageLimits {
 | 
			
		||||
				hugepageLimits = append(hugepageLimits, &runtime.HugepageLimit{
 | 
			
		||||
					PageSize: l.Pagesize,
 | 
			
		||||
 
 | 
			
		||||
@@ -425,7 +425,7 @@ func (c *criService) registryHosts(ctx context.Context, auth *runtime.AuthConfig
 | 
			
		||||
				if err != nil {
 | 
			
		||||
					return nil, fmt.Errorf("get TLSConfig for registry %q: %w", e, err)
 | 
			
		||||
				}
 | 
			
		||||
			} else if isLocalHost(host) && u.Scheme == "http" {
 | 
			
		||||
			} else if docker.IsLocalhost(host) && u.Scheme == "http" {
 | 
			
		||||
				// Skipping TLS verification for localhost
 | 
			
		||||
				transport.TLSClientConfig = &tls.Config{
 | 
			
		||||
					InsecureSkipVerify: true,
 | 
			
		||||
@@ -470,26 +470,12 @@ func (c *criService) registryHosts(ctx context.Context, auth *runtime.AuthConfig
 | 
			
		||||
 | 
			
		||||
// defaultScheme returns the default scheme for a registry host.
 | 
			
		||||
func defaultScheme(host string) string {
 | 
			
		||||
	if isLocalHost(host) {
 | 
			
		||||
	if docker.IsLocalhost(host) {
 | 
			
		||||
		return "http"
 | 
			
		||||
	}
 | 
			
		||||
	return "https"
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
// isLocalHost checks if the registry host is local.
 | 
			
		||||
func isLocalHost(host string) bool {
 | 
			
		||||
	if h, _, err := net.SplitHostPort(host); err == nil {
 | 
			
		||||
		host = h
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	if host == "localhost" {
 | 
			
		||||
		return true
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	ip := net.ParseIP(host)
 | 
			
		||||
	return ip.IsLoopback()
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
// addDefaultScheme returns the endpoint with default scheme
 | 
			
		||||
func addDefaultScheme(endpoint string) (string, error) {
 | 
			
		||||
	if strings.Contains(endpoint, "://") {
 | 
			
		||||
 
 | 
			
		||||
@@ -330,6 +330,8 @@ func (c *criService) setupPodNetwork(ctx context.Context, sandbox *sandboxstore.
 | 
			
		||||
		config    = sandbox.Config
 | 
			
		||||
		path      = sandbox.NetNSPath
 | 
			
		||||
		netPlugin = c.getNetworkPlugin(sandbox.RuntimeHandler)
 | 
			
		||||
		err       error
 | 
			
		||||
		result    *cni.Result
 | 
			
		||||
	)
 | 
			
		||||
	if netPlugin == nil {
 | 
			
		||||
		return errors.New("cni config not initialized")
 | 
			
		||||
@@ -341,7 +343,11 @@ func (c *criService) setupPodNetwork(ctx context.Context, sandbox *sandboxstore.
 | 
			
		||||
	}
 | 
			
		||||
	log.G(ctx).WithField("podsandboxid", id).Debugf("begin cni setup")
 | 
			
		||||
	netStart := time.Now()
 | 
			
		||||
	result, err := netPlugin.Setup(ctx, id, path, opts...)
 | 
			
		||||
	if c.config.CniConfig.NetworkPluginSetupSerially {
 | 
			
		||||
		result, err = netPlugin.SetupSerially(ctx, id, path, opts...)
 | 
			
		||||
	} else {
 | 
			
		||||
		result, err = netPlugin.Setup(ctx, id, path, opts...)
 | 
			
		||||
	}
 | 
			
		||||
	networkPluginOperations.WithValues(networkSetUpOp).Inc()
 | 
			
		||||
	networkPluginOperationsLatency.WithValues(networkSetUpOp).UpdateSince(netStart)
 | 
			
		||||
	if err != nil {
 | 
			
		||||
 
 | 
			
		||||
		Reference in New Issue
	
	Block a user