e2e79feb09b7cb87dc7145989de247b9d6946055

Author
John Olheiser <john.olheiser@gmail.com>
Committer
GitHub <noreply@github.com>
Date

Message

feat: job config (#402)

* feat: job config

Signed-off-by: jolheiser <john.olheiser@gmail.com>

* docs: add new config to readme

Signed-off-by: jolheiser <john.olheiser@gmail.com>

* style: appease linter

Signed-off-by: jolheiser <john.olheiser@gmail.com>

* review(aymanbagabas): add jobs to default config file template

Signed-off-by: jolheiser <john.olheiser@gmail.com>

---------

Signed-off-by: jolheiser <john.olheiser@gmail.com>

Diff

  1diff --git a/README.md b/README.md
  2index 89f2986d237fb5a6d4b8746608d529578e285656..a8544f051a1a2e6bb4c533be05263eda074cb2f0 100644
  3--- a/README.md
  4+++ b/README.md
  5@@ -210,6 +210,10 @@ lfs:
  6   # Enable Git SSH transfer.
  7   ssh_enabled: true
  8 
  9+# Cron job configuration
 10+jobs:
 11+  mirror_pull: "@every 10m"
 12+
 13 # The stats server configuration.
 14 stats:
 15   # The address on which the stats server will listen.
 16diff --git a/server/config/config.go b/server/config/config.go
 17index fa5e2de8ec8a2d62691a0aab7ecc76031acba694..4707cc452befbbb27a28e92485e3e03a6ba49924 100644
 18--- a/server/config/config.go
 19+++ b/server/config/config.go
 20@@ -108,6 +108,11 @@ type LFSConfig struct {
 21 	SSHEnabled bool `env:"SSH_ENABLED" yaml:"ssh_enabled"`
 22 }
 23 
 24+// JobsConfig is the configuration for cron jobs.
 25+type JobsConfig struct {
 26+	MirrorPull string `env:"MIRROR_PULL" yaml:"mirror_pull"`
 27+}
 28+
 29 // Config is the configuration for Soft Serve.
 30 type Config struct {
 31 	// Name is the name of the server.
 32@@ -134,6 +139,9 @@ type Config struct {
 33 	// LFS is the configuration for Git LFS.
 34 	LFS LFSConfig `envPrefix:"LFS_" yaml:"lfs"`
 35 
 36+	// Jobs is the configuration for cron jobs
 37+	Jobs JobsConfig `envPrefix:"JOBS_" yaml:"jobs"`
 38+
 39 	// InitialAdminKeys is a list of public keys that will be added to the list of admins.
 40 	InitialAdminKeys []string `env:"INITIAL_ADMIN_KEYS" envSeparator:"\n" yaml:"initial_admin_keys"`
 41 
 42diff --git a/server/config/file.go b/server/config/file.go
 43index 27a3dcdf1f43b097956a79c06fc2db9f3d167fc9..4bb0302db0f76b5197b6528345c254abc427703c 100644
 44--- a/server/config/file.go
 45+++ b/server/config/file.go
 46@@ -102,6 +102,10 @@ lfs:
 47   # Enable Git SSH transfer.
 48   ssh_enabled: {{ .LFS.SSHEnabled }}
 49 
 50+# Cron job configuration
 51+jobs:
 52+  mirror_pull: "{{ .Jobs.MirrorPull }}"
 53+
 54 # Additional admin keys.
 55 #initial_admin_keys:
 56 #  - "ssh-rsa AAAAB3NzaC1yc2..."
 57diff --git a/server/jobs/jobs.go b/server/jobs/jobs.go
 58index ba39af85c6ae9e632d64d9512f96a9ddccbf27b8..505863ea03647e3bdc020e62f6584d1a5052c874 100644
 59--- a/server/jobs/jobs.go
 60+++ b/server/jobs/jobs.go
 61@@ -7,9 +7,14 @@ import (
 62 
 63 // Job is a job that can be registered with the scheduler.
 64 type Job struct {
 65-	ID   int
 66-	Spec string
 67-	Func func(context.Context) func()
 68+	ID     int
 69+	Runner Runner
 70+}
 71+
 72+// Runner is a job runner.
 73+type Runner interface {
 74+	Spec(context.Context) string
 75+	Func(context.Context) func()
 76 }
 77 
 78 var (
 79@@ -18,10 +23,10 @@ var (
 80 )
 81 
 82 // Register registers a job.
 83-func Register(name, spec string, fn func(context.Context) func()) {
 84+func Register(name string, runner Runner) {
 85 	mtx.Lock()
 86 	defer mtx.Unlock()
 87-	jobs[name] = &Job{Spec: spec, Func: fn}
 88+	jobs[name] = &Job{Runner: runner}
 89 }
 90 
 91 // List returns a map of registered jobs.
 92diff --git a/server/jobs/mirror.go b/server/jobs/mirror.go
 93index 8b14d2511c810c7bafde2922ba0e1881ba28a2de..4a8f080530b148dd2f75c6b7d99b522eea0b05e7 100644
 94--- a/server/jobs/mirror.go
 95+++ b/server/jobs/mirror.go
 96@@ -17,11 +17,22 @@ import (
 97 )
 98 
 99 func init() {
100-	Register("mirror-pull", "@every 10m", mirrorPull)
101+	Register("mirror-pull", mirrorPull{})
102 }
103 
104-// mirrorPull runs the (pull) mirror job task.
105-func mirrorPull(ctx context.Context) func() {
106+type mirrorPull struct{}
107+
108+// Spec derives the spec used for pull mirrors and implements Runner.
109+func (m mirrorPull) Spec(ctx context.Context) string {
110+	cfg := config.FromContext(ctx)
111+	if cfg.Jobs.MirrorPull != "" {
112+		return cfg.Jobs.MirrorPull
113+	}
114+	return "@every 10m"
115+}
116+
117+// Func runs the (pull) mirror job task and implements Runner.
118+func (m mirrorPull) Func(ctx context.Context) func() {
119 	cfg := config.FromContext(ctx)
120 	logger := log.FromContext(ctx).WithPrefix("jobs.mirror")
121 	b := backend.FromContext(ctx)
122diff --git a/server/server.go b/server/server.go
123index 8c73ad213dd6d68a51f7463604e56d851ff70d47..71f796522ecea1169f311ff7bef573e2fbac313e 100644
124--- a/server/server.go
125+++ b/server/server.go
126@@ -57,7 +57,7 @@ func NewServer(ctx context.Context) (*Server, error) {
127 	// Add cron jobs.
128 	sched := cron.NewScheduler(ctx)
129 	for n, j := range jobs.List() {
130-		id, err := sched.AddFunc(j.Spec, j.Func(ctx))
131+		id, err := sched.AddFunc(j.Runner.Spec(ctx), j.Runner.Func(ctx))
132 		if err != nil {
133 			logger.Warn("error adding cron job", "job", n, "err", err)
134 		}