Beispiel #1
0
func getCmdWeb(s liblush.Session, idstr string) (liblush.Cmd, error) {
	id, _ := liblush.ParseCmdId(idstr)
	c := s.GetCommand(id)
	if c == nil {
		return nil, web.WebError{404, "no such command: " + idstr}
	}
	return c, nil
}
Beispiel #2
0
func getCmd(s *server, idstr string) (liblush.Cmd, error) {
	var err error
	id, _ := liblush.ParseCmdId(idstr)
	c := s.session.GetCommand(id)
	if c == nil {
		err = errors.New("no such command: " + idstr)
	}
	return c, err
}
Beispiel #3
0
// free resources associated with a command. eg:
//
//     release;3
//
// will generate a cmd_released;<id> event. eg:
//
//     cmd_released;3
//
// cannot be executed while command is running.
func wseventRelease(s *server, idstr string) error {
	id, _ := liblush.ParseCmdId(idstr)
	err := s.session.ReleaseCommand(id)
	if err != nil {
		return err
	}
	_, err = fmt.Fprintf(&s.ctrlclients, "cmd_released;%s", idstr)
	return err
}
Beispiel #4
0
func handleGetCmdJson(ctx *web.Context, idstr string) error {
	id, _ := liblush.ParseCmdId(idstr)
	s := ctx.User.(*server)
	c := s.session.GetCommand(id)
	if c == nil {
		return web.WebError{404, "no such command: " + idstr}
	}
	md, err := metacmd{c}.Metadata()
	if err != nil {
		return err
	}
	ctx.ContentType("json")
	// Don't hammer me, but don't cache for too long. This resource is not
	// intended for polling, anyway. This may seem race sensitive, but that's
	// because it is. Only matters in big, multi user setups with lots of
	// concurrent changes, which is totally not lush's current intended use
	// case. So a few race conditions here and there are no biggy (for now).
	ctx.Response.Header().Set("cache-control", "max-age=3")
	return json.NewEncoder(ctx).Encode(md)
}
Beispiel #5
0
func handlePostClose(ctx *web.Context, idstr string) error {
	if err := errorIfNotMaster(ctx); err != nil {
		return err
	}
	id, _ := liblush.ParseCmdId(idstr)
	s := ctx.User.(*server)
	c := s.session.GetCommand(id)
	if c == nil {
		return web.WebError{404, "no such command: " + idstr}
	}
	if ctx.Params["stream"] != "stdin" {
		return web.WebError{400, "must send to stdin"}
	}
	err := c.Stdin().Close()
	if err != nil {
		return err
	}
	redirect(ctx, cmdloc(c))
	return nil
}
Beispiel #6
0
func handleWsStream(ctx *web.Context, idstr, streamname string) error {
	id, _ := liblush.ParseCmdId(idstr)
	s := ctx.User.(*server)
	c := s.session.GetCommand(id)
	if c == nil {
		return web.WebError{404, "no such command: " + idstr}
	}
	var stream liblush.OutStream
	switch streamname {
	case "stdout":
		stream = c.Stdout()
	case "stderr":
		stream = c.Stderr()
	default:
		return web.WebError{400, "No such stream: " + streamname}
	}
	stream.Peeker().AddWriter(ctx.WebsockConn)
	buf := make([]byte, 1)
	ctx.WebsockConn.Read(buf)
	return nil
}
Beispiel #7
0
func handleGetCmdInfo(ctx *web.Context, idstr string) error {
	id, _ := liblush.ParseCmdId(idstr)
	s := ctx.User.(*server)
	c := s.session.GetCommand(id)
	if c == nil {
		return web.WebError{404, "no such command: " + idstr}
	}
	ctx.Header().Set("content-type", "application/json")
	enc := json.NewEncoder(ctx)
	var info = struct {
		Started, Exited *time.Time
		Error           string `json:",omitempty"`
	}{
		Started: c.Status().Started(),
		Exited:  c.Status().Exited(),
	}
	if cerr := c.Status().Err(); cerr != nil {
		info.Error = cerr.Error()
	}
	return enc.Encode(info)
}
Beispiel #8
0
func handleGetCmd(ctx *web.Context, idstr string) error {
	type cmdctx struct {
		Cmd          liblush.Cmd
		Stdout       string
		Stderr       string
		Connectables chan liblush.Cmd
	}
	id, _ := liblush.ParseCmdId(idstr)
	s := ctx.User.(*server)
	c := s.session.GetCommand(id)
	if c == nil {
		return web.WebError{404, "no such command: " + idstr}
	}
	stdout := make([]byte, 1000)
	stderr := make([]byte, 1000)
	n := c.Stdout().Scrollback().Last(stdout)
	stdout = stdout[:n]
	n = c.Stderr().Scrollback().Last(stderr)
	stderr = stderr[:n]
	ch := make(chan liblush.Cmd)
	go func() {
		for _, id := range s.session.GetCommandIds() {
			other := s.session.GetCommand(id)
			if c.Id() != other.Id() && other.Status().Started() == nil {
				ch <- other
			}
		}
		close(ch)
	}()
	tmplCtx := cmdctx{
		Cmd:          c,
		Stdout:       string(stdout),
		Stderr:       string(stderr),
		Connectables: ch,
	}
	err := s.tmplts.ExecuteTemplate(ctx, "cmd", tmplCtx)
	return err
}