@@ -9,13 +9,15 @@ import (
99 "syscall"
1010
1111 "github.com/alecthomas/kong"
12+ "github.com/warpdotdev/oz-agent-worker/internal/config"
1213 "github.com/warpdotdev/oz-agent-worker/internal/log"
1314 "github.com/warpdotdev/oz-agent-worker/internal/worker"
1415)
1516
1617var CLI struct {
18+ ConfigFile string `help:"Path to YAML config file" type:"path"`
1719 APIKey string `help:"API key for authentication" env:"WARP_API_KEY" required:""`
18- WorkerID string `help:"Worker host identifier" required:" "`
20+ WorkerID string `help:"Worker host identifier ( required via flag or config file) "`
1921 WebSocketURL string `default:"wss://oz.warp.dev/api/v1/selfhosted/worker/ws" hidden:""`
2022 ServerRootURL string `default:"https://app.warp.dev" hidden:""`
2123 LogLevel string `help:"Log level (debug, info, warn, error)" default:"info" enum:"debug,info,warn,error"`
@@ -34,29 +36,24 @@ func main() {
3436 kong.Vars {},
3537 )
3638
37- if strings .HasPrefix (CLI .WorkerID , "warp" ) {
38- log .Fatalf (ctx , "Invalid worker-id: values starting with 'warp' are reserved and cannot be used" )
39- }
40-
4139 log .SetLevel (CLI .LogLevel )
4240
43- envMap , err := parseEnvFlags (CLI .Env )
44- if err != nil {
45- log .Fatalf (ctx , "%v" , err )
41+ // Parse config file if provided.
42+ var fileConfig * config.FileConfig
43+ if CLI .ConfigFile != "" {
44+ var err error
45+ fileConfig , err = config .Load (CLI .ConfigFile )
46+ if err != nil {
47+ log .Fatalf (ctx , "%v" , err )
48+ }
4649 }
4750
48- config := worker.Config {
49- APIKey : CLI .APIKey ,
50- WorkerID : CLI .WorkerID ,
51- WebSocketURL : CLI .WebSocketURL ,
52- ServerRootURL : CLI .ServerRootURL ,
53- LogLevel : CLI .LogLevel ,
54- NoCleanup : CLI .NoCleanup ,
55- Volumes : CLI .Volumes ,
56- Env : envMap ,
51+ workerConfig , err := mergeConfig (fileConfig )
52+ if err != nil {
53+ log .Fatalf (ctx , "%v" , err )
5754 }
5855
59- w , err := worker .New (ctx , config )
56+ w , err := worker .New (ctx , workerConfig )
6057 if err != nil {
6158 log .Fatalf (ctx , "Failed to create worker: %v" , err )
6259 }
@@ -81,6 +78,61 @@ func main() {
8178 log .Infof (ctx , "Worker shutdown complete" )
8279}
8380
81+ // mergeConfig merges CLI flags with an optional config file.
82+ // Priority: CLI flags > config file > defaults.
83+ func mergeConfig (fileConfig * config.FileConfig ) (worker.Config , error ) {
84+ // Merge worker_id: CLI > config file.
85+ workerID := CLI .WorkerID
86+ if workerID == "" && fileConfig != nil {
87+ workerID = fileConfig .WorkerID
88+ }
89+ if workerID == "" {
90+ return worker.Config {}, fmt .Errorf ("worker-id is required (via --worker-id flag or config file)" )
91+ }
92+ if strings .HasPrefix (workerID , "warp" ) {
93+ return worker.Config {}, fmt .Errorf ("invalid worker-id: values starting with 'warp' are reserved and cannot be used" )
94+ }
95+
96+ // Merge cleanup: --no-cleanup flag > config file cleanup > default (cleanup=true).
97+ noCleanup := CLI .NoCleanup
98+ if ! noCleanup && fileConfig != nil && fileConfig .Cleanup != nil {
99+ noCleanup = ! * fileConfig .Cleanup
100+ }
101+
102+ // Parse CLI env flags.
103+ cliEnv , err := parseEnvFlags (CLI .Env )
104+ if err != nil {
105+ return worker.Config {}, err
106+ }
107+
108+ // Merge env: config file first, then CLI entries overlay (CLI wins on key conflict).
109+ mergedEnv := make (map [string ]string )
110+ if fileConfig != nil && fileConfig .Backend .Docker != nil {
111+ mergedEnv = config .ResolveEnv (fileConfig .Backend .Docker .Environment )
112+ }
113+ for k , v := range cliEnv {
114+ mergedEnv [k ] = v
115+ }
116+
117+ // Merge volumes: config file + CLI (concatenated).
118+ var volumes []string
119+ if fileConfig != nil && fileConfig .Backend .Docker != nil {
120+ volumes = append (volumes , fileConfig .Backend .Docker .Volumes ... )
121+ }
122+ volumes = append (volumes , CLI .Volumes ... )
123+
124+ return worker.Config {
125+ APIKey : CLI .APIKey ,
126+ WorkerID : workerID ,
127+ WebSocketURL : CLI .WebSocketURL ,
128+ ServerRootURL : CLI .ServerRootURL ,
129+ LogLevel : CLI .LogLevel ,
130+ NoCleanup : noCleanup ,
131+ Volumes : volumes ,
132+ Env : mergedEnv ,
133+ }, nil
134+ }
135+
84136// parseEnvFlags parses -e/--env flag values into a map.
85137// "KEY=VALUE" is used as-is; bare "KEY" inherits from the host environment.
86138// Empty keys and keys containing whitespace are rejected.
0 commit comments