From 28f578d8d406f9fe563c9251ba3d8ff32c68f99c Mon Sep 17 00:00:00 2001 From: "Jeffrey C. Ollie" Date: Sat, 15 Apr 2023 22:30:12 -0500 Subject: [PATCH] switch to nixos --- .drone.yml | 36 +++++++-- .gitignore | 1 + flake.lock | 26 +++++++ flake.nix | 223 ++++++++++++++++++++++++++++++++++++++++++++++------- 4 files changed, 249 insertions(+), 37 deletions(-) create mode 100644 .gitignore create mode 100644 flake.lock diff --git a/.drone.yml b/.drone.yml index c2c29a0..26ca68b 100644 --- a/.drone.yml +++ b/.drone.yml @@ -15,22 +15,42 @@ kind: pipeline type: kubernetes name: build steps: - - name: publish - image: plugins/kaniko + # - name: publish + # image: plugins/kaniko + # pull: always + # settings: + # build_args: + # - VERSION=2.8.1 + # repo: r.ocj.io/network/healthchecks + # registry: r.ocj.io + # username: + # from_secret: local_username + # password: + # from_secret: local_password + # tags: + # - "latest" + # - "${DRONE_BUILD_NUMBER}-${DRONE_COMMIT_SHA:0:8}" + - name: nixos + image: docker.io/jcollie/nixos-runner:latest + pull: always + commands: + - nix build -L .#webserver + - nix run .#push-container -- result --repository network/healthchecks-webserver + - nix build -L .#smtpd + - nix run .#push-container -- result --repository network/healthchecks-smtpd + - nix build -L .#sendalerts + - nix run .#push-container -- result --repository network/healthchecks-sendalerts + - nix build -L .#maintenance + - nix run .#push-container -- result --repository network/healthchecks-maintenance settings: - build_args: - - VERSION=2.8.1 - repo: r.ocj.io/network/healthchecks registry: r.ocj.io username: from_secret: local_username password: from_secret: local_password - tags: - - "latest" - - "${DRONE_BUILD_NUMBER}-${DRONE_COMMIT_SHA:0:8}" - name: notify image: plugins/webhook + failure: ignore settings: urls: - http://receiver.flux-system.svc/hook/edb4b3e16a177e035bc595a5be33c3b04b51145c7d802bddf05f27486e1dbd4d diff --git a/.gitignore b/.gitignore new file mode 100644 index 0000000..d6944e3 --- /dev/null +++ b/.gitignore @@ -0,0 +1 @@ +/result* diff --git a/flake.lock b/flake.lock new file mode 100644 index 0000000..33692a3 --- /dev/null +++ b/flake.lock @@ -0,0 +1,26 @@ +{ + "nodes": { + "nixpkgs": { + "locked": { + "lastModified": 1681465517, + "narHash": "sha256-EasJh15/jcJNAHtq2SGbiADRXteURAnQbj1NqBoKkzU=", + "owner": "NixOS", + "repo": "nixpkgs", + "rev": "abe7316dd51a313ce528972b104f4f04f56eefc4", + "type": "github" + }, + "original": { + "id": "nixpkgs", + "ref": "nixos-unstable", + "type": "indirect" + } + }, + "root": { + "inputs": { + "nixpkgs": "nixpkgs" + } + } + }, + "root": "root", + "version": 7 +} diff --git a/flake.nix b/flake.nix index 806b954..96016cf 100644 --- a/flake.nix +++ b/flake.nix @@ -3,7 +3,7 @@ inputs = { nixpkgs = { - url = "nixpkgs/nixos-22.11"; + url = "nixpkgs/nixos-unstable"; }; }; @@ -33,39 +33,204 @@ ) ]; }; - + py = pkgs.python3.override { + packageOverrides = final: prev: { + django = prev.django_4; + }; + }; + baseImage = { + tag = "latest"; + maxLayers = 2; + contents = [ + pkgs.bash + pkgs.coreutils-full + ]; + config = { + User = "5000:5000"; + Volumes = { + "/static" = { }; + "/tmp" = { }; + }; + WorkingDir = "${self.packages.${system}.healthchecks}/opt/healthchecks"; + Env = [ + "LANG=en_US.UTF-8" + "PYTHONPATH=${self.packages.${system}.healthchecks.pythonPath}" + "PYTHONUNBUFFERED=1" + "SSL_CERT_FILE=${pkgs.cacert}/etc/ssl/certs/ca-bundle.crt" + "STATIC_ROOT=/static" + ]; + }; + }; in { - packages.${system}.smtpd = pkgs.dockerTools.buildLayeredImage - { - name = "healthchecks-smtpd"; - tag = "latest"; - maxLayers = 2; - copyToRoot = pkgs.buildEnv { - name = "image-root"; - pathsToLink = [ "/" ]; - paths = [ - pkgs.healthchecks + packages.${system} = { + healthchecks = + let + pname = "healthchecks"; + version = "2.8.1"; + hash = "sha256-lJ0AZJpznet2YKPIyMOx5ZdETZB8de5vp7sydfndxZg="; + localSettings = pkgs.writeText "local_settings.py" '' + import os + STATIC_ROOT = os.getenv("STATIC_ROOT") + SECRET_KEY_FILE = os.getenv("SECRET_KEY_FILE") + if SECRET_KEY_FILE: + with open(SECRET_KEY_FILE, "r") as file: + SECRET_KEY = file.readline() + ''; + propagatedBuildInputs = with py.pkgs; [ + apprise + cron-descriptor + cronsim + django + django-compressor + fido2 + minio + psycopg2 + pycurl + pyotp + segno + statsd + whitenoise ]; - }; - config = { - Cmd = [ - "${pkgs.sonarr}/bin/NzbDrone" - "-nobrowser" - "-data=/config" - ]; - User = "5000:5000"; - ExposedPorts = { - "8989/tcp" = { }; + in + py.pkgs.buildPythonApplication { + inherit pname version propagatedBuildInputs; + format = "other"; + + src = pkgs.fetchFromGitHub { + owner = "healthchecks"; + repo = pname; + rev = "v${version}"; + inherit hash; }; - Volumes = { - "/config" = { }; + + installPhase = '' + mkdir -p $out/opt/healthchecks + cp -r . $out/opt/healthchecks + chmod +x $out/opt/healthchecks/manage.py + cp ${localSettings} $out/opt/healthchecks/hc/local_settings.py + ''; + + passthru = { + # PYTHONPATH of all dependencies used by the package + pythonPath = py.pkgs.makePythonPath propagatedBuildInputs; + + tests = { + inherit (pkgs.nixosTests) healthchecks; + }; + }; + + meta = with pkgs.lib; { + homepage = "https://github.com/healthchecks/healthchecks"; + description = "A cron monitoring tool written in Python & Django "; + license = licenses.bsd3; }; - Env = [ - "LANG=en_US.UTF-8" - "SSL_CERT_FILE=${pkgs.cacert}/etc/ssl/certs/ca-bundle.crt" - ]; }; - }; + + smtpd = pkgs.dockerTools.buildLayeredImage + ( + pkgs.lib.attrsets.recursiveUpdate baseImage { + name = "healthchecks-smtpd"; + config = { + Cmd = [ + "${self.packages.${system}.healthchecks}/opt/healthchecks/manage.py" + "smtpd" + "--port" + "2525" + ]; + ExposedPorts = { + "2525/tcp" = { }; + }; + }; + } + ); + + sendalerts = pkgs.dockerTools.buildLayeredImage + ( + pkgs.lib.attrsets.recursiveUpdate baseImage { + name = "healthchecks-sendalerts"; + config = { + Cmd = [ + "${self.packages.${system}.healthchecks}/opt/healthchecks/manage.py" + "sendalerts" + ]; + ExposedPorts = { }; + }; + } + ); + + maintenance = + let + script = pkgs.writeScript "maintenance" '' + CURL_OPTIONS="--fail --silent --show-error --max-time 10 --retry 5 --output /dev/null" + ${pkgs.curl}/bin/curl $CURL_OPTIONS http://webserver.healthchecks.svc/ping/$MAINTENANCE_CHECK_UUID/start + ${self.packages.${system}.healthchecks}/opt/healthchecks/manage.py prunenotifications + ${self.packages.${system}.healthchecks}/opt/healthchecks/manage.py pruneusers + ${self.packages.${system}.healthchecks}/opt/healthchecks/manage.py prunetokenbucket + ${self.packages.${system}.healthchecks}/opt/healthchecks/manage.py pruneflips + ${pkgs.curl}/bin/curl $CURL_OPTIONS http://webserver.healthchecks.svc/ping/$MAINTENANCE_CHECK_UUID + ''; + in + pkgs.dockerTools.buildLayeredImage + ( + pkgs.lib.attrsets.recursiveUpdate baseImage { + name = "healthchecks-maintenance"; + config = { + Cmd = [ + "${script}" + ]; + ExposedPorts = { }; + }; + } + ); + + webserver = + let + uwsgi-ini = pkgs.writeTextFile { + name = "uwsgi.ini"; + text = '' + [uwsgi] + master + die-on-term + http-socket = :8000 + harakiri = 10 + post-buffering = 4096 + processes = 4 + enable-threads + threads = 1 + chdir = ${self.packages.${system}.healthchecks}/opt/healthchecks + module = hc.wsgi:application + thunder-lock + disable-write-exception + static-map = /static=${self.packages.${system}.healthchecks}/opt/healthchecks/static-collected + buffer-size = 32768 + ''; + }; + in + pkgs.dockerTools.buildLayeredImage ( + pkgs.lib.attrsets.recursiveUpdate baseImage { + name = "healthchecks-webserver"; + fakeRootCommands = ''; + mkdir /static + chmod 0777 /static + mkdir /tmp + chmod 0777 /tmp + ''; + config = { + Cmd = [ + "${pkgs.python3Packages.gunicorn}/bin/gunicorn" + "hc.wsgi" + "--bind" + ":8000" + "--pythonpath" + self.packages.${system}.healthchecks.pythonPath + ]; + ExposedPorts = { + "8000/tcp" = { }; + }; + }; + } + ); + }; }; }