Add an option to run headless (no interactive input)

Allow `tty-share` to run without having an interactive input terminal.
pull/62/head
Vasile Popescu 2 years ago committed by Elis Popescu
parent b4b9c20bdb
commit aca5802379

@ -75,6 +75,9 @@ Flags:
publicSession := flag.Bool("public", false, "Create a public session") publicSession := flag.Bool("public", false, "Create a public session")
noTLS := flag.Bool("no-tls", false, "Don't use TLS to connect to the tty-proxy server. Useful for local debugging") noTLS := flag.Bool("no-tls", false, "Don't use TLS to connect to the tty-proxy server. Useful for local debugging")
noWaitEnter := flag.Bool("no-wait", false, "Don't wait for the Enter press before starting the session") noWaitEnter := flag.Bool("no-wait", false, "Don't wait for the Enter press before starting the session")
headless := flag.Bool("headless", false, "Don't expect an interactive terminal at stdin")
headlessCols := flag.Int("headless-cols", 80, "Number of cols for the allocated pty when running headless")
headlessRows := flag.Int("headless-rows", 25, "Number of rows for the allocated pty when running headless")
detachKeys := flag.String("detach-keys", "ctrl-o,ctrl-c", "Sequence of keys to press for closing the connection. Supported: https://godoc.org/github.com/moby/term#pkg-variables.") detachKeys := flag.String("detach-keys", "ctrl-o,ctrl-c", "Sequence of keys to press for closing the connection. Supported: https://godoc.org/github.com/moby/term#pkg-variables.")
verbose := flag.Bool("verbose", false, "Verbose logging") verbose := flag.Bool("verbose", false, "Verbose logging")
flag.Usage = func() { flag.Usage = func() {
@ -121,7 +124,7 @@ Flags:
} }
// tty-share works as a server, from here on // tty-share works as a server, from here on
if !isStdinTerminal() { if !isStdinTerminal() && !*headless {
fmt.Printf("Input not a tty\n") fmt.Printf("Input not a tty\n")
os.Exit(1) os.Exit(1)
} }
@ -153,7 +156,7 @@ Flags:
) )
} }
ptyMaster := ptyMasterNew() ptyMaster := ptyMasterNew(*headless, *headlessCols, *headlessRows)
err := ptyMaster.Start(*commandName, strings.Fields(*commandArgs), envVars) err := ptyMaster.Start(*commandName, strings.Fields(*commandArgs), envVars)
if err != nil { if err != nil {
log.Errorf("Cannot start the %s command: %s", *commandName, err.Error()) log.Errorf("Cannot start the %s command: %s", *commandName, err.Error())
@ -168,7 +171,7 @@ Flags:
fmt.Printf("local session: http://%s/s/local/\n", *listenAddress) fmt.Printf("local session: http://%s/s/local/\n", *listenAddress)
if !*noWaitEnter { if !*noWaitEnter && !*headless {
fmt.Printf("Press Enter to continue!\n") fmt.Printf("Press Enter to continue!\n")
bufio.NewReader(os.Stdin).ReadString('\n') bufio.NewReader(os.Stdin).ReadString('\n')
} }
@ -195,8 +198,11 @@ Flags:
server.WindowSize(cols, rows) server.WindowSize(cols, rows)
}) })
mw := io.MultiWriter(os.Stdout, server) var mw io.Writer
mw = server
if !*headless {
mw = io.MultiWriter(os.Stdout, server)
}
go func() { go func() {
err := server.Run() err := server.Run()
@ -213,12 +219,14 @@ Flags:
} }
}() }()
go func() { if !*headless {
_, err := io.Copy(ptyMaster, os.Stdin) go func() {
if err != nil { _, err := io.Copy(ptyMaster, os.Stdin)
stopPtyAndRestore() if err != nil {
} stopPtyAndRestore()
}() }
}()
}
ptyMaster.Wait() ptyMaster.Wait()
fmt.Printf("tty-share finished\n\n\r") fmt.Printf("tty-share finished\n\n\r")

@ -20,10 +20,13 @@ type ptyMaster struct {
ptyFile *os.File ptyFile *os.File
command *exec.Cmd command *exec.Cmd
terminalInitState *terminal.State terminalInitState *terminal.State
headless bool
headlessCols int
headlessRows int
} }
func ptyMasterNew() *ptyMaster { func ptyMasterNew(headless bool, headlessCols, headlessRows int) *ptyMaster {
return &ptyMaster{} return &ptyMaster{headless: headless, headlessCols: headlessCols, headlessRows: headlessRows}
} }
func isStdinTerminal() bool { func isStdinTerminal() bool {
@ -40,12 +43,21 @@ func (pty *ptyMaster) Start(command string, args []string, envVars []string) (er
} }
// Set the initial window size // Set the initial window size
cols, rows, err := terminal.GetSize(0) cols, rows := pty.headlessCols, pty.headlessRows
if !pty.headless {
cols, rows, err = terminal.GetSize(0)
}
pty.SetWinSize(rows, cols) pty.SetWinSize(rows, cols)
return return
} }
func (pty *ptyMaster) MakeRaw() (err error) { func (pty *ptyMaster) MakeRaw() (err error) {
// don't do anything if running headless
if pty.headless {
return nil
}
// Save the initial state of the terminal, before making it RAW. Note that this terminal is the // Save the initial state of the terminal, before making it RAW. Note that this terminal is the
// terminal under which the tty-share command has been started, and it's identified via the // terminal under which the tty-share command has been started, and it's identified via the
@ -59,20 +71,25 @@ func (pty *ptyMaster) MakeRaw() (err error) {
} }
func (pty *ptyMaster) SetWinChangeCB(winChangedCB onWindowChangedCB) { func (pty *ptyMaster) SetWinChangeCB(winChangedCB onWindowChangedCB) {
// Start listening for window changes // Start listening for window changes if not running headless
go onWindowChanges(func(cols, rows int) { if !pty.headless {
// TODO:policy: should the server decide here if we care about the size and set it go onWindowChanges(func(cols, rows int) {
// right here? // TODO:policy: should the server decide here if we care about the size and set it
pty.SetWinSize(rows, cols) // right here?
pty.SetWinSize(rows, cols)
// Notify the ptyMaster user of the window changes, to be sent to the remote side
winChangedCB(cols, rows) // Notify the ptyMaster user of the window changes, to be sent to the remote side
}) winChangedCB(cols, rows)
})
}
} }
func (pty *ptyMaster) GetWinSize() (int, int, error) { func (pty *ptyMaster) GetWinSize() (int, int, error) {
cols, rows, err := terminal.GetSize(0) if pty.headless {
return cols, rows, err return pty.headlessCols, pty.headlessRows, nil
} else {
return terminal.GetSize(0)
}
} }
func (pty *ptyMaster) Write(b []byte) (int, error) { func (pty *ptyMaster) Write(b []byte) (int, error) {
@ -110,7 +127,9 @@ func (pty *ptyMaster) Wait() (err error) {
} }
func (pty *ptyMaster) Restore() { func (pty *ptyMaster) Restore() {
terminal.Restore(0, pty.terminalInitState) if !pty.headless {
terminal.Restore(0, pty.terminalInitState)
}
return return
} }

Loading…
Cancel
Save