# HG changeset patch
# User Clemens Beck <cbeck@gitlab.com>
# Date 1698730026 0
#      Tue Oct 31 05:27:06 2023 +0000
# Node ID de219baa8cc0efd91ae334cd355cf25cfad598cc
# Parent  4a6b0bffab1b789bf5c312930cd620babab04238
Add support for go-crond flags

Parse and pass flags (https://github.com/webdevops/go-crond#usage) from
crond['flags'] dictionary to the go-crond service.

For example, --verbose and --server.bind can be configured by setting:

'''
crond['flags'] = {
  'verbose': true,
  'server.bind': '0.0.0.0:7000'
}
'''

The include flag (configurable via crond['cron_d']) can not be
configured with the flags dictionary.

Changelog: added

diff --git a/doc/settings/ssl/index.md b/doc/settings/ssl/index.md
--- a/doc/settings/ssl/index.md
+++ b/doc/settings/ssl/index.md
@@ -104,6 +104,17 @@
 For example, if you set it to renew on the 1st of every month at 00:00 and the
 certificate expires on the 31st, then the certificate will expire before it's renewed.
 
+Automatic renewals are managed with [go-crond](https://github.com/webdevops/go-crond).
+If wanted, one can pass [CLI arguments](https://github.com/webdevops/go-crond#usage) to
+go-crond by editing the `/etc/gitlab/gitlab.rb`:
+
+```ruby
+crond['flags'] = {
+  'log.json' = true,
+  'server.bind' = ':8040'
+}
+```
+
 To disable the automatic renewal:
 
 1. Edit `/etc/gitlab/gitlab.rb`:
diff --git a/files/gitlab-config-template/gitlab.rb.template b/files/gitlab-config-template/gitlab.rb.template
--- a/files/gitlab-config-template/gitlab.rb.template
+++ b/files/gitlab-config-template/gitlab.rb.template
@@ -3209,7 +3209,7 @@
 # patroni['tls_verify'] = true
 
 ################################################################################
-# Consul (EEP only)
+# Consul (EE only)
 ################################################################################
 # consul['enable'] = false
 # consul['dir'] = '/var/opt/gitlab/consul'
@@ -3327,7 +3327,7 @@
 #### encoded with base64
 # gitlab_rails['service_desk_email_auth_token'] = nil
 
-################################################################################
+#################################################################################
 ## Spamcheck (EE only)
 #################################################################################
 
@@ -3349,3 +3349,10 @@
 #   'SSL_CERT_DIR' => '/opt/gitlab/embedded/ssl/cers'
 # }
 # spamcheck['classifier']['log_directory'] = "/var/log/gitlab/spam-classifier"
+
+#################################################################################
+## (Go-)Crond
+#################################################################################
+# crond['log_directory'] = '/var/log/gitlab/crond'
+# crond['cron_d'] = '/var/opt/gitlab/crond'
+# crond['flags'] = {}
diff --git a/files/gitlab-cookbooks/crond/attributes/default.rb b/files/gitlab-cookbooks/crond/attributes/default.rb
--- a/files/gitlab-cookbooks/crond/attributes/default.rb
+++ b/files/gitlab-cookbooks/crond/attributes/default.rb
@@ -1,3 +1,4 @@
 default['crond']['enable'] = false
 default['crond']['log_directory'] = '/var/log/gitlab/crond'
 default['crond']['cron_d'] = '/var/opt/gitlab/crond'
+default['crond']['flags'] = {}
diff --git a/files/gitlab-cookbooks/crond/libraries/crond_helper.rb b/files/gitlab-cookbooks/crond/libraries/crond_helper.rb
new file mode 100644
--- /dev/null
+++ b/files/gitlab-cookbooks/crond/libraries/crond_helper.rb
@@ -0,0 +1,27 @@
+require 'shellwords'
+
+class CrondHelper
+  attr_reader :node
+
+  def initialize(node)
+    @node = node
+  end
+
+  def flags
+    config = []
+
+    node['crond']['flags'].each do |flag_key, flag_value|
+      next if flag_key == 'include' || flag_value == false
+
+      config << if flag_value == true
+                  "--#{flag_key}"
+                elsif !flag_value.empty?
+                  "--#{flag_key}=#{Shellwords.escape(flag_value)}"
+                end
+    end
+
+    config << "--include=#{Shellwords.escape(node['crond']['cron_d'])}"
+
+    config.join(" ")
+  end
+end
diff --git a/files/gitlab-cookbooks/crond/recipes/enable.rb b/files/gitlab-cookbooks/crond/recipes/enable.rb
--- a/files/gitlab-cookbooks/crond/recipes/enable.rb
+++ b/files/gitlab-cookbooks/crond/recipes/enable.rb
@@ -20,11 +20,13 @@
   owner "root"
 end
 
+crond_flags = CrondHelper.new(node).flags
+
 runit_service "crond" do
   owner "root"
   group "root"
   options({
-    cron_d: node['crond']['cron_d'],
+    flags: crond_flags,
     log_directory: logging_settings[:log_directory],
     log_user: logging_settings[:runit_owner],
     log_group: logging_settings[:runit_group]
diff --git a/files/gitlab-cookbooks/crond/templates/default/sv-crond-run.erb b/files/gitlab-cookbooks/crond/templates/default/sv-crond-run.erb
--- a/files/gitlab-cookbooks/crond/templates/default/sv-crond-run.erb
+++ b/files/gitlab-cookbooks/crond/templates/default/sv-crond-run.erb
@@ -6,4 +6,4 @@
 
 exec chpst -P \
   /opt/gitlab/embedded/bin/go-crond \
-    --include=<%= @options[:cron_d] %>
+    <%= @options[:flags] %>
diff --git a/spec/chef/cookbooks/crond/recipes/crond_enable_spec.rb b/spec/chef/cookbooks/crond/recipes/crond_enable_spec.rb
--- a/spec/chef/cookbooks/crond/recipes/crond_enable_spec.rb
+++ b/spec/chef/cookbooks/crond/recipes/crond_enable_spec.rb
@@ -20,6 +20,32 @@
 
   it_behaves_like "enabled runit service", "crond", "root", "root"
 
+  context 'custom flags' do
+    before do
+      stub_gitlab_rb(
+        crond: {
+          enable: true,
+          flags: {
+            'verbose': true,
+            'auto': false,
+            'log-json': true,
+            'default-user': 'user'
+          }
+        }
+      )
+    end
+
+    it "should pass correct options to runit_service" do
+      expect(chef_run).to render_file("/opt/gitlab/sv/crond/run").with_content { |content|
+        expect(content).to match(/--include=\/var\/opt\/gitlab\/crond/)
+        expect(content).to match(/--default-user=user/)
+        expect(content).to match(/--log-json/)
+        expect(content).to match(/--verbose/)
+        expect(content).not_to match(/--auto/)
+      }
+    end
+  end
+
   context 'log directory and runit group' do
     context 'default values' do
       before do