feat: headless mode
Some checks are pending
build / lint (push) Waiting to run
build / build (push) Blocked by required conditions
build / release (push) Blocked by required conditions

This commit is contained in:
Rob Watson 2025-04-30 22:46:27 +02:00
parent 750e9432be
commit 06a1501fbe
2 changed files with 28 additions and 19 deletions

View File

@ -21,12 +21,15 @@ import (
// App is an instance of the app. // App is an instance of the app.
type App struct { type App struct {
cfg config.Config cfg config.Config
configService *config.Service configService *config.Service
eventBus *event.Bus eventBus *event.Bus
dispatchC chan event.Command dispatchC chan event.Command
dockerClient container.DockerClient dockerClient container.DockerClient
screen *terminal.Screen // Screen may be nil. screen *terminal.Screen // Screen may be nil.
// TODO: startup check
// TODO: handle SIGINT
headless bool
clipboardAvailable bool clipboardAvailable bool
configFilePath string configFilePath string
buildInfo domain.BuildInfo buildInfo domain.BuildInfo
@ -39,6 +42,7 @@ type Params struct {
DockerClient container.DockerClient DockerClient container.DockerClient
ChanSize int ChanSize int
Screen *terminal.Screen // Screen may be nil. Screen *terminal.Screen // Screen may be nil.
Headless bool
ClipboardAvailable bool ClipboardAvailable bool
ConfigFilePath string ConfigFilePath string
BuildInfo domain.BuildInfo BuildInfo domain.BuildInfo
@ -57,6 +61,7 @@ func New(params Params) *App {
dispatchC: make(chan event.Command, cmp.Or(params.ChanSize, defaultChanSize)), dispatchC: make(chan event.Command, cmp.Or(params.ChanSize, defaultChanSize)),
dockerClient: params.DockerClient, dockerClient: params.DockerClient,
screen: params.Screen, screen: params.Screen,
headless: params.Headless,
clipboardAvailable: params.ClipboardAvailable, clipboardAvailable: params.ClipboardAvailable,
configFilePath: params.ConfigFilePath, configFilePath: params.ConfigFilePath,
buildInfo: params.BuildInfo, buildInfo: params.BuildInfo,
@ -75,19 +80,21 @@ func (a *App) Run(ctx context.Context) error {
return errors.New("config: either sources.mediaServer.rtmp.enabled or sources.mediaServer.rtmps.enabled must be set") return errors.New("config: either sources.mediaServer.rtmp.enabled or sources.mediaServer.rtmps.enabled must be set")
} }
ui, err := terminal.StartUI(ctx, terminal.StartParams{ if !a.headless {
EventBus: a.eventBus, ui, err := terminal.StartUI(ctx, terminal.StartParams{
Dispatcher: func(cmd event.Command) { a.dispatchC <- cmd }, EventBus: a.eventBus,
Screen: a.screen, Dispatcher: func(cmd event.Command) { a.dispatchC <- cmd },
ClipboardAvailable: a.clipboardAvailable, Screen: a.screen,
ConfigFilePath: a.configFilePath, ClipboardAvailable: a.clipboardAvailable,
BuildInfo: a.buildInfo, ConfigFilePath: a.configFilePath,
Logger: a.logger.With("component", "ui"), BuildInfo: a.buildInfo,
}) Logger: a.logger.With("component", "ui"),
if err != nil { })
return fmt.Errorf("start terminal user interface: %w", err) if err != nil {
return fmt.Errorf("start terminal user interface: %w", err)
}
defer ui.Close()
} }
defer ui.Close()
// emptyUI is a dummy function that sets the UI state to an empty state, and // emptyUI is a dummy function that sets the UI state to an empty state, and
// re-renders the screen. // re-renders the screen.

View File

@ -100,6 +100,7 @@ func run(ctx context.Context) error {
app := app.New(app.Params{ app := app.New(app.Params{
ConfigService: configService, ConfigService: configService,
DockerClient: dockerClient, DockerClient: dockerClient,
Headless: os.Getenv("OCTO_HEADLESS") != "",
ClipboardAvailable: clipboardAvailable, ClipboardAvailable: clipboardAvailable,
ConfigFilePath: configService.Path(), ConfigFilePath: configService.Path(),
BuildInfo: domain.BuildInfo{ BuildInfo: domain.BuildInfo{
@ -160,7 +161,8 @@ func printUsage() {
os.Stderr.WriteString(" help Print this help message\n") os.Stderr.WriteString(" help Print this help message\n")
os.Stderr.WriteString("\n") os.Stderr.WriteString("\n")
os.Stderr.WriteString("Additionally, Octoplex can be configured with the following environment variables:\n\n") os.Stderr.WriteString("Additionally, Octoplex can be configured with the following environment variables:\n\n")
os.Stderr.WriteString(" OCTO_DEBUG Enables debug logging if set\n") os.Stderr.WriteString(" OCTO_DEBUG Enables debug logging if set\n\n")
os.Stderr.WriteString(" OCTO_HEADLESS Enables headless mode if set (experimental)\n")
} }
// buildLogger builds the logger, which may be a no-op logger. // buildLogger builds the logger, which may be a no-op logger.