|
9 | 9 | "os/exec"
|
10 | 10 | "path"
|
11 | 11 | "path/filepath"
|
| 12 | + "regexp" |
12 | 13 | "strings"
|
13 | 14 | "time"
|
14 | 15 |
|
@@ -42,6 +43,17 @@ var createCmd = cli.Command{
|
42 | 43 | },
|
43 | 44 | }
|
44 | 45 |
|
| 46 | +// maps from CRIO namespace names to LXC names |
| 47 | +var NamespaceMap = map[string]string{ |
| 48 | + "cgroup": "cgroup", |
| 49 | + "ipc": "ipc", |
| 50 | + "mount": "mnt", |
| 51 | + "network": "net", |
| 52 | + "pid": "pid", |
| 53 | + "user": "user", |
| 54 | + "uts": "uts", |
| 55 | +} |
| 56 | + |
45 | 57 | func ensureShell(rootfs string) {
|
46 | 58 | shPath := filepath.Join(rootfs, "bin/sh")
|
47 | 59 | if exists, _ := pathExists(shPath); exists {
|
@@ -80,6 +92,49 @@ exec $@
|
80 | 92 | return ioutil.WriteFile(file, []byte(fifoWaiter), 0755)
|
81 | 93 | }
|
82 | 94 |
|
| 95 | +func configureNamespaces(c *lxc.Container, spec *specs.Spec) error { |
| 96 | + procPidPathRE := regexp.MustCompile(`/proc/(\d+)/ns`) |
| 97 | + |
| 98 | + var nsToClone []string |
| 99 | + var configVal string |
| 100 | + seenNamespaceTypes := map[specs.LinuxNamespaceType]bool{} |
| 101 | + for _, ns := range spec.Linux.Namespaces { |
| 102 | + if _, ok := seenNamespaceTypes[ns.Type]; ok == true { |
| 103 | + return fmt.Errorf("duplicate namespace type %s", ns.Type) |
| 104 | + } |
| 105 | + seenNamespaceTypes[ns.Type] = true |
| 106 | + if ns.Path == "" { |
| 107 | + nsToClone = append(nsToClone, NamespaceMap[string(ns.Type)]) |
| 108 | + } else { |
| 109 | + configKey := fmt.Sprintf("lxc.namespace.share.%s", NamespaceMap[string(ns.Type)]) |
| 110 | + |
| 111 | + matches := procPidPathRE.FindStringSubmatch(ns.Path) |
| 112 | + switch len(matches) { |
| 113 | + case 0: |
| 114 | + configVal = ns.Path |
| 115 | + case 1: |
| 116 | + return fmt.Errorf("error parsing namespace path. expected /proc/(\\d+)/ns/*, got '%s'", ns.Path) |
| 117 | + case 2: |
| 118 | + configVal = matches[1] |
| 119 | + default: |
| 120 | + return fmt.Errorf("error parsing namespace path. expected /proc/(\\d+)/ns/*, got '%s'", ns.Path) |
| 121 | + } |
| 122 | + |
| 123 | + if err := c.SetConfigItem(configKey, configVal); err != nil { |
| 124 | + return errors.Wrapf(err, "failed to set namespace config: '%s'='%s'", configKey, configVal) |
| 125 | + } |
| 126 | + } |
| 127 | + } |
| 128 | + |
| 129 | + if len(nsToClone) > 0 { |
| 130 | + configVal = strings.Join(nsToClone, " ") |
| 131 | + if err := c.SetConfigItem("lxc.namespace.clone", configVal); err != nil { |
| 132 | + return errors.Wrapf(err, "failed to set lxc.namespace.clone=%s", configVal) |
| 133 | + } |
| 134 | + } |
| 135 | + return nil |
| 136 | +} |
| 137 | + |
83 | 138 | func doCreate(ctx *cli.Context) error {
|
84 | 139 | pidfile := ctx.String("pid-file")
|
85 | 140 | containerID := ctx.Args().Get(0)
|
@@ -202,6 +257,10 @@ func configureContainer(ctx *cli.Context, c *lxc.Container, spec *specs.Spec) er
|
202 | 257 | return errors.Wrap(err, "failed to set hook version")
|
203 | 258 | }
|
204 | 259 |
|
| 260 | + if err := configureNamespaces(c, spec); err != nil { |
| 261 | + return errors.Wrap(err, "failed to configure namespaces") |
| 262 | + } |
| 263 | + |
205 | 264 | // capabilities?
|
206 | 265 |
|
207 | 266 | // if !spec.Process.Terminal {
|
|
0 commit comments