package player import ( "context" "crypto/tls" "fmt" "os" "forge.cadoles.com/arcad/arcast" "forge.cadoles.com/arcad/arcast/pkg/browser" "forge.cadoles.com/arcad/arcast/pkg/browser/dummy" "forge.cadoles.com/arcad/arcast/pkg/browser/lorca" "forge.cadoles.com/arcad/arcast/pkg/config" "forge.cadoles.com/arcad/arcast/pkg/server" "github.com/pkg/errors" "github.com/urfave/cli/v2" "gitlab.com/wpetit/goweb/logger" ) func Run() *cli.Command { defaults := lorca.NewOptions() return &cli.Command{ Name: "run", Flags: []cli.Flag{ &cli.StringFlag{ Name: "config", EnvVars: []string{"ARCAST_DESKTOP_CONFIG"}, Value: config.DefaultConfigFile(context.Background()), }, &cli.StringSliceFlag{ Name: "additional-chrome-arg", EnvVars: []string{"ARCAST_DESKTOP_ADDITIONAL_CHROME_ARGS"}, Value: cli.NewStringSlice("incognito"), }, &cli.StringFlag{ Name: "instance-id", EnvVars: []string{"ARCAST_DESKTOP_INSTANCE_ID"}, Value: "", }, &cli.StringFlag{ Name: "address", EnvVars: []string{"ARCAST_DESKTOP_ADDRESS"}, Value: ":", }, &cli.StringFlag{ Name: "https-address", EnvVars: []string{"ARCAST_DESKTOP_HTTPS_ADDRESS"}, Value: ":", }, &cli.IntFlag{ Name: "window-height", EnvVars: []string{"ARCAST_DESKTOP_WINDOW_HEIGHT"}, Value: defaults.Height, }, &cli.BoolFlag{ Name: "apps", EnvVars: []string{"ARCAST_DESKTOP_APPS"}, Value: false, }, &cli.IntFlag{ Name: "window-width", EnvVars: []string{"ARCAST_DESKTOP_WINDOW_WIDTH"}, Value: defaults.Width, }, &cli.StringSliceFlag{ Name: "allowed-origins", EnvVars: []string{"ARCAST_DESKTOP_ALLOWED_ORIGINS"}, Value: cli.NewStringSlice(), }, &cli.StringFlag{ Name: "custom-files-dir", EnvVars: []string{"ARCAST_DESKTOP_CUSTOM_FILES_DIR"}, Value: "", }, &cli.BoolFlag{ Name: "dummy-browser", EnvVars: []string{"ARCAST_DESKTOP_DUMMY_BROWSER"}, Value: false, }, }, Action: func(ctx *cli.Context) error { configFile := ctx.String("config") windowHeight := ctx.Int("window-height") windowWidth := ctx.Int("window-width") chromeArgs := addFlagsPrefix(ctx.StringSlice("additional-chrome-arg")...) dummyBrowser := ctx.Bool("dummy-browser") var browser browser.Browser if dummyBrowser { logger.Info(ctx.Context, "using dummy browser") browser = dummy.NewBrowser() } else { lorcaBrowser := lorca.NewBrowser( lorca.WithAdditionalChromeArgs(chromeArgs...), lorca.WithWindowSize(windowWidth, windowHeight), ) if err := lorcaBrowser.Start(); err != nil { return errors.Wrap(err, "could not start browser") } go func() { lorcaBrowser.Wait() logger.Warn(ctx.Context, "browser was closed") os.Exit(1) }() defer func() { logger.Info(ctx.Context, "stopping browser") if err := lorcaBrowser.Stop(); err != nil { logger.Error(ctx.Context, "could not stop browser", logger.CapturedE(errors.WithStack(err))) } }() browser = lorcaBrowser } conf := config.DefaultConfig() instanceID := ctx.String("instance-id") if instanceID != "" { conf.InstanceID = instanceID } if ctx.IsSet("apps") { conf.Apps.Enabled = ctx.Bool("apps") } if ctx.IsSet("address") { conf.HTTP.Address = ctx.String("address") } if ctx.IsSet("https-address") { conf.HTTPS.Address = ctx.String("tls-address") } if ctx.IsSet("allowed-origins") { conf.AllowedOrigins = ctx.StringSlice("allowed-origins") } if ctx.IsSet("custom-dir") { conf.HTTP.CustomDir = ctx.String("custom-dir") } logger.Info(ctx.Context, "loading or creating configuration file", logger.F("filename", configFile)) if err := config.LoadOrCreate(ctx.Context, configFile, conf, config.DefaultTransforms...); err != nil { logger.Error(ctx.Context, "could not load configuration file", logger.CapturedE(errors.WithStack(err))) } cert, err := tls.X509KeyPair(conf.HTTPS.Cert, conf.HTTPS.Key) if err != nil { return errors.Wrap(err, "could not parse tls cert/key pair") } server := server.New(browser, server.WithInstanceID(conf.InstanceID), server.WithAppsEnabled(conf.Apps.Enabled), server.WithDefaultApp(conf.Apps.DefaultApp), server.WithApps(arcast.DefaultApps...), server.WithAddress(conf.HTTP.Address), server.WithTLSAddress(conf.HTTPS.Address), server.WithTLSCertificate(&cert), server.WithAllowedOrigins(conf.AllowedOrigins...), server.WithUpperLayerDir(conf.HTTP.CustomDir), ) if err := server.Start(); err != nil { return errors.Wrap(err, "could not start server") } defer func() { if err := server.Stop(); err != nil { logger.Error(ctx.Context, "could not stop server", logger.CapturedE(errors.WithStack(err))) } }() if err := server.Wait(); err != nil { return errors.Wrap(err, "could not wait for server") } return nil }, } } func addFlagsPrefix(stripped ...string) []string { flags := make([]string, len(stripped)) for i, s := range stripped { flags[i] = fmt.Sprintf("--%s", s) } return flags }