Exemple #1
0
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
}
Exemple #2
0
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
}