package main import ( "context" "docker-updater/config" "docker-updater/contextutil" "docker-updater/docker/helper" "docker-updater/runtime" "flag" "log/slog" "os" "os/signal" ) const ( success int = 0 failure int = 1 usageError int = 2 ) func run(ctx context.Context, debug bool) int { var configPath string var verbose bool flag.StringVar(&configPath, "config", "./config.json", "Specify the configuration file path") flag.BoolVar(&verbose, "verbose", false, "Set the log as verbose") flag.Parse() ctx = contextutil.WithThreadName(ctx, "main") if verbose { slog.SetLogLoggerLevel(slog.LevelDebug) } config, err := config.Load(configPath) if err != nil { slog.Error("failed to load the configuration", "thread", "main", "err", err) return failure } if err := config.Validate(); err != nil { slog.Error("failed to validate the configuration", "thread", "main", "err", err) return failure } docker, err := helper.Open(config) if err != nil { slog.Error("unable to connect to the docker socket", "thread", "main", "err", err) return failure } defer docker.Close() if err := docker.StartWatcher(ctx, config.DaemonConfiguration.PullInterval); err != nil { slog.Error("unable to start the docker watcher", "thread", "main", "err", err) return failure } el, err := runtime.NewEventLoop(ctx, docker) if err != nil { slog.Error("failed to init the event loop", "thread", "main", "err", err) return failure } defer el.Close() go func() { interruptNum := 0 c := make(chan os.Signal, 10) signal.Notify(c) defer close(c) for sig := range c { switch sig { case os.Interrupt: { interruptNum++ slog.Info("the process received an interruption signal", "thread", "signal_watcher", "signal", sig.String()) el.Close() } case os.Kill: { interruptNum++ slog.Info("the process received a kill signal", "thread", "signal_watcher", "signal", sig.String()) el.Close() } } if interruptNum == 3 { slog.Info("received 3 times a stop signal, forcing the program to shut down", "thread", "signal_watch") os.Exit(failure) } } }() slog.Info("everything seems ok, starting the event loop", "thread", "main") el.Execute() slog.Info("Need to go, byyye 👋", "thread", "main") return success }