/
namespaces.go
96 lines (86 loc) · 3.31 KB
/
namespaces.go
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
package container
import (
"errors"
"fmt"
"github.com/cri-o/cri-o/internal/config/nsmgr"
"github.com/cri-o/cri-o/internal/lib/sandbox"
oci "github.com/cri-o/cri-o/internal/oci"
"github.com/cri-o/cri-o/pkg/config"
rspec "github.com/opencontainers/runtime-spec/specs-go"
"github.com/opencontainers/runtime-tools/generate"
types "k8s.io/cri-api/pkg/apis/runtime/v1"
)
func (c *container) SpecAddNamespaces(sb *sandbox.Sandbox, targetCtr *oci.Container, serverConfig *config.Config) error {
// Join the namespace paths for the pod sandbox container.
if err := ConfigureGeneratorGivenNamespacePaths(sb.NamespacePaths(), &c.spec); err != nil {
return fmt.Errorf("failed to configure namespaces in container create: %w", err)
}
sc := c.config.Linux.SecurityContext
if sc.NamespaceOptions.Network == types.NamespaceMode_NODE {
if err := c.spec.RemoveLinuxNamespace(string(rspec.NetworkNamespace)); err != nil {
return err
}
}
switch sc.NamespaceOptions.Pid {
case types.NamespaceMode_NODE:
// kubernetes PodSpec specify to use Host PID namespace
if err := c.spec.RemoveLinuxNamespace(string(rspec.PIDNamespace)); err != nil {
return err
}
case types.NamespaceMode_POD:
pidNsPath := sb.PidNsPath()
if pidNsPath == "" {
if sb.NamespaceOptions().Pid != types.NamespaceMode_POD {
return errors.New("pod level PID namespace requested for the container, but pod sandbox was not similarly configured, and does not have an infra container")
}
return errors.New("PID namespace requested, but sandbox infra container unexpectedly invalid")
}
if err := c.spec.AddOrReplaceLinuxNamespace(string(rspec.PIDNamespace), pidNsPath); err != nil {
return fmt.Errorf("updating container PID namespace to pod: %w", err)
}
case types.NamespaceMode_TARGET:
if targetCtr == nil {
return errors.New("target PID namespace specified with invalid target ID")
}
targetPID, err := targetCtr.Pid()
if err != nil {
return fmt.Errorf("target PID namespace find PID: %w", err)
}
ns, err := serverConfig.NamespaceManager().NamespaceFromProcEntry(targetPID, nsmgr.PIDNS)
if err != nil {
return fmt.Errorf("target PID namespace from proc: %w", err)
}
if err := c.spec.AddOrReplaceLinuxNamespace(string(rspec.PIDNamespace), ns.Path()); err != nil {
return fmt.Errorf("updating container PID namespace to target %s: %w", targetCtr.ID(), err)
}
c.pidns = ns
}
return nil
}
// ConfigureGeneratorGivenNamespacePaths takes a map of nsType -> nsPath. It configures the generator
// to add or replace the defaults to these paths
func ConfigureGeneratorGivenNamespacePaths(managedNamespaces []*sandbox.ManagedNamespace, g *generate.Generator) error {
typeToSpec := map[nsmgr.NSType]rspec.LinuxNamespaceType{
nsmgr.IPCNS: rspec.IPCNamespace,
nsmgr.NETNS: rspec.NetworkNamespace,
nsmgr.UTSNS: rspec.UTSNamespace,
nsmgr.USERNS: rspec.UserNamespace,
}
for _, ns := range managedNamespaces {
// allow for empty paths, as this namespace just shouldn't be configured
if ns.Path() == "" {
continue
}
nsForSpec := typeToSpec[ns.Type()]
if nsForSpec == "" {
return fmt.Errorf("invalid namespace type %s", ns.Type())
}
if err := g.AddOrReplaceLinuxNamespace(string(nsForSpec), ns.Path()); err != nil {
return err
}
}
return nil
}
func (c *container) PidNamespace() nsmgr.Namespace {
return c.pidns
}