func (d *daemonState) handleNetworkReconfigure() { brIP, brNet, err := network.FindEmptyRange() if err != nil { d.log.Error("Unable to find new network range: %v", err) return } if brIP.Equal(d.network.Gateway) { d.log.Notice("Range %s is still available, not reconfiguring %s.", d.network.GatewayNet.String(), brNet.String()) return } d.log.Notice("Network has changed, reconfiguring %s to %s", d.network.GatewayNet.String(), brNet.String()) newhtn, err := d.network.BridgeReconfigure(d.log) if err != nil { d.log.Error("Unable to reconfigure bridge network: %v", err) return } d.network = newhtn for _, sbox := range d.sandboxes { if sbox.profile.Networking.Nettype == network.TYPE_BRIDGE { d.log.Debug("Reconfiguring network for sandbox `%s` (%d).", sbox.profile.Name, sbox.init.Process.Pid) sbox.network, err = network.PrepareSandboxNetwork(sbox.network, d.network, d.log) if err != nil { d.log.Error("Unable to prepare reconfigure of sandbox `%s` networking: %v", sbox.profile.Name, err) continue } if err := network.NetReconfigure(sbox.network, d.network, sbox.init.Process.Pid, d.log); err != nil { d.log.Error("Unable to reconfigure sandbox `%s` networking: %v", sbox.profile.Name, err) continue } } } return }
func (d *daemonState) launch(p *oz.Profile, msg *LaunchMsg, rawEnv []string, uid, gid uint32, log *logging.Logger) (*Sandbox, error) { /* u, err := user.LookupId(fmt.Sprintf("%d", uid)) if err != nil { return nil, fmt.Errorf("failed to lookup user for uid=%d: %v", uid, err) } fs := fs.NewFromProfile(p, u, d.config.SandboxPath, d.config.UseFullDev, d.log) if err := fs.Setup(d.config.ProfileDir); err != nil { return nil, err } */ u, err := user.LookupId(strconv.FormatUint(uint64(uid), 10)) if err != nil { return nil, fmt.Errorf("Failed to look up user with uid=%ld: %v", uid, err) } groups, err := d.sanitizeGroups(p, u.Username, msg.Gids) if err != nil { return nil, fmt.Errorf("Unable to sanitize user groups: %v", err) } display := 0 if p.XServer.Enabled && p.Networking.Nettype == network.TYPE_HOST { display = d.nextDisplay d.nextDisplay += 1 } stn := new(network.SandboxNetwork) stn.Nettype = p.Networking.Nettype if p.Networking.Nettype == network.TYPE_BRIDGE { stn, err = network.PrepareSandboxNetwork(nil, d.network, log) if err != nil { return nil, fmt.Errorf("Unable to prepare veth network: %+v", err) } if err := network.NetInit(stn, d.network, log); err != nil { return nil, fmt.Errorf("Unable to create veth networking: %+v", err) } } socketPath, err := createSocketPath(path.Join(d.config.SandboxPath, "sockets")) if err != nil { return nil, fmt.Errorf("Failed to create random socket path: %v", err) } initPath := path.Join(d.config.PrefixPath, "bin", "oz-init") cmd := createInitCommand(initPath, (stn.Nettype != network.TYPE_HOST)) pp, err := cmd.StderrPipe() if err != nil { //fs.Cleanup() return nil, fmt.Errorf("error creating stderr pipe for init process: %v", err) } pi, err := cmd.StdinPipe() if err != nil { //fs.Cleanup() return nil, fmt.Errorf("error creating stdin pipe for init process: %v", err) } jdata, err := json.Marshal(ozinit.InitData{ Display: display, User: *u, Uid: uid, Gid: gid, Gids: groups, Network: network.SandboxNetwork{ Interface: stn.Interface, VethHost: stn.VethHost, VethGuest: stn.VethGuest, Ip: stn.Ip, Gateway: stn.Gateway, Class: stn.Class, Nettype: stn.Nettype, }, Profile: *p, Config: *d.config, Sockaddr: socketPath, LaunchEnv: msg.Env, }) if err != nil { return nil, fmt.Errorf("Unable to marshal init state: %+v", err) } io.Copy(pi, bytes.NewBuffer(jdata)) pi.Close() if err := cmd.Start(); err != nil { //fs.Cleanup() return nil, fmt.Errorf("Unable to start process: %+v", err) } //rootfs := path.Join(d.config.SandboxPath, "rootfs") sbox := &Sandbox{ daemon: d, id: d.nextSboxId, display: display, profile: p, init: cmd, cred: &syscall.Credential{Uid: uid, Gid: gid, Groups: msg.Gids}, user: u, fs: fs.NewFilesystem(d.config, log), //addr: path.Join(rootfs, ozinit.SocketAddress), addr: socketPath, stderr: pp, network: stn, rawEnv: rawEnv, } sbox.ready.Add(1) sbox.waiting.Add(1) go sbox.logMessages() sbox.waiting.Wait() if p.Networking.Nettype == network.TYPE_BRIDGE { if err := network.NetAttach(stn, d.network, cmd.Process.Pid); err != nil { cmd.Process.Kill() return nil, fmt.Errorf("Unable to attach veth networking: %+v", err) } } cmd.Process.Signal(syscall.SIGUSR1) wgNet := new(sync.WaitGroup) if p.Networking.Nettype != network.TYPE_HOST && p.Networking.Nettype != network.TYPE_NONE && len(p.Networking.Sockets) > 0 { wgNet.Add(1) go func() { defer wgNet.Done() sbox.ready.Wait() err := network.ProxySetup(sbox.init.Process.Pid, p.Networking.Sockets, d.log, sbox.ready) if err != nil { log.Warning("Unable to create connection proxy: %+s", err) } }() } if !msg.Noexec { go func() { sbox.ready.Wait() wgNet.Wait() go sbox.launchProgram(d.config.PrefixPath, msg.Path, msg.Pwd, msg.Args, log) }() } if sbox.profile.XServer.Enabled { go func() { sbox.ready.Wait() go sbox.startXpraClient() }() } d.nextSboxId += 1 d.sandboxes = append(d.sandboxes, sbox) return sbox, nil }