now you can kill sandboxes

master
brl 10 years ago
parent 1a6d5ff18d
commit 2b2de2fa31

@ -98,6 +98,21 @@ func Clean(arg string) error {
}
}
func KillSandbox(id int) error {
resp, err := clientSend(&KillSandboxMsg{Id: id})
if err != nil {
return err
}
switch body := resp.Body.(type) {
case *ErrorMsg:
return errors.New(body.Msg)
case *OkMsg:
return nil
default:
return fmt.Errorf("Unexpected message received %+v", body)
}
}
func parseProfileArg(arg string) (int, string, error) {
if len(arg) == 0 {
return 0, "", errors.New("profile argument needed")

@ -11,6 +11,7 @@ import (
"github.com/subgraph/oz/network"
"github.com/op/go-logging"
"os"
)
type daemonState struct {
@ -35,6 +36,7 @@ func Main() {
d.handleLaunch,
d.handleListSandboxes,
d.handleClean,
d.handleKillSandbox,
d.handleLogs,
)
if err != nil {
@ -133,6 +135,26 @@ func (d *daemonState) handleLaunch(msg *LaunchMsg, m *ipc.Message) error {
return m.Respond(&OkMsg{})
}
func (d *daemonState) handleKillSandbox(msg *KillSandboxMsg, m *ipc.Message) error {
sbox := d.sandboxById(msg.Id)
if sbox == nil {
return m.Respond(&ErrorMsg{fmt.Sprintf("no sandbox found with id = %d", msg.Id)})
}
if err := sbox.init.Process.Signal(os.Interrupt); err != nil {
return m.Respond(&ErrorMsg{fmt.Sprintf("failed to send interrupt signal: %v", err)})
}
return m.Respond(&OkMsg{})
}
func (d *daemonState) sandboxById(id int) *Sandbox {
for _, sb := range d.sandboxes {
if sb.id == id {
return sb
}
}
return nil
}
func (d *daemonState) getProfileByIdxOrName(index int, name string) (*oz.Profile, error) {
if len(name) == 0 {
if index < 1 || index > len(d.profiles) {

@ -50,6 +50,10 @@ type ListSandboxesResp struct {
Sandboxes []SandboxInfo "ListSandboxesResp"
}
type KillSandboxMsg struct {
Id int "KillSandbox"
}
type CleanMsg struct {
Index int "Clean"
Name string
@ -73,6 +77,7 @@ var messageFactory = ipc.NewMsgFactory(
new(LaunchMsg),
new(ListSandboxesMsg),
new(ListSandboxesResp),
new(KillSandboxMsg),
new(CleanMsg),
new(LogsMsg),
new(LogData),

@ -21,6 +21,7 @@ import (
"github.com/kr/pty"
"github.com/op/go-logging"
"os/signal"
)
const SocketAddress = "/tmp/oz-init-control"
@ -151,6 +152,8 @@ func parseArgs() *initState {
func (st *initState) runInit() {
st.log.Info("Starting oz-init for profile: %s", st.profile.Name)
sigs := make(chan os.Signal)
signal.Notify(sigs, syscall.SIGTERM, os.Interrupt)
if st.profile.Networking.Nettype != "host" {
err := network.NetSetup(st.network)
@ -192,6 +195,8 @@ func (st *initState) runInit() {
}
os.Stderr.WriteString("OK\n")
go st.processSignals(sigs, s)
if err := s.Run(); err != nil {
st.log.Warning("MsgServer.Run() return err: %v", err)
}
@ -247,7 +252,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)
stdout, err := cmd.StdoutPipe()
if err != nil {
st.log.Warning("Failed to create stdout pipe: %v", err)
@ -361,3 +366,11 @@ func ptyStart(c *exec.Cmd) (ptty *os.File, err error) {
func (is *initState) handleChildExit(pid int, wstatus syscall.WaitStatus) {
is.log.Debug("Child process pid=%d exited with status %d", pid, wstatus.ExitStatus())
}
func (st *initState) processSignals(c <-chan os.Signal, s *ipc.MsgServer) {
for {
sig := <-c
st.log.Info("Recieved signal (%v)", sig)
s.Close()
}
}

@ -42,6 +42,10 @@ func main() {
Name: "clean",
Action: handleClean,
},
{
Name: "kill",
Action: handleKill,
},
{
Name: "logs",
Action: handleLogs,
@ -153,6 +157,21 @@ func handleClean(c *cli.Context) {
}
}
func handleKill(c *cli.Context) {
if len(c.Args()) == 0 {
fmt.Println("Need a sandbox id to kill\n")
os.Exit(1)
}
id, err := strconv.Atoi(c.Args()[0])
if err != nil {
fmt.Printf("Could not parse id value %s\n", c.Args()[0])
os.Exit(1)
}
if err := daemon.KillSandbox(id); err != nil {
fmt.Println("Kill command failed:", err)
}
}
func handleLogs(c *cli.Context) {
follow := c.Bool("f")
ch, err := daemon.Logs(0, follow)

Loading…
Cancel
Save