checkpoint, switch name from sh2-runner to mshell

This commit is contained in:
sawka
2022-06-23 10:16:54 -07:00
parent 0b172cd689
commit 766d19f1bc
7 changed files with 152 additions and 95 deletions
+1 -1
View File
@@ -1,4 +1,4 @@
module github.com/scripthaus-dev/sh2-runner
module github.com/scripthaus-dev/mshell
go 1.17
+5 -5
View File
@@ -15,10 +15,10 @@ import (
"time"
"github.com/google/uuid"
"github.com/scripthaus-dev/sh2-runner/pkg/base"
"github.com/scripthaus-dev/sh2-runner/pkg/cmdtail"
"github.com/scripthaus-dev/sh2-runner/pkg/packet"
"github.com/scripthaus-dev/sh2-runner/pkg/shexec"
"github.com/scripthaus-dev/mshell/pkg/base"
"github.com/scripthaus-dev/mshell/pkg/cmdtail"
"github.com/scripthaus-dev/mshell/pkg/packet"
"github.com/scripthaus-dev/mshell/pkg/shexec"
)
// in single run mode, we don't want the runner to die from signals
@@ -155,7 +155,7 @@ func doMain() {
packet.SendErrorPacket(os.Stdout, fmt.Sprintf("cannot change directory to $HOME '%s': %v", homeDir, err))
return
}
err = base.EnsureRunnerPath()
err = base.EnsureMShellPath()
if err != nil {
packet.SendErrorPacket(os.Stdout, err.Error())
return
+12 -22
View File
@@ -11,11 +11,14 @@ import (
"fmt"
"io/fs"
"os"
"os/exec"
"path"
"path/filepath"
)
const ScRunnerVarName = "SCRIPTHAUS_RUNNER"
const DefaultMShellPath = "mshell"
const MShellPathVarName = "MSHELL_PATH"
const SSHCommandVarName = "SSH_COMMAND"
const ScHomeVarName = "SCRIPTHAUS_HOME"
const HomeVarName = "HOME"
const ScShell = "bash"
@@ -125,33 +128,20 @@ func EnsureSessionDir(sessionId string) (string, error) {
return sdir, nil
}
func GetScRunnerPath() (string, error) {
runnerPath := os.Getenv(ScRunnerVarName)
if runnerPath != "" {
return runnerPath, nil
func GetMShellPath() string {
msPath := os.Getenv(MShellPathVarName)
if msPath != "" {
return msPath
}
scHome, err := GetScHomeDir()
if err != nil {
return "", err
}
return path.Join(scHome, RunnerBaseName), nil
return DefaultMShellPath
}
func EnsureRunnerPath() error {
runnerPath, err := GetScRunnerPath()
func EnsureMShellPath() error {
msPath := GetMShellPath()
_, err := exec.LookPath(msPath)
if err != nil {
return err
}
info, err := os.Stat(runnerPath)
if err != nil {
if errors.Is(err, fs.ErrNotExist) {
return fmt.Errorf("cannot find scripthaus runner at path '%s'", runnerPath)
}
return fmt.Errorf("error stating scripthaus runner at path '%s'", runnerPath)
}
if info.Mode()&0100 == 0 {
return fmt.Errorf("scripthaus runner at path '%s' is not executable mode=%#o", runnerPath, info.Mode())
}
return nil
}
+2 -2
View File
@@ -16,8 +16,8 @@ import (
"github.com/fsnotify/fsnotify"
"github.com/google/uuid"
"github.com/scripthaus-dev/sh2-runner/pkg/base"
"github.com/scripthaus-dev/sh2-runner/pkg/packet"
"github.com/scripthaus-dev/mshell/pkg/base"
"github.com/scripthaus-dev/mshell/pkg/packet"
)
const MaxDataBytes = 4096
+34
View File
@@ -0,0 +1,34 @@
package packet
type CombinedPacket struct {
Type string `json:"type"`
Success bool `json:"success"`
Ts int64 `json:"ts"`
Id string `json:"id,omitempty"`
SessionId string `json:"sessionid"`
CmdId string `json:"cmdid"`
PtyPos int64 `json:"ptypos"`
PtyLen int64 `json:"ptylen"`
RunPos int64 `json:"runpos"`
RunLen int64 `json:"runlen"`
Error string `json:"error"`
NotFound bool `json:"notfound,omitempty"`
Tail bool `json:"tail,omitempty"`
Dir string `json:"dir"`
ChDir string `json:"chdir,omitempty"`
Data string `json:"data"`
PtyData string `json:"ptydata"`
RunData string `json:"rundata"`
Message string `json:"message"`
Command string `json:"command"`
ScHomeDir string `json:"schomedir"`
HomeDir string `json:"homedir"`
Env []string `json:"env"`
ExitCode int `json:"exitcode"`
RunnerPid int `json:"runnerpid"`
}
+84 -48
View File
@@ -18,22 +18,29 @@ import (
"sync"
)
const RunPacketStr = "run"
const PingPacketStr = "ping"
const DonePacketStr = "done"
const ErrorPacketStr = "error"
const MessagePacketStr = "message"
const CmdStartPacketStr = "cmdstart"
const CmdDonePacketStr = "cmddone"
const ListCmdPacketStr = "lscmd"
const GetCmdPacketStr = "getcmd"
const UntailCmdPacketStr = "untailcmd"
const RunnerInitPacketStr = "runnerinit"
const CdPacketStr = "cd"
const CdResponseStr = "cdresp"
const CmdDataPacketStr = "cmddata"
const RawPacketStr = "raw"
const InputPacketStr = "input"
// remote: runnerinit, run, ping, data, cmdstart, cmddone
// remote(detached): runnerinit, run, cmdstart
// server: runnerinit, run, ping, cmdstart, cmddone, cd, resp, getcmd, untailcmd, cmddata, input, data, [comp]
// all: error, message
const (
RunPacketStr = "run"
PingPacketStr = "ping"
RunnerInitPacketStr = "runnerinit"
DataPacketStr = "data"
CmdStartPacketStr = "cmdstart"
CmdDonePacketStr = "cmddone"
ResponsePacketStr = "resp"
DonePacketStr = "done"
ErrorPacketStr = "error"
MessagePacketStr = "message"
GetCmdPacketStr = "getcmd"
UntailCmdPacketStr = "untailcmd"
CdPacketStr = "cd"
CmdDataPacketStr = "cmddata"
RawPacketStr = "raw"
InputPacketStr = "input"
)
var TypeStrToFactory map[string]reflect.Type
@@ -41,20 +48,20 @@ func init() {
TypeStrToFactory = make(map[string]reflect.Type)
TypeStrToFactory[RunPacketStr] = reflect.TypeOf(RunPacketType{})
TypeStrToFactory[PingPacketStr] = reflect.TypeOf(PingPacketType{})
TypeStrToFactory[ResponsePacketStr] = reflect.TypeOf(ResponsePacketType{})
TypeStrToFactory[DonePacketStr] = reflect.TypeOf(DonePacketType{})
TypeStrToFactory[ErrorPacketStr] = reflect.TypeOf(ErrorPacketType{})
TypeStrToFactory[MessagePacketStr] = reflect.TypeOf(MessagePacketType{})
TypeStrToFactory[CmdStartPacketStr] = reflect.TypeOf(CmdStartPacketType{})
TypeStrToFactory[CmdDonePacketStr] = reflect.TypeOf(CmdDonePacketType{})
TypeStrToFactory[ListCmdPacketStr] = reflect.TypeOf(ListCmdPacketType{})
TypeStrToFactory[GetCmdPacketStr] = reflect.TypeOf(GetCmdPacketType{})
TypeStrToFactory[UntailCmdPacketStr] = reflect.TypeOf(UntailCmdPacketType{})
TypeStrToFactory[RunnerInitPacketStr] = reflect.TypeOf(RunnerInitPacketType{})
TypeStrToFactory[CdPacketStr] = reflect.TypeOf(CdPacketType{})
TypeStrToFactory[CdResponseStr] = reflect.TypeOf(CdResponseType{})
TypeStrToFactory[CmdDataPacketStr] = reflect.TypeOf(CmdDataPacketType{})
TypeStrToFactory[RawPacketStr] = reflect.TypeOf(RawPacketType{})
TypeStrToFactory[InputPacketStr] = reflect.TypeOf(InputPacketType{})
TypeStrToFactory[DataPacketStr] = reflect.TypeOf(DataPacketType{})
}
func MakePacket(packetType string) (PacketType, error) {
@@ -103,6 +110,22 @@ func MakePingPacket() *PingPacketType {
return &PingPacketType{Type: PingPacketStr}
}
type DataPacketType struct {
Type string `json:"type"`
SessionId string `json:"sessionid"`
CmdId string `json:"cmdid"`
FdNum int `json:"fdnum"`
Data string `json:"data"`
}
func (*DataPacketType) GetType() string {
return DataPacketStr
}
func MakeDataPacket(fdNum int, data string) *DataPacketType {
return &DataPacketType{Type: DataPacketStr, FdNum: fdNum, Data: data}
}
// InputData gets written to PTY directly
// SigNum gets sent to process via a signal
// WinSize, if set, will run TIOCSWINSZ to set size, and then send SIGWINCH
@@ -157,19 +180,6 @@ func MakeGetCmdPacket() *GetCmdPacketType {
return &GetCmdPacketType{Type: GetCmdPacketStr}
}
type ListCmdPacketType struct {
Type string `json:"type"`
SessionId string `json:"sessionid"`
}
func (*ListCmdPacketType) GetType() string {
return ListCmdPacketStr
}
func MakeListCmdPacket(sessionId string) *ListCmdPacketType {
return &ListCmdPacketType{Type: ListCmdPacketStr, SessionId: sessionId}
}
type CdPacketType struct {
Type string `json:"type"`
PacketId string `json:"packetid"`
@@ -180,23 +190,32 @@ func (*CdPacketType) GetType() string {
return CdPacketStr
}
func (p *CdPacketType) GetPacketId() string {
return p.PacketId
}
func MakeCdPacket() *CdPacketType {
return &CdPacketType{Type: CdPacketStr}
}
type CdResponseType struct {
Type string `json:"type"`
PacketId string `json:"packetid"`
Success bool `json:"success"`
Error string `json:"error"`
type ResponsePacketType struct {
Type string `json:"type"`
PacketId string `json:"packetid"`
Success bool `json:"success"`
Error string `json:"error"`
Data interface{} `json:"data"`
}
func (*CdResponseType) GetType() string {
return CdResponseStr
func (*ResponsePacketType) GetType() string {
return ResponsePacketStr
}
func MakeCdResponse() *CdResponseType {
return &CdResponseType{Type: CdResponseStr}
func (p *ResponsePacketType) GetPacketId() string {
return p.PacketId
}
func MakeResponsePacket(packetId string) *ResponsePacketType {
return &ResponsePacketType{Type: ResponsePacketStr, PacketId: packetId}
}
type RawPacketType struct {
@@ -232,10 +251,11 @@ func FmtMessagePacket(fmtStr string, args ...interface{}) *MessagePacketType {
type RunnerInitPacketType struct {
Type string `json:"type"`
ScHomeDir string `json:"schomedir"`
HomeDir string `json:"homedir"`
Env []string `json:"env"`
User string `json:"user"`
Version string `json:"version"`
ScHomeDir string `json:"schomedir,omitempty"`
HomeDir string `json:"homedir,omitempty"`
Env []string `json:"env,omitempty"`
User string `json:"user,omitempty"`
}
func (*RunnerInitPacketType) GetType() string {
@@ -290,15 +310,26 @@ func MakeCmdStartPacket() *CmdStartPacketType {
return &CmdStartPacketType{Type: CmdStartPacketStr}
}
type TermSize struct {
Rows int `json:"rows"`
Cols int `json:"cols"`
}
type RemoteFd struct {
FdNum int `json:"fdnum"`
Read bool `json:"read"`
Write bool `json:"write"`
}
type RunPacketType struct {
Type string `json:"type"`
SessionId string `json:"sessionid"`
CmdId string `json:"cmdid"`
ChDir string `json:"chdir,omitempty"`
Env map[string]string `json:"env,omitempty"`
Command string `json:"command"`
Rows int `json:"rows"`
Cols int `json:'cols"`
Cwd string `json:"cwd,omitempty"`
Env map[string]string `json:"env,omitempty"`
TermSize TermSize `json:"termsize"`
Fds []RemoteFd `json:"fds"`
}
func (*RunPacketType) GetType() string {
@@ -335,6 +366,11 @@ type PacketType interface {
GetType() string
}
type RpcPacketType interface {
GetType() string
GetPacketId() string
}
func ParseJsonPacket(jsonBuf []byte) (PacketType, error) {
var bareCmd BarePacketType
err := json.Unmarshal(jsonBuf, &bareCmd)
+14 -17
View File
@@ -17,8 +17,8 @@ import (
"github.com/creack/pty"
"github.com/google/uuid"
"github.com/scripthaus-dev/sh2-runner/pkg/base"
"github.com/scripthaus-dev/sh2-runner/pkg/packet"
"github.com/scripthaus-dev/mshell/pkg/base"
"github.com/scripthaus-dev/mshell/pkg/packet"
)
const DefaultRows = 25
@@ -79,8 +79,8 @@ func UpdateCmdEnv(cmd *exec.Cmd, envVars map[string]string) {
func MakeExecCmd(pk *packet.RunPacketType, cmdTty *os.File) *exec.Cmd {
ecmd := exec.Command("bash", "-c", pk.Command)
UpdateCmdEnv(ecmd, pk.Env)
if pk.ChDir != "" {
ecmd.Dir = pk.ChDir
if pk.Cwd != "" {
ecmd.Dir = pk.Cwd
}
ecmd.Stdin = cmdTty
ecmd.Stdout = cmdTty
@@ -93,11 +93,8 @@ func MakeExecCmd(pk *packet.RunPacketType, cmdTty *os.File) *exec.Cmd {
}
func MakeRunnerExec(cmdId string) (*exec.Cmd, error) {
runnerPath, err := base.GetScRunnerPath()
if err != nil {
return nil, err
}
ecmd := exec.Command(runnerPath, cmdId)
msPath := base.GetMShellPath()
ecmd := exec.Command(msPath, cmdId)
return ecmd, nil
}
@@ -141,13 +138,13 @@ func ValidateRunPacket(pk *packet.RunPacketType) error {
if err != nil {
return fmt.Errorf("invalid cmdid '%s' for command", pk.CmdId)
}
if pk.ChDir != "" {
dirInfo, err := os.Stat(pk.ChDir)
if pk.Cwd != "" {
dirInfo, err := os.Stat(pk.Cwd)
if err != nil {
return fmt.Errorf("invalid cwd '%s' for command: %v", pk.ChDir, err)
return fmt.Errorf("invalid cwd '%s' for command: %v", pk.Cwd, err)
}
if !dirInfo.IsDir() {
return fmt.Errorf("invalid cwd '%s' for command, not a directory", pk.ChDir)
return fmt.Errorf("invalid cwd '%s' for command, not a directory", pk.Cwd)
}
}
return nil
@@ -156,11 +153,11 @@ func ValidateRunPacket(pk *packet.RunPacketType) error {
func GetWinsize(p *packet.RunPacketType) *pty.Winsize {
rows := DefaultRows
cols := DefaultCols
if p.Rows > 0 && p.Rows <= MaxRows {
rows = p.Rows
if p.TermSize.Rows > 0 && p.TermSize.Rows <= MaxRows {
rows = p.TermSize.Rows
}
if p.Cols > 0 && p.Cols <= MaxCols {
cols = p.Cols
if p.TermSize.Cols > 0 && p.TermSize.Cols <= MaxCols {
cols = p.TermSize.Cols
}
return &pty.Winsize{Rows: uint16(rows), Cols: uint16(cols)}
}