# SPDX-FileCopyrightText: 2020 Luke Granger-Brown <depot@lukegb.com>
#
# SPDX-License-Identifier: Apache-2.0

{ depot, lib, pkgs, rebuilder, config, ... }:
let
  inherit (depot.ops) secrets;
in {
  imports = [
    ../../../third_party/nixpkgs/nixos/modules/profiles/qemu-guest.nix
    ../lib/low-space.nix
  ];
  boot.kernelModules = [ "tcp_bbr" ];
  boot.kernel.sysctl = {
    "net.ipv6.conf.default.accept_ra" = 1;
    "net.ipv6.conf.all.accept_ra" = 1;
  };

  fileSystems = {
    "/" = {
      device = "/dev/vda1";
      fsType = "ext4";
    };
  };

  nix.maxJobs = lib.mkDefault 2;
  hardware.enableRedistributableFirmware = true;

  nix.nixPath = [ "depot=/home/lukegb/depot/" "nixpkgs=/home/lukegb/depot/third_party/nixpkgs/" ];

  # Use GRUB2.
  boot.loader.grub.enable = true;
  boot.loader.grub.version = 2;
  boot.loader.grub.device = "/dev/vda";

  # Networking!
  networking = {
    hostName = "marukuru"; # Define your hostname.
    domain = "lukegb.xyz";
    nameservers = ["2001:4860:4860::8888" "8.8.8.8"];
    useDHCP = false;
    defaultGateway = {
      address = "103.105.48.1"; interface = "eth0";
    };
    dhcpcd.enable = false;
    usePredictableInterfaceNames = true;
    interfaces = {
      eth0 = {
        ipv4.addresses = [
          { address="103.105.48.15"; prefixLength=24; }
        ];
        ipv6.addresses = [
          { address="2402:28c0:4:104e::1"; prefixLength=64; }
        ];
      };
    };
  };
  my.ip.tailscale = "100.98.193.46";
  services.udev.extraRules = ''
    ATTR{address}=="52:54:00:84:e2:2a", NAME="eth0"
  '';

  # List packages installed in system profile. To search, run:
  # $ nix search wget
  environment.systemPackages = with pkgs; [];

  services.openssh.ports = [ 20022 ];
  my.deploy.args = "-p 20022";

  networking.firewall = {
    interfaces.docker0.allowedTCPPorts = [ 25 ];
    allowedTCPPorts = [ 22 80 443 20022 ];
    # allowedUDPPorts = [];
    allowPing = true;
  };

  # Define a user account.
  users.mutableUsers = false;
  users.users = {
    root.hashedPassword = secrets.passwordHashes.root;
    lukegb = {
      isNormalUser = true;
      uid = 1000;
      extraGroups = [ "wheel" ];
      hashedPassword = secrets.passwordHashes.root;
    };
    postfix = {
      extraGroups = [ "opendkim" ];
    };
  };

  services.postfix = {
    enable = true;
    domain = "hg.lukegb.com";
    hostname = "hg.lukegb.com";
    extraConfig = ''
      milter_protocol = 2
      milter_default_action = accept
      smtpd_milters = ${config.services.opendkim.socket}
      non_smtpd_milters = ${config.services.opendkim.socket}
    '';
    networks = [ "172.17.0.0/16" ];
  };
  services.opendkim = {
    enable = true;
    domains = "csl:hg.lukegb.com";
    selector = "marukuru";
  };

  security.acme = {
    acceptTerms = true;
    email = "letsencrypt@lukegb.com";
  };

  virtualisation.oci-containers.containers = {
    heptapod-runner = {
      image = "octobus/heptapod-runner:0.2.0";
      volumes = [
        "/srv/gitlab-runner/config:/etc/gitlab-runner"
        "/var/run/docker.sock:/var/run/docker.sock"
      ];
    };
    heptapod = {
      #image = "octobus/heptapod:0.13.0-py3";
      image = "heptapod:latest";
      ports = [
        # host:container
        "22:22"
        "80:80"
        "443:443"
      ];
      volumes = [
        "/srv/gitlab/config:/etc/gitlab"
        "/srv/gitlab/logs:/var/log/gitlab"
        "/srv/gitlab/data:/var/opt/gitlab"
      ];
      environment = {
        GITLAB_OMNIBUS_CONFIG = builtins.replaceStrings ["\n"] [";"] ''
          external_url "https://hg.lukegb.com"
          letsencrypt['enable'] = true
          letsencrypt['contact_emails'] = ['letsencrypt@lukegb.com']
          nginx['redirect_http_to_https'] = true

          gitlab_rails['smtp_enable'] = true
          gitlab_rails['smtp_address'] = '103.105.48.15'
          gitlab_rails['smtp_port'] = 25
          gitlab_rails['gitlab_email_from'] = 'heptapod@hg.lukegb.com'
          gitlab_rails['gitlab_email_reply_to'] = 'noreply@hg.lukegb.com'

          prometheus['enable'] = false
        '';
      };
    };
  };

  # Container networking.
  networking.nat = {
    enable = true;
    internalInterfaces = [ "ve-+" ];
    externalInterface = "eth0";
  };
  networking.networkmanager.unmanaged = [ "interface-name:ve-*" ];

  containers.deployer = {
    config = { config, pkgs, ... }: {
      imports = [
        ../lib/low-space.nix
      ];
      networking.hosts = depot.ops.nixos.tailscaleIPs;
      nix = {
        binaryCaches = lib.mkForce [ "https://cache.nixos.org/" "s3://lukegb-nix-cache?endpoint=storage.googleapis.com&trusted=1" ];
        trustedBinaryCaches = lib.mkForce [ "https://cache.nixos.org/" "s3://lukegb-nix-cache?endpoint=storage.googleapis.com&trusted=1" ];
        envVars = {
          AWS_ACCESS_KEY_ID = "${depot.ops.secrets.nixCache.AWS_ACCESS_KEY_ID}";
          AWS_SECRET_ACCESS_KEY = "${depot.ops.secrets.nixCache.AWS_SECRET_ACCESS_KEY}";
        };
      };
      environment.etc."secrets/gitlab-runner-registration" = {
        text = ''
          CI_SERVER_URL=https://hg.lukegb.com
          REGISTRATION_TOKEN=${depot.ops.secrets.deployer.registrationToken}
        '';
        mode = "0600";
      };
      services.gitlab-runner = {
        enable = true;
        concurrent = 4;
        services = {
          deployer = {
            registrationConfigFile = "/etc/secrets/gitlab-runner-registration";
            executor = "shell";
            tagList = [ "deployer" ];
          };
        };
        gracefulTermination = true;
        gracefulTimeout = "4min";
        package = depot.nix.pkgs.heptapod-runner;
      };
      users.users.gitlab-runner = {
        createHome = true;
        home = "/srv/gitlab-runner";
      };
      system.activationScripts.deployer-key = lib.stringAfter [ "users" "groups" ] ''
        mkdir -p /srv/gitlab-runner/.ssh
        chown -R gitlab-runner:nogroup /srv/gitlab-runner/.ssh
        chmod -R u=rwX,go= /srv/gitlab-runner/.ssh
        cp "${pkgs.writeTextFile {
          name = "gitlab-runner-key";
          destination = "/private/id_ed25519";
          text = depot.ops.secrets.deployer.privateKey;
        }}/private/id_ed25519" /srv/gitlab-runner/.ssh/id_ed25519
        chown -R gitlab-runner:nogroup /srv/gitlab-runner/.ssh
        chmod -R u=rwX,go= /srv/gitlab-runner/.ssh
      '';
      environment.systemPackages = with pkgs; [
        vim rxvt_unicode.terminfo rsync jq
        depot.nix.pkgs.heptapod-runner-mercurial
      ];
    };
  };

  system.stateVersion = "20.03";
}