~aasg/nixexprs

4a7cc80bdd35a357bccbcaed3ada4865f6962af6 — Aluísio Augusto Silva Gonçalves 10 months ago
Split packages and modules off nixos-configurations

This will allow me to make them public while keeping the NixOS
configuration private.

Some reorganization was made to 1) be compatible with NUR, even though
I don't currently use it; and 2) mirror the nixpkgs taxonomy, to more
easily move packages upstream later on.

All package and NixOS module expressions were taken from
nixos-configurations@361ad13626117ee715ee1e215458329e8d0bada4.
A  => .editorconfig +9 -0
@@ 1,9 @@
root = true

[*]
charset = utf-8
end_of_line = lf
insert_final_newline = true
trim_trailing_whitespace = true
indent_style = spaces
indent_size = 2

A  => .gitattributes +1 -0
@@ 1,1 @@
* text eol=lf

A  => .gitignore +2 -0
@@ 1,2 @@
result
result-*

A  => default.nix +8 -0
@@ 1,8 @@
{ pkgs ? import <nixpkgs> { } }:

{
  modules = import ./modules;
  overlays = {
    pkgs = import ./pkgs/overlay.nix;
  };
} // (import ./pkgs { inherit pkgs; })

A  => modules/default.nix +4 -0
@@ 1,4 @@
{
  postgresql-base-backup = ./services/databases/postgresql-base-backup.nix;
  dyndnsc = ./services/networking/dyndnsc.nix;
}

A  => modules/services/databases/postgresql-base-backup.nix +45 -0
@@ 1,45 @@
{ config, lib, pkgs, ... }:

with lib;
let

  cfg = config.services.postgresqlBaseBackup;

in
{
  options = {
    services.postgresqlBaseBackup = {
      enable = mkEnableOption "PostgreSQL backups using pg_basebackup";

      location = mkOption {
        type = types.path;
        description = "directory where to store the backup.";
      };
    };
  };

  config = mkIf cfg.enable {
    systemd.tmpfiles.rules = [
      "d ${cfg.location} 0700 postgres postgres - -"
    ];

    systemd.services."postgresql-base-backup" = {
      description = "PostgreSQL database cluster backup";
      serviceConfig = {
        Type = "oneshot";
        User = "postgres";
      };
      restartIfChanged = false;
      preStart = ''
        ${pkgs.coreutils}/bin/rm -f ${cfg.location}/*
      '';
      script = toString [
        "${config.services.postgresql.package}/bin/pg_basebackup"
        "--port=${config.services.postgresql.port}"
        "--username=${config.services.postgresql.superUser}"
        "--pgdata=${cfg.location}"
        "--wal-method=stream"
      ];
    };
  };
}

A  => modules/services/networking/dyndnsc.nix +137 -0
@@ 1,137 @@
{ config, lib, pkgs, ... }:

with lib;
let
  stateDir = "/run/dyndnsc";

  runtimeConfigFile = "${stateDir}/config.ini";

  cfg = config.services.dyndnsc;

  profileConfigs =
    mapAttrsToList
      (name: profile: ''
        [${name}]
        ${optionalString (profile.preset != "") "use_preset = ${profile.preset}"}
        updater-hostname = ${profile.hostname}
        updater-userid = ${profile.username}
        updater-password = %(password_${name})s
        ${profile.extraConfig}
      '')
      cfg.profiles;

  configFile = pkgs.writeText "dyndnsc.ini" ''
    [dyndnsc]
    configs = ${concatStringsSep ", " (attrNames cfg.profiles)}

    ${concatStrings profileConfigs}
  '';

in
{
  options = {
    services.dyndnsc = {
      enable = mkEnableOption "dyndnsc Dynamic DNS client";

      package = mkOption {
        default = pkgs.dyndnsc or (import ../../../pkgs { inherit pkgs; }).dyndnsc;
        defaultText = "pkgs.dyndnsc";
        type = types.package;
        description = "dyndnsc package to use.";
      };

      profiles = mkOption {
        type = types.attrsOf (types.submodule {
          options = {
            preset = mkOption {
              type = types.nullOr (types.enum [
                # Keep in sync with dyndnsc/resources/presets.ini in the source.
                "no-ip.com"
                "freedns.afraid.com"
                "nsupdate.info:ipv4"
                "nsupdate.info:ipv6"
                "dns.he.net"
                "dnsimple.com"
                "dnsdynamic.org"
                "hopper.pw:ipv4"
                "hopper.pw:ipv6"
                "dyn.com"
                "duckdns.org"
              ]);
              default = null;
              description = ''
                Preset profile to inherit.
              '';
              example = "dns.he.net";
            };
            hostname = mkOption {
              type = types.str;
              description = "Hostname or domain to be updated.";
              example = "dynamic.example.com";
            };
            username = mkOption {
              type = types.str;
              description = "Username to login with in the dynamic DNS service.";
            };
            passwordFile = mkOption {
              type = types.path;
              description = "Path to a file containing the service's password.";
              example = "/run/keys/dyndnsc-myprofile";
            };
            extraConfig = mkOption {
              type = types.lines;
              default = "";
              description = "Additional profile parameters.";
            };
          };
        });
        example = literalExample ''
          {
            "myhost_ip4" = {
              preset = "nsupdate.info:ipv4";
              hostname = "dynamic.example.com";
              username = "me";
              passwordFile = "/run/keys/dyndnsc-myhost_ip4";
            };
          };
        '';
        description = "Declarative profile config";
      };
    };
  };

  config = mkIf cfg.enable {
    systemd.services.dyndnsc = {
      description = "Dynamic DNS client";
      after = [ "network.target" ];
      wantedBy = [ "multi-user.target" ];
      stopIfChanged = true;
      serviceConfig = {
        ExecStart = ''${cfg.package}/bin/dyndnsc --verbose --loop --config "${runtimeConfigFile}"'';
        Restart = "on-failure";
        RestartIntervalSec = 30;
      };
      preStart =
        let
          profilePasswords = concatStrings (
            mapAttrsToList
              (name: profile: ''
                password_${name} = $(cat "${profile.passwordFile}")
              '')
              cfg.profiles
          );
        in
        ''
          mkdir -p "${stateDir}"
          install -m0600 /dev/null "${runtimeConfigFile}"
          cat "${configFile}" - >"${runtimeConfigFile}" <<EOF
          [DEFAULT]
          ${profilePasswords}
          EOF
        '';
      postStop = ''
        rm -f "${runtimeConfigFile}"
      '';
    };
  };
}

A  => pkgs/default.nix +5 -0
@@ 1,5 @@
{ pkgs }:
let
  self = (import ./overlay.nix) (self // pkgs) pkgs;
in
self

A  => pkgs/development/python-modules/daemonocle/default.nix +29 -0
@@ 1,29 @@
{ lib
, buildPythonPackage
, fetchPypi
, click
, psutil
}:

buildPythonPackage rec {
  pname = "daemonocle";
  version = "1.0.1";

  src = fetchPypi {
    inherit pname version;
    sha256 = "a8fc48d55f6390302a9a1816ad488cba640e70948f750d4c8fe5a401294dab68";
  };

  propagatedBuildInputs = [ click psutil ];

  # Tests don't seem to work with sandboxing enabled.
  doCheck = false;

  meta = with lib; {
    description = "A Python library for creating super fancy Unix daemons";
    homepage = "https://github.com/jnrbsn/daemonocle";
    license = licenses.mit;
    platforms = platforms.unix;
    maintainers = [ maintainers.AluisioASG ];
  };
}

A  => pkgs/development/python-modules/default.nix +5 -0
@@ 1,5 @@
pyself: pysuper:

{
  daemonocle = pysuper.callPackage ./daemonocle { inherit (pyself) click psutil; };
}

A  => pkgs/os-specific/linux/kernel-packages.nix +5 -0
@@ 1,5 @@
kself: ksuper:

{
  rtl8723bu = ksuper.callPackage ./rtl8723bu { };
}

A  => pkgs/os-specific/linux/rtl8723bu/default.nix +43 -0
@@ 1,43 @@
{ stdenv, fetchFromGitHub, kernel, concurrentMode ? false }:

stdenv.mkDerivation rec {
  name = "rtl8723bu-${kernel.version}-${version}";
  version = "2020-01-26";

  src = fetchFromGitHub {
    owner = "lwfinger";
    repo = "rtl8723bu";
    rev = "2d939a37048e9ee9fa26e225461c59a34f72dcc5";
    sha256 = "0scc5hx083gmcp3igb00agwpv903r2h9pzz1zdmy2pm072m2ayji";
  };

  postPatch = stdenv.lib.optionalString (!concurrentMode) ''
    sed -i '/-DCONFIG_CONCURRENT_MODE/d' Makefile
  '';

  hardeningDisable = [
    "fortify"
    "pic"
    "stackprotector"
  ];

  nativeBuildInputs = kernel.moduleBuildDependencies;

  makeFlags = [
    "ARCH=${stdenv.hostPlatform.platform.kernelArch}"
    "KSRC=${kernel.dev}/lib/modules/${kernel.modDirVersion}/build"
    "KVER=${kernel.version}"
    "DEPMOD=true"
    "INSTALL_MOD_PATH=$(out)"
  ];

  enableParallelBuilding = true;

  meta = with stdenv.lib; {
    description = "Driver for RTL8723BU";
    homepage = "https://github.com/lwfinger/rtl8723bu";
    license = licenses.unfreeRedistributableFirmware;
    platforms = platforms.linux;
    maintainers = [ maintainers.AluisioASG ];
  };
}

A  => pkgs/overlay.nix +16 -0
@@ 1,16 @@
self: super:

{

  dma = super.callPackage ./tools/networking/dma { inherit (self) flex openssl yacc; };

  dyndnsc = super.callPackage ./tools/networking/dyndnsc { inherit (self) python3Packages; };

  linuxPackagesFor = kernel:
    (super.linuxPackagesFor kernel).extend (import ./os-specific/linux/kernel-packages.nix);

  python3 = super.python3.override { packageOverrides = import ./development/python-modules; };

  starship = super.callPackage ./shells/starship { inherit (self) rustPlatform; };

}

A  => pkgs/shells/starship/default.nix +23 -0
@@ 1,23 @@
{ fetchFromGitHub, lib, rustPlatform }:

rustPlatform.buildRustPackage rec {
  pname = "starship";
  version = "0.19.0";

  src = fetchFromGitHub {
    owner = "starship";
    repo = "starship";
    rev = "v${version}";
    sha256 = "0cj3r8c583xzraggwl1xb36790czha4dja6c3yvn5f19whmmf2g9";
  };

  cargoSha256 = "1cg0vqsgnm35n0fdbc9vgpa44gs2g3f6vcqm80sbz28xc7rs19gr";

  meta = with lib; {
    description = "Minimal, fast, customizable cross-shell prompt";
    homepage = "https://starship.rs";
    license = licenses.isc;
    platforms = platforms.all;
    maintainers = [ maintainers.AluisioASG ];
  };
}

A  => pkgs/tools/networking/dma/default.nix +29 -0
@@ 1,29 @@
{ stdenv, fetchFromGitHub, lib, flex, yacc, openssl }:

stdenv.mkDerivation rec {
  name = "dma-${version}";
  version = "0.13";

  src = fetchFromGitHub {
    owner = "corecode";
    repo = "dma";
    rev = "v${version}";
    sha256 = "01yv1bkyim8f2jbdl83p5arrh53lyjq7dlmfl72ni4amafwfssx7";
  };

  buildInputs = [ openssl ];
  nativeBuildInputs = [ yacc flex ];

  postPatch = ''
    sed -i 's/-m [[:digit:]]\{3,4\} -o root -g mail//' Makefile
  '';
  makeFlags = [ "PREFIX=$(out)" "LEX=flex" ];

  meta = with lib; {
    description = "Small mail transport agent (MTA) designed for home and office use";
    homepage = "https://github.com/corecode/dma";
    license = licenses.bsd3;
    platforms = platforms.unix;
    maintainers = [ maintainers.AluisioASG ];
  };
}

A  => pkgs/tools/networking/dyndnsc/default.nix +38 -0
@@ 1,38 @@
{ lib, python3Packages }:

python3Packages.buildPythonApplication rec {
  pname = "dyndnsc";
  version = "0.5.1";

  src = python3Packages.fetchPypi {
    inherit pname version;
    sha256 = "1p8dgfhvks1bjvq8gww4yvi3g8fam2m5irirkf7xjhs8g38r8bjb";
  };

  nativeBuildInputs = with python3Packages; [ pytestrunner ];
  propagatedBuildInputs = with python3Packages; [
    daemonocle
    dnspython
    netifaces
    requests
    setuptools
  ];
  checkInputs = with python3Packages; [ bottle pytest ];

  postPatch = ''
    substituteInPlace setup.py --replace "bottle==" "bottle>="
  '';

  # Disable tests not supported in the sandbox.
  checkPhase = ''
    py.test -k 'not dnswanip'
  '';

  meta = with lib; {
    description = "Dynamic DNS update client with support for multiple protocols";
    homepage = "https://github.com/infothrill/python-dyndnsc";
    license = licenses.mit;
    platforms = platforms.unix;
    maintainers = [ maintainers.AluisioASG ];
  };
}