From eb81078b3c32c76f6723bfffaf52a765906ff991 Mon Sep 17 00:00:00 2001 From: Yvan Sraka Date: Thu, 21 Aug 2025 05:56:49 +0200 Subject: [PATCH] feat: deploy logrotate using system manager --- .editorconfig | 12 +++ .../logrotate-postgres-auth.conf | 8 -- .../logrotate-postgres-csv.conf | 11 --- .../logrotate_config/logrotate-postgres.conf | 9 -- .../logrotate_config/logrotate-walg.conf | 9 -- ansible/tasks/finalize-ami.yml | 20 ----- nix/packages/docker-ubuntu.nix | 4 + nix/systemConfigs.nix | 2 + nix/systemModules/default.nix | 4 +- nix/systemModules/logrotate.nix | 90 +++++++++++++++++++ nix/systemModules/tests/test_logrotate.py | 30 +++++++ 11 files changed, 141 insertions(+), 58 deletions(-) create mode 100644 .editorconfig delete mode 100644 ansible/files/logrotate_config/logrotate-postgres-auth.conf delete mode 100644 ansible/files/logrotate_config/logrotate-postgres-csv.conf delete mode 100644 ansible/files/logrotate_config/logrotate-postgres.conf delete mode 100644 ansible/files/logrotate_config/logrotate-walg.conf create mode 100644 nix/systemModules/logrotate.nix create mode 100644 nix/systemModules/tests/test_logrotate.py diff --git a/.editorconfig b/.editorconfig new file mode 100644 index 000000000..a72279722 --- /dev/null +++ b/.editorconfig @@ -0,0 +1,12 @@ +# EditorConfig is awesome: https://EditorConfig.org + +# top-most EditorConfig file +root = true + +[*.nix] +indent_style = space +indent_size = 2 +end_of_line = lf +charset = utf-8 +trim_trailing_whitespace = true +insert_final_newline = true \ No newline at end of file diff --git a/ansible/files/logrotate_config/logrotate-postgres-auth.conf b/ansible/files/logrotate_config/logrotate-postgres-auth.conf deleted file mode 100644 index 050210e60..000000000 --- a/ansible/files/logrotate_config/logrotate-postgres-auth.conf +++ /dev/null @@ -1,8 +0,0 @@ -/var/log/postgresql/auth-failures.csv { - size 10M - rotate 5 - compress - delaycompress - notifempty - missingok -} diff --git a/ansible/files/logrotate_config/logrotate-postgres-csv.conf b/ansible/files/logrotate_config/logrotate-postgres-csv.conf deleted file mode 100644 index e5418e8e0..000000000 --- a/ansible/files/logrotate_config/logrotate-postgres-csv.conf +++ /dev/null @@ -1,11 +0,0 @@ -/var/log/postgresql/postgresql.csv { - size 50M - rotate 9 - compress - delaycompress - notifempty - missingok - postrotate - sudo -u postgres /usr/lib/postgresql/bin/pg_ctl -D /var/lib/postgresql/data logrotate - endscript -} diff --git a/ansible/files/logrotate_config/logrotate-postgres.conf b/ansible/files/logrotate_config/logrotate-postgres.conf deleted file mode 100644 index c802320c4..000000000 --- a/ansible/files/logrotate_config/logrotate-postgres.conf +++ /dev/null @@ -1,9 +0,0 @@ -/var/log/postgresql/postgresql.log { - size 50M - rotate 3 - copytruncate - delaycompress - compress - notifempty - missingok -} diff --git a/ansible/files/logrotate_config/logrotate-walg.conf b/ansible/files/logrotate_config/logrotate-walg.conf deleted file mode 100644 index 49eeb59eb..000000000 --- a/ansible/files/logrotate_config/logrotate-walg.conf +++ /dev/null @@ -1,9 +0,0 @@ -/var/log/wal-g/*.log { - size 50M - rotate 3 - copytruncate - delaycompress - compress - notifempty - missingok -} diff --git a/ansible/tasks/finalize-ami.yml b/ansible/tasks/finalize-ami.yml index 7f0de3ac8..095b3a342 100644 --- a/ansible/tasks/finalize-ami.yml +++ b/ansible/tasks/finalize-ami.yml @@ -41,18 +41,6 @@ policy: deny direction: incoming -- name: Move logrotate files to /etc/logrotate.d/ - copy: - src: "files/logrotate_config/{{ item.file }}" - dest: "/etc/logrotate.d/{{ item.file }}" - mode: "0700" - owner: root - loop: - - { file: "logrotate-postgres-csv.conf" } - - { file: "logrotate-postgres.conf" } - - { file: "logrotate-walg.conf" } - - { file: "logrotate-postgres-auth.conf" } - - name: Ensure default Postgres logrotate config is removed file: path: /etc/logrotate.d/postgresql-common @@ -63,14 +51,6 @@ src: files/cron.deny dest: /etc/cron.deny -- name: Configure logrotation to run every hour - shell: - cmd: | - cp /usr/lib/systemd/system/logrotate.timer /etc/systemd/system/logrotate.timer - sed -i -e 's;daily;*:0/5;' /etc/systemd/system/logrotate.timer - systemctl reenable logrotate.timer - become: yes - - name: import pgsodium_getkey script template: src: files/pgsodium_getkey_readonly.sh.j2 diff --git a/nix/packages/docker-ubuntu.nix b/nix/packages/docker-ubuntu.nix index 838f68f68..c60fc7f96 100644 --- a/nix/packages/docker-ubuntu.nix +++ b/nix/packages/docker-ubuntu.nix @@ -14,6 +14,10 @@ let in runCommand "ubuntu-cloudimg" { nativeBuildInputs = [ xz ]; } '' mkdir -p $out + # FIXME: remove (among other things) builtin logrotate to avoid conflicts with the one set-up by system-manager + # --exclude='etc/systemd/system/timers.target.wants/logrotate.timer' \ + # --exclude='usr/lib/systemd/system/logrotate.service' \ + # --exclude='usr/lib/systemd/system/logrotate.timer' \ tar --exclude='dev/*' \ --exclude='etc/systemd/system/network-online.target.wants/systemd-networkd-wait-online.service' \ --exclude='etc/systemd/system/multi-user.target.wants/systemd-resolved.service' \ diff --git a/nix/systemConfigs.nix b/nix/systemConfigs.nix index 7f50ded93..0945288a6 100644 --- a/nix/systemConfigs.nix +++ b/nix/systemConfigs.nix @@ -1,9 +1,11 @@ { self, inputs, ... }: let mkModules = system: [ + self.systemModules.logrotate ({ services.nginx.enable = true; nixpkgs.hostPlatform = system; + supabase.services.logrotate.enable = true; }) ]; diff --git a/nix/systemModules/default.nix b/nix/systemModules/default.nix index 14b459255..92d31be46 100644 --- a/nix/systemModules/default.nix +++ b/nix/systemModules/default.nix @@ -4,6 +4,8 @@ { imports = [ ./tests ]; flake = { - systemModules = { }; + systemModules = { + logrotate = ./logrotate.nix; + }; }; } diff --git a/nix/systemModules/logrotate.nix b/nix/systemModules/logrotate.nix new file mode 100644 index 000000000..9b8cc793e --- /dev/null +++ b/nix/systemModules/logrotate.nix @@ -0,0 +1,90 @@ +{ + lib, + nixosModulesPath, + config, + ... +}: +let + cfg = config.supabase.services.logrotate; +in +{ + imports = map (path: nixosModulesPath + path) [ + # FIXME: we can't use the logrotate module from nixpkgs becauce it's defined as a no-op option in system-manager: + # https://github.com/numtide/system-manager/blob/main/nix/modules/default.nix#L102-L108 + # + # error: The option `services.logrotate' in module `/nix/store/...-source/nix/modules' + # would be a parent of the following options,but its type `attribute set' does not support nested options. + # + # "/services/logging/logrotate.nix" + ]; + + options = { + supabase.services.logrotate = { + enable = lib.mkEnableOption "Whether to enable the logrotate systemd service."; + }; + }; + + config = lib.mkIf cfg.enable { + environment.etc = { + "logrotate.d/logrotate-postgres-auth.conf".text = '' + /var/log/postgresql/auth-failures.csv { + size 10M + rotate 5 + compress + delaycompress + notifempty + missingok + } + ''; + "logrotate.d/logrotate-postgres-csv.conf".text = '' + /var/log/postgresql/postgresql.csv { + size 50M + rotate 9 + compress + delaycompress + notifempty + missingok + postrotate + sudo -u postgres /usr/lib/postgresql/bin/pg_ctl -D /var/lib/postgresql/data logrotate + endscript + } + ''; + "logrotate.d/logrotate-postgres.conf".text = '' + /var/log/postgresql/postgresql.log { + size 50M + rotate 3 + copytruncate + delaycompress + compress + notifempty + missingok + } + ''; + "logrotate.d/logrotate-walg.conf".text = '' + /var/log/wal-g/*.log { + size 50M + rotate 3 + copytruncate + delaycompress + compress + notifempty + missingok + } + ''; + }; + + # FIXME: logrotate.service isn't a valid unit file (missing ExecStart), because it's already provided by Ubuntu: + # systemd.services.logrotate = { + # wantedBy = lib.mkForce [ + # "system-manager.target" + # ]; + # }; + + # Overide systemd logrotate.timer to run every 5 minutes: + systemd.timers.logrotate = { + wantedBy = [ "timers.target" ]; + timerConfig.OnCalendar = "*:0/5"; + timerConfig.Persistent = true; + }; + }; +} diff --git a/nix/systemModules/tests/test_logrotate.py b/nix/systemModules/tests/test_logrotate.py new file mode 100644 index 000000000..4b06aec8f --- /dev/null +++ b/nix/systemModules/tests/test_logrotate.py @@ -0,0 +1,30 @@ +# from time import sleep + + +# def test_debug(host): +# sleep(5000) # Handy for interactive debugging (with docker exec -it $CONTAINER_ID /bin/bash) + + +def test_logrotate_timer(host): + timer = host.service("logrotate.timer") + assert timer.is_enabled + assert timer.is_running + + +def test_logrotate_service_unit(host): + svc = host.service("logrotate.service") + assert svc.is_valid + result = host.run("systemctl start logrotate.service") + assert result.rc == 0 + + +def test_logrotate_configs(host): + for fname in [ + "/etc/logrotate.d/logrotate-postgres-auth.conf", + "/etc/logrotate.d/logrotate-postgres-csv.conf", + "/etc/logrotate.d/logrotate-postgres.conf", + "/etc/logrotate.d/logrotate-walg.conf", + ]: + f = host.file(fname) + assert f.exists + assert f.user == "root"