This commit is contained in:
Iwasaki Yudai 2017-02-26 07:37:07 +09:00
parent 54403dd678
commit a6133f34b7
54 changed files with 2140 additions and 1334 deletions

100
main.go
View file

@ -1,6 +1,7 @@
package main
import (
"context"
"fmt"
"os"
"os/signal"
@ -8,24 +9,25 @@ import (
"github.com/codegangsta/cli"
"github.com/yudai/gotty/app"
"github.com/yudai/gotty/backends/ptycommand"
"github.com/yudai/gotty/backend/localcommand"
"github.com/yudai/gotty/pkg/homedir"
"github.com/yudai/gotty/server"
"github.com/yudai/gotty/utils"
)
func main() {
cmd := cli.NewApp()
cmd.Name = "gotty"
cmd.Version = app.Version
cmd.Usage = "Share your terminal as a web application"
cmd.HideHelp = true
app := cli.NewApp()
app.Name = "gotty"
app.Version = Version
app.Usage = "Share your terminal as a web application"
app.HideHelp = true
cli.AppHelpTemplate = helpTemplate
appOptions := &app.Options{}
appOptions := &server.Options{}
if err := utils.ApplyDefaultValues(appOptions); err != nil {
exit(err, 1)
}
backendOptions := &ptycommand.Options{}
backendOptions := &localcommand.Options{}
if err := utils.ApplyDefaultValues(backendOptions); err != nil {
exit(err, 1)
}
@ -35,7 +37,7 @@ func main() {
exit(err, 3)
}
cmd.Flags = append(
app.Flags = append(
cliFlags,
cli.StringFlag{
Name: "config",
@ -45,7 +47,7 @@ func main() {
},
)
cmd.Action = func(c *cli.Context) {
app.Action = func(c *cli.Context) {
if len(c.Args()) == 0 {
msg := "Error: No command given."
cli.ShowAppHelp(c)
@ -53,7 +55,7 @@ func main() {
}
configFile := c.String("config")
_, err := os.Stat(utils.ExpandHomeDir(configFile))
_, err := os.Stat(homedir.Expand(configFile))
if configFile != "~/.gotty" || !os.IsNotExist(err) {
if err := utils.ApplyConfigFile(configFile, appOptions, backendOptions); err != nil {
exit(err, 2)
@ -65,27 +67,45 @@ func main() {
appOptions.EnableBasicAuth = c.IsSet("credential")
appOptions.EnableTLSClientAuth = c.IsSet("tls-ca-crt")
if err := app.CheckConfig(appOptions); err != nil {
err = appOptions.Validate()
if err != nil {
exit(err, 6)
}
manager, err := ptycommand.NewCommandClientContextManager(c.Args(), backendOptions)
if err != nil {
exit(err, 3)
}
app, err := app.New(manager, appOptions)
args := c.Args()
factory, err := localcommand.NewFactory(args[0], args[1:], backendOptions)
if err != nil {
exit(err, 3)
}
registerSignals(app)
err = app.Run()
if err != nil {
exit(err, 4)
hostname, _ := os.Hostname()
appOptions.TitleVariables = map[string]interface{}{
"command": args[0],
"argv": args[1:],
"hostname": hostname,
}
srv, err := server.New(factory, appOptions)
if err != nil {
exit(err, 3)
}
ctx, cancel := context.WithCancel(context.Background())
gCtx, gCancel := context.WithCancel(context.Background())
errs := make(chan error, 1)
go func() {
errs <- srv.Run(ctx, server.WithGracefullContext(gCtx))
}()
err = waitSignals(errs, cancel, gCancel)
if err != nil && err != context.Canceled {
fmt.Printf("Error: %s\n", err)
exit(err, 8)
}
}
cmd.Run(os.Args)
app.Run(os.Args)
}
func exit(err error, code int) {
@ -95,7 +115,7 @@ func exit(err error, code int) {
os.Exit(code)
}
func registerSignals(app *app.App) {
func waitSignals(errs chan error, cancel context.CancelFunc, gracefullCancel context.CancelFunc) error {
sigChan := make(chan os.Signal, 1)
signal.Notify(
sigChan,
@ -103,17 +123,25 @@ func registerSignals(app *app.App) {
syscall.SIGTERM,
)
go func() {
for {
s := <-sigChan
switch s {
case syscall.SIGINT, syscall.SIGTERM:
if app.Exit() {
fmt.Println("Send ^C to force exit.")
} else {
os.Exit(5)
}
select {
case err := <-errs:
return err
case s := <-sigChan:
switch s {
case syscall.SIGINT:
gracefullCancel()
fmt.Println("C-C to force close")
select {
case err := <-errs:
return err
case <-sigChan:
cancel()
return <-errs
}
default:
cancel()
return <-errs
}
}()
}
}