From 8bd2a9450e62b3b5b7ed6293f8c1842f57df7bcc Mon Sep 17 00:00:00 2001 From: Ashok Siyani Date: Wed, 26 Mar 2025 14:55:00 +0000 Subject: [PATCH] simplify watch loop and initial steps By manually doing initial mirror we get more control over the sync process and clean up steps. Fresh repo fetch always takes longer then incremental fetches, so my doing initial mirror we can set higher timeout. As added benefit it can now supports one off sync without complicating sync loop. --- main.go | 39 +++++++++++++++++++++++++++++---------- 1 file changed, 29 insertions(+), 10 deletions(-) diff --git a/main.go b/main.go index f218b48..47d1f76 100644 --- a/main.go +++ b/main.go @@ -71,6 +71,7 @@ func usage() { fmt.Fprintf(os.Stderr, "\t-config value (default: '/etc/git-mirror/config.yaml') Absolute path to the config file. [$GIT_MIRROR_CONFIG]\n") fmt.Fprintf(os.Stderr, "\t-watch-config value (default: true) watch config for changes and reload when changes encountered. [$GIT_MIRROR_WATCH_CONFIG]\n") fmt.Fprintf(os.Stderr, "\t-http-bind-address value (default: ':9001') The address the web server binds to. [$GIT_MIRROR_HTTP_BIND]\n") + fmt.Fprintf(os.Stderr, "\t-one-time (default: 'false') Exit after first mirror. [$GIT_MIRROR_ONE_TIME]\n") os.Exit(2) } @@ -82,6 +83,7 @@ func main() { flagConfig := flag.String("config", envString("GIT_MIRROR_CONFIG", "/etc/git-mirror/config.yaml"), "Absolute path to the config file") flagWatchConfig := flag.Bool("watch-config", envBool("GIT_MIRROR_WATCH_CONFIG", true), "watch config for changes and reload when changes encountered") flagHttpBind := flag.String("http-bind-address", envString("GIT_MIRROR_HTTP_BIND", ":9001"), "The address the web server binds to") + flagOneTime := flag.Bool("one-time", envBool("GIT_MIRROR_ONE_TIME", false), "Exit after first mirror") flagVersion := flag.Bool("version", false, "git-mirror version") flag.Usage = usage @@ -122,26 +124,43 @@ func main() { mux.HandleFunc("/debug/pprof/trace", pprof.Trace) server.Handler = mux + conf, err := parseConfigFile(*flagConfig) + if err != nil { + logger.Error("unable to parse git-mirror config file", "err", err) + os.Exit(1) + } + + applyGitDefaults(conf) + // path to resolve git gitENV := []string{fmt.Sprintf("PATH=%s", os.Getenv("PATH"))} - // create empty repo pool which will be populated by watchConfig - repoPool, err := mirror.NewRepoPool(ctx, mirror.RepoPoolConfig{}, logger.With("logger", "git-mirror"), gitENV) + repoPool, err := mirror.NewRepoPool(ctx, *conf, logger.With("logger", "git-mirror"), gitENV) if err != nil { logger.Error("could not create git mirror pool", "err", err) os.Exit(1) } - firstRun := true - onConfigChange := func(config *mirror.RepoPoolConfig) bool { - ok := ensureConfig(repoPool, config) + // perform 1st mirror to ensure all repositories before starting controller + // initial mirror might take longer + timeout := 2 * conf.Defaults.MirrorTimeout + if err := repoPool.MirrorAll(ctx, timeout); err != nil { + logger.Error("could not perform initial repositories mirror", "err", err) + os.Exit(1) + } - if firstRun { - cleanupOrphanedRepos(config, repoPool) - firstRun = false - } + if *flagOneTime { + logger.Info("existing after first mirror") + os.Exit(0) + } - return ok + // start mirror Loop + repoPool.StartLoop() + + cleanupOrphanedRepos(conf, repoPool) + + onConfigChange := func(config *mirror.RepoPoolConfig) bool { + return ensureConfig(repoPool, config) } // Start watching the config file