diff --git a/oz-daemon/client.go b/oz-daemon/client.go index 0e8d98f..b0ed62c 100644 --- a/oz-daemon/client.go +++ b/oz-daemon/client.go @@ -53,7 +53,7 @@ func ListSandboxes() ([]SandboxInfo, error) { return body.Sandboxes, nil } -func Launch(arg string, args, env []string) error { +func Launch(arg string, args, env []string, noexec bool) error { idx, name, err := parseProfileArg(arg) if err != nil { return err @@ -61,11 +61,12 @@ func Launch(arg string, args, env []string) error { pwd, _ := os.Getwd() resp, err := clientSend(&LaunchMsg{ - Index: idx, - Name: name, - Pwd: pwd, - Args: args, - Env: env, + Index: idx, + Name: name, + Pwd: pwd, + Args: args, + Env: env, + Noexec: noexec, }) if err != nil { return err diff --git a/oz-daemon/daemon.go b/oz-daemon/daemon.go index d1e6d18..cad0cb8 100644 --- a/oz-daemon/daemon.go +++ b/oz-daemon/daemon.go @@ -133,12 +133,18 @@ func (d *daemonState) handleLaunch(msg *LaunchMsg, m *ipc.Message) error { return m.Respond(&ErrorMsg{err.Error()}) } if sbox := d.getRunningSandboxByName(p.Name); sbox != nil { - d.Info("Found running sandbox for `%s`, running program there", p.Name) - sbox.launchProgram(msg.Pwd, msg.Args, d.log) + if msg.Noexec { + errmsg := "Asked to launch program but sandbox is running and noexec is set!" + d.Notice(errmsg) + return m.Respond(&ErrorMsg{errmsg}) + } else { + d.Info("Found running sandbox for `%s`, running program there", p.Name) + sbox.launchProgram(msg.Pwd, msg.Args, d.log) + } } else { d.Debug("Would launch %s", p.Name) env := d.sanitizeEnvironment(p, msg.Env) - _, err = d.launch(p, msg.Pwd, msg.Args, env, m.Ucred.Uid, m.Ucred.Gid, d.log) + _, err = d.launch(p, msg.Pwd, msg.Args, env, msg.Noexec, 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()}) diff --git a/oz-daemon/launch.go b/oz-daemon/launch.go index cab7cd7..44cbbf3 100644 --- a/oz-daemon/launch.go +++ b/oz-daemon/launch.go @@ -74,7 +74,7 @@ func createInitCommand(initPath, name, chroot string, env []string, uid uint32, return cmd } -func (d *daemonState) launch(p *oz.Profile, pwd string, args, env []string, uid, gid uint32, log *logging.Logger) (*Sandbox, error) { +func (d *daemonState) launch(p *oz.Profile, pwd string, args, env []string, noexec bool, 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) @@ -145,11 +145,13 @@ func (d *daemonState) launch(p *oz.Profile, pwd string, args, env []string, uid, }() } - go func () { - sbox.ready.Wait() - go sbox.launchProgram(pwd, args, log) - }() - + if !noexec { + go func () { + sbox.ready.Wait() + go sbox.launchProgram(pwd, args, log) + }() + } + if sbox.profile.XServer.Enabled { go func() { sbox.ready.Wait() diff --git a/oz-daemon/protocol.go b/oz-daemon/protocol.go index 058edeb..0028642 100644 --- a/oz-daemon/protocol.go +++ b/oz-daemon/protocol.go @@ -31,11 +31,12 @@ type ListProfilesResp struct { } type LaunchMsg struct { - Index int "Launch" - Name string - Pwd string - Args []string - Env []string + Index int "Launch" + Name string + Pwd string + Args []string + Env []string + Noexec bool } type ListSandboxesMsg struct { diff --git a/oz/main.go b/oz/main.go index e28a794..30cb8b4 100644 --- a/oz/main.go +++ b/oz/main.go @@ -41,7 +41,7 @@ func runSandbox() { os.Exit(1) } - err := daemon.Launch(runBasename, os.Args[1:], os.Environ()) + err := daemon.Launch(runBasename, os.Args[1:], os.Environ(), false) if err != nil { fmt.Fprintf(os.Stderr, "launch command failed: %v.\n", err) os.Exit(1) @@ -65,6 +65,11 @@ func runApplication() { Name: "launch", Usage: "launch an application profile", Action: handleLaunch, + Flags: []cli.Flag{ + cli.BoolFlag{ + Name: "noexec, n", + }, + }, }, { Name: "list", @@ -109,11 +114,12 @@ func handleProfiles(c *cli.Context) { } func handleLaunch(c *cli.Context) { + noexec := c.Bool("noexec") if len(c.Args()) == 0 { fmt.Println("Argument needed to launch command") os.Exit(1) } - err := daemon.Launch(c.Args()[0], c.Args()[1:], os.Environ()) + err := daemon.Launch(c.Args()[0], c.Args()[1:], os.Environ(), noexec) if err != nil { fmt.Printf("launch command failed: %v\n", err) os.Exit(1)