pass all environment from ./oz to applications launched from oz-init

(+ gofmt)
master
brl 9 years ago
parent dee514bd4e
commit d1bb0fdeec

@ -51,7 +51,7 @@ func ListSandboxes() ([]SandboxInfo, error) {
return body.Sandboxes, nil
}
func Launch(arg string) error {
func Launch(arg string, env []string) error {
idx, name, err := parseProfileArg(arg)
if err != nil {
return err
@ -59,6 +59,7 @@ func Launch(arg string) error {
resp, err := clientSend(&LaunchMsg{
Index: idx,
Name: name,
Env: env,
})
if err != nil {
return err

@ -9,7 +9,7 @@ import (
"github.com/subgraph/oz/fs"
"github.com/subgraph/oz/ipc"
"github.com/subgraph/oz/network"
"github.com/op/go-logging"
)
@ -62,7 +62,7 @@ func initialize() *daemonState {
oz.ReapChildProcs(d.log, d.handleChildExit)
d.nextSboxId = 1
d.nextDisplay = 100
for _, pp := range d.profiles {
if pp.Networking.Nettype == "bridge" {
d.log.Info("Initializing bridge networking")
@ -71,12 +71,12 @@ func initialize() *daemonState {
d.log.Fatalf("Failed to initialize bridge networking: %+v", err)
return nil
}
d.network = htn
network.NetPrint(d.log)
break;
break
}
}
@ -125,7 +125,7 @@ func (d *daemonState) handleLaunch(msg *LaunchMsg, m *ipc.Message) error {
return m.Respond(&ErrorMsg{err.Error()})
}
d.Debug("Would launch %s", p.Name)
_, err = d.launch(p, m.Ucred.Uid, m.Ucred.Gid, d.log)
_, err = d.launch(p, msg.Env, m.Ucred.Uid, m.Ucred.Gid, d.log)
if err != nil {
d.Warning("launch of %s failed: %v", p.Name, err)
return m.Respond(&ErrorMsg{err.Error()})

@ -9,13 +9,14 @@ import (
"path"
"sync"
"syscall"
"github.com/subgraph/oz"
"github.com/subgraph/oz/fs"
"github.com/subgraph/oz/xpra"
"github.com/subgraph/oz/network"
"github.com/subgraph/oz/xpra"
"github.com/op/go-logging"
"github.com/subgraph/oz/oz-init"
)
const initPath = "/usr/local/bin/oz-init"
@ -46,7 +47,7 @@ func findSandbox(id int) *Sandbox {
}
*/
func createInitCommand(name, chroot string, uid uint32, display int, stn *network.SandboxNetwork, nettype string) *exec.Cmd {
func createInitCommand(name, chroot string, env []string, uid uint32, display int, stn *network.SandboxNetwork, nettype string) *exec.Cmd {
cmd := exec.Command(initPath)
cmd.Dir = "/"
@ -54,11 +55,11 @@ func createInitCommand(name, chroot string, uid uint32, display int, stn *networ
cloneFlags |= syscall.CLONE_NEWIPC
cloneFlags |= syscall.CLONE_NEWPID
cloneFlags |= syscall.CLONE_NEWUTS
if nettype != "host" {
cloneFlags |= syscall.CLONE_NEWNET
}
cmd.SysProcAttr = &syscall.SysProcAttr{
Chroot: chroot,
Cloneflags: cloneFlags,
@ -67,20 +68,24 @@ func createInitCommand(name, chroot string, uid uint32, display int, stn *networ
"INIT_PROFILE=" + name,
fmt.Sprintf("INIT_UID=%d", uid),
}
if stn.Ip != "" {
cmd.Env = append(cmd.Env, "INIT_ADDR=" + stn.Ip)
cmd.Env = append(cmd.Env, "INIT_VHOST=" + stn.VethHost)
cmd.Env = append(cmd.Env, "INIT_VGUEST=" + stn.VethGuest)
cmd.Env = append(cmd.Env, "INIT_GATEWAY=" + stn.Gateway.String() + "/" + stn.Class)
cmd.Env = append(cmd.Env, "INIT_ADDR="+stn.Ip)
cmd.Env = append(cmd.Env, "INIT_VHOST="+stn.VethHost)
cmd.Env = append(cmd.Env, "INIT_VGUEST="+stn.VethGuest)
cmd.Env = append(cmd.Env, "INIT_GATEWAY="+stn.Gateway.String()+"/"+stn.Class)
}
cmd.Env = append(cmd.Env, fmt.Sprintf("INIT_DISPLAY=%d", display))
for _, e := range env {
cmd.Env = append(cmd.Env, ozinit.EnvPrefix+e)
}
return cmd
}
func (d *daemonState) launch(p *oz.Profile, uid, gid uint32, log *logging.Logger) (*Sandbox, error) {
func (d *daemonState) launch(p *oz.Profile, env []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)
@ -90,11 +95,11 @@ func (d *daemonState) launch(p *oz.Profile, uid, gid uint32, log *logging.Logger
return nil, err
}
display := 0
if p.XServer.Enabled && p.Networking.Nettype == "host" {
if p.XServer.Enabled && p.Networking.Nettype == "host" {
display = d.nextDisplay
d.nextDisplay += 1
}
stn := new(network.SandboxNetwork)
if p.Networking.Nettype == "bridge" {
stn, err = network.PrepareSandboxNetwork(d.network, log)
@ -102,8 +107,8 @@ func (d *daemonState) launch(p *oz.Profile, uid, gid uint32, log *logging.Logger
return nil, fmt.Errorf("Unable to prepare veth network: %+v", err)
}
}
cmd := createInitCommand(p.Name, fs.Root(), uid, display, stn, p.Networking.Nettype)
cmd := createInitCommand(p.Name, fs.Root(), env, uid, display, stn, p.Networking.Nettype)
log.Debug("Command environment: %+v", cmd.Env)
pp, err := cmd.StderrPipe()
if err != nil {
@ -111,13 +116,12 @@ func (d *daemonState) launch(p *oz.Profile, uid, gid uint32, log *logging.Logger
return nil, fmt.Errorf("error creating stderr pipe for init process: %v", err)
}
if err := cmd.Start(); err != nil {
fs.Cleanup()
return nil, fmt.Errorf("Unable to start process: %+v", err)
}
sbox := &Sandbox{
daemon: d,
id: d.nextSboxId,
@ -130,7 +134,7 @@ func (d *daemonState) launch(p *oz.Profile, uid, gid uint32, log *logging.Logger
stderr: pp,
network: stn,
}
if p.Networking.Nettype == "bridge" {
if err := network.NetInit(stn, d.network, cmd.Process.Pid, log); err != nil {
cmd.Process.Kill()
@ -138,7 +142,7 @@ func (d *daemonState) launch(p *oz.Profile, uid, gid uint32, log *logging.Logger
return nil, fmt.Errorf("Unable to create veth networking: %+v", err)
}
}
sbox.ready.Add(1)
go sbox.logMessages()
if sbox.profile.XServer.Enabled {

@ -33,6 +33,7 @@ type ListProfilesResp struct {
type LaunchMsg struct {
Index int "Launch"
Name string
Env []string
}
type ListSandboxesMsg struct {

@ -12,23 +12,25 @@ import (
"strings"
"sync"
"syscall"
"github.com/subgraph/oz"
"github.com/subgraph/oz/fs"
"github.com/subgraph/oz/ipc"
"github.com/subgraph/oz/xpra"
"github.com/subgraph/oz/network"
"github.com/subgraph/oz/xpra"
"github.com/kr/pty"
"github.com/op/go-logging"
)
const SocketAddress = "/tmp/oz-init-control"
const EnvPrefix = "INIT_ENV_"
type initState struct {
log *logging.Logger
profile *oz.Profile
config *oz.Config
launchEnv []string
uid int
gid int
user *user.User
@ -67,12 +69,12 @@ func parseArgs() *initState {
pname := getvar("INIT_PROFILE")
uidval := getvar("INIT_UID")
dispval := os.Getenv("INIT_DISPLAY")
stnip := os.Getenv("INIT_ADDR")
stnvhost := os.Getenv("INIT_VHOST")
stnvguest := os.Getenv("INIT_VGUEST")
stngateway := os.Getenv("INIT_GATEWAY")
var config *oz.Config
config, err := oz.LoadConfig(oz.DefaultConfigPath)
if err != nil {
@ -109,7 +111,7 @@ func parseArgs() *initState {
}
display = d
}
stn := new(network.SandboxNetwork)
if stnip != "" {
gateway, _, err := net.ParseCIDR(stngateway)
@ -117,29 +119,39 @@ func parseArgs() *initState {
log.Error("Unable to parse network configuration gateway (%s): %v", stngateway, err)
os.Exit(1)
}
stn.Ip = stnip
stn.VethHost = stnvhost
stn.Ip = stnip
stn.VethHost = stnvhost
stn.VethGuest = stnvguest
stn.Gateway = gateway
stn.Gateway = gateway
}
env := []string{}
for _, e := range os.Environ() {
if strings.HasPrefix(e, EnvPrefix) {
e = e[len(EnvPrefix):]
log.Debug("Adding (%s) to launch environment", e)
env = append(env, e)
}
}
return &initState{
log: log,
config: config,
profile: p,
uid: uid,
gid: gid,
user: u,
display: display,
fs: fs.NewFromProfile(p, u, config.SandboxPath, config.UseFullDev, log),
network: stn,
log: log,
config: config,
launchEnv: env,
profile: p,
uid: uid,
gid: gid,
user: u,
display: display,
fs: fs.NewFromProfile(p, u, config.SandboxPath, config.UseFullDev, log),
network: stn,
}
}
func (st *initState) runInit() {
st.log.Info("Starting oz-init for profile: %s", st.profile.Name)
if st.profile.Networking.Nettype != "host" {
err := network.NetSetup(st.network)
if err != nil {
@ -148,7 +160,7 @@ func (st *initState) runInit() {
}
}
network.NetPrint(st.log)
if syscall.Sethostname([]byte(st.profile.Name)) != nil {
st.log.Error("Failed to set hostname to (%s)", st.profile.Name)
}
@ -159,7 +171,7 @@ func (st *initState) runInit() {
os.Exit(1)
}
oz.ReapChildProcs(st.log, st.handleChildExit)
if st.profile.XServer.Enabled {
st.xpraReady.Add(1)
st.startXpraServer()
@ -235,7 +247,7 @@ func (st *initState) readXpraOutput(r io.ReadCloser) {
}
func (st *initState) launchApplication() {
cmd := exec.Command(st.profile.Path + ".unsafe")
cmd := exec.Command(st.profile.Path /*+ ".unsafe"*/)
stdout, err := cmd.StdoutPipe()
if err != nil {
st.log.Warning("Failed to create stdout pipe: %v", err)
@ -251,9 +263,9 @@ func (st *initState) launchApplication() {
Uid: uint32(st.uid),
Gid: uint32(st.gid),
}
cmd.Env = []string{
cmd.Env = append(st.launchEnv,
fmt.Sprintf("DISPLAY=:%d", st.display),
}
)
if err := cmd.Start(); err != nil {
st.log.Warning("Failed to start application (%s): %v", st.profile.Path, err)
return
@ -311,7 +323,7 @@ func (st *initState) handleRunShell(rs *RunShellMsg, msg *ipc.Message) error {
}
}
if st.profile.XServer.Enabled {
cmd.Env = append(cmd.Env, "DISPLAY=:" + strconv.Itoa(st.display))
cmd.Env = append(cmd.Env, "DISPLAY=:"+strconv.Itoa(st.display))
}
cmd.Env = append(cmd.Env, "PATH=/usr/bin:/bin")
cmd.Env = append(cmd.Env, fmt.Sprintf("PS1=[%s] $ ", st.profile.Name))

@ -71,10 +71,9 @@ func handleLaunch(c *cli.Context) {
fmt.Println("Argument needed to launch command")
os.Exit(1)
}
err := daemon.Launch(c.Args()[0])
err := daemon.Launch(c.Args()[0], os.Environ())
if err != nil {
fmt.Printf("launch command failed: %v\n", err)
}
}

Loading…
Cancel
Save