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 }