Added fudo.org DNS config (unused) and better lib imports

This commit is contained in:
root 2020-11-23 16:22:28 -06:00
parent 4164a3b156
commit 9f52086eb7
10 changed files with 629 additions and 58 deletions

View File

@ -5,8 +5,6 @@ with lib;
let let
cfg = config.fudo.dns; cfg = config.fudo.dns;
ip = import ../../lib/ip.nix { lib = lib; };
join-lines = concatStringsSep "\n"; join-lines = concatStringsSep "\n";
hostOpts = { host, ...}: { hostOpts = { host, ...}: {
@ -32,6 +30,7 @@ let
description = '' description = ''
A list of DNS SSHFP records for this host. A list of DNS SSHFP records for this host.
''; '';
default = [];
}; };
description = mkOption { description = mkOption {
@ -83,7 +82,11 @@ let
description = "A map of hostname to { host_attributes }."; description = "A map of hostname to { host_attributes }.";
}; };
dnssec = mkEnableOption "Enable DNSSEC security for this zone."; dnssec = mkOption {
type = bool;
description = "Enable DNSSEC security for this zone.";
default = true;
};
mx = mkOption { mx = mkOption {
type = listOf str; type = listOf str;
@ -160,9 +163,7 @@ let
optionalString (dmarc-email != null) optionalString (dmarc-email != null)
''_dmarc IN TXT "v=DMARC1;p=quarantine;sp=quarantine;rua=mailto:${dmarc-email};"''; ''_dmarc IN TXT "v=DMARC1;p=quarantine;sp=quarantine;rua=mailto:${dmarc-email};"'';
nsRecords = ns-hosts: nsRecords = dom: ns-hosts: join-lines (mapAttrsToList (host: _: "@ IN NS ${host}.${dom}.") ns-hosts);
join-lines ((mapAttrsToList (host: _: "@ IN NS ${host}.") ns-hosts) ++
(mapAttrsToList (host: ip: "${host}. IN A ${ip}") ns-hosts));
in { in {
@ -170,10 +171,21 @@ in {
enable = mkEnableOption "Enable master DNS services."; enable = mkEnableOption "Enable master DNS services.";
# FIXME: This should allow for AAAA addresses too... # FIXME: This should allow for AAAA addresses too...
dns-hosts = mkOption { nameservers = mkOption {
type = loaOf str; type = loaOf (submodule hostOpts);
description = "Map of domain nameserver FQDNs to IP."; description = "Map of domain nameserver FQDNs to IP.";
example = { "ns1.domain.com" = "1.1.1.1"; }; example = {
"ns1.domain.com" = {
ip-addresses = [ "1.1.1.1" ];
ipv6-addresses = [];
description = "my fancy dns server";
};
};
};
identity = mkOption {
type = str;
description = "The identity (CH TXT ID.SERVER) of this host.";
}; };
domains = mkOption { domains = mkOption {
@ -192,7 +204,7 @@ in {
config = mkIf cfg.enable { config = mkIf cfg.enable {
services.nsd = { services.nsd = {
enable = true; enable = true;
identity = "procul.informis.land"; identity = cfg.identity;
interfaces = cfg.listen-ips; interfaces = cfg.listen-ips;
zones = mapAttrs' (dom: dom-cfg: zones = mapAttrs' (dom: dom-cfg:
nameValuePair "${dom}." { nameValuePair "${dom}." {
@ -215,7 +227,8 @@ in {
$TTL 6h $TTL 6h
${nsRecords cfg.dns-hosts} ${nsRecords dom cfg.nameservers}
${join-lines (mapAttrsToList hostRecords cfg.nameservers)}
${dmarcRecord dom-cfg.dmarc-report-address} ${dmarcRecord dom-cfg.dmarc-report-address}

View File

@ -7,9 +7,6 @@ let
join-lines = concatStringsSep "\n"; join-lines = concatStringsSep "\n";
ip = import ../../lib/ip.nix { inherit lib; };
dns = import ../../lib/dns.nix { inherit lib; };
hostOpts = { hostname, ... }: { hostOpts = { hostname, ... }: {
options = { options = {
ip-address = mkOption { ip-address = mkOption {

View File

@ -4,8 +4,6 @@ with lib;
let let
cfg = config.fudo.vpn; cfg = config.fudo.vpn;
ip-util = import ../../lib/ip.nix { lib = lib; };
generate-pubkey-pkg = name: privkey: generate-pubkey-pkg = name: privkey:
pkgs.runCommand "wireguard-${name}-pubkey" { pkgs.runCommand "wireguard-${name}-pubkey" {
WIREGUARD_PRIVATE_KEY = privkey; WIREGUARD_PRIVATE_KEY = privkey;
@ -17,7 +15,7 @@ let
generate-client-config = privkey-file: server-pubkey: network: server-ip: listen-port: dns-servers: '' generate-client-config = privkey-file: server-pubkey: network: server-ip: listen-port: dns-servers: ''
[Interface] [Interface]
Address = ${ip-util.networkMinIp network} Address = ${ip.networkMinIp network}
PrivateKey = ${fileContents privkey-file} PrivateKey = ${fileContents privkey-file}
ListenPort = ${toString listen-port} ListenPort = ${toString listen-port}
DNS = ${concatStringsSep ", " dns-servers} DNS = ${concatStringsSep ", " dns-servers}
@ -86,8 +84,8 @@ in {
name = peer.name; name = peer.name;
privkey-path = peer.privkey-path; privkey-path = peer.privkey-path;
network-range = let network-range = let
base = ip-util.intToIpv4 base = ip.intToIpv4
((ip-util.ipv4ToInt (ip-util.getNetworkBase cfg.network)) + (i * 256)); ((ip.ipv4ToInt (ip.getNetworkBase cfg.network)) + (i * 256));
in "${base}/24"; in "${base}/24";
}) (mapAttrsToList (name: privkey-path: { }) (mapAttrsToList (name: privkey-path: {
name = name; name = name;

View File

@ -1,6 +1,6 @@
# Ref: https://learnxinyminutes.com/docs/nix/ # Ref: https://learnxinyminutes.com/docs/nix/
{ config, pkgs, ... }: { config, pkgs, lib, ... }:
{ {
imports = [ imports = [
@ -9,6 +9,12 @@
./config/local.nix ./config/local.nix
]; ];
lib = {
buildLisp = import ./lib/buildLisp.nix;
ip = import ./lib/ip.nix;
dns = import ./lib/dns.nix;
};
nixpkgs.config.allowUnfree = true; nixpkgs.config.allowUnfree = true;
security.acme.acceptTerms = true; security.acme.acceptTerms = true;

268
fudo/fudo.org.nix Normal file
View File

@ -0,0 +1,268 @@
{ config, ... }:
{
dnssec = true;
mx = ["mail.fudo.org"];
hosts = {
cisco = {
ip-addresses = [ "198.163.150.211" ];
description = "\"allbran\" \"converge\"";
};
cisco-int = {
ip-addresses = [ "10.73.77.10" ];
description = "\"fruitloops\" \"aironet\"";
};
cupid = {
ip-addresses = [ "208.38.36.100" ];
};
docker = {
ip-addresses = [ "208.81.3.126" ];
};
france = {
ip-addresses = [ "208.81.3.117" ];
ssh-fingerprints = [
"4 1 c95a198f504a589fc62893a95424b12f0b24732d"
"4 2 3e7dad879d6cab7f7fb6769e156d7988d0c01281618d03b793834eea2f09bc96"
"1 1 1b6d62dafae9ebc59169dfb4ef828582a5450d94"
"1 2 079e7a57873542541095bf3d2f97b7350bb457d027b423a6fb56f7f6aa84ac80"
];
};
frankfurt = {
ip-addresses = [ "208.81.3.120" ];
ipv6-addresses = [ "2605:e200:d200:1:5054:ff:fe8c:9738" ];
ssh-fingerprints = [
"2 1 4b9e4ed16a6b3fe6d41ed0f5cdeed853cc101e12"
"2 2 286ce32326874fe8aa15e3fd60b176b906ebd87306109f7c250d077db4ba85c5"
"3 1 3531dfd2f240ce0cd548b748462f78451df3f081"
"3 2 338809345ed38eb6808fd468067a74b2a8000fd8cc3bc016b9f977050bf1bba8"
"1 1 fb9ba707daa78243f8a8801f024fe790516b99a7"
"1 2 407f9692fedbd83449f0daf1cf795258b561a7e9c7e8072577cc84ffc0c84130"
];
};
germany = {
ip-addresses = [ "208.81.3.116" ];
ipv6-addresses = [ "2605:e200:d200:1:78d9:d8ff:fe0f:dd88" ];
ssh-fingerprints = [
"2 1 5609a728a91d7e52a6060ea7f3a7790005ba5e81"
"2 2 520a8eb3b9013837ac3ab4b28254f96b7718f9613e751a20dc488bf7d967b485"
"3 1 ee5b49888a36a34e7d4ee0d18626c82a16c2fcdf"
"3 2 d5e44cf2d85032638d49c030a9ccbff6638198c354efcb11bf173017d1257f49"
"1 1 9915d2515d7acdb38924d8829925113d5ce80b88"
"1 2 a7c866306e9661b8b568b2de282367c84065301d6228e58e57e6c4d3d33e3051"
];
};
hanover = {
ip-addresses = [ "208.81.1.130" ];
ipv6-addresses = [ "2605:e200:d100:1:5054:ff:fe61:ac8b" ];
};
localhost = {
ip-addresses = [ "127.0.0.1" ];
};
lsbb-gba = {
ip-addresses = [ "199.101.56.34" ];
};
lsbb-abg = {
ip-addresses = [ "199.101.56.38" ];
};
lsbb-hwd = {
ip-addresses = [ "199.101.56.106" ];
};
lsbb-hcl = {
ip-addresses = [ "199.101.56.110" ];
};
procul = {
ip-addresses = [ "172.86.179.18" ];
};
prunel = {
ip-addresses = [ "208.81.3.123" ];
};
mbix = {
ip-addresses = [ "208.81.7.146" ];
};
ns3-fudo = {
ip-addresses = [ "208.75.74.205" ];
};
ns3-dair = {
ip-addresses = [ "208.75.74.205" ];
};
ns4-fudo = {
ip-addresses = [ "208.75.75.157" ];
};
ns4-dair = {
ip-addresses = [ "208.75.75.157" ];
};
paris = {
ip-addresses = [ "208.81.3.125" ];
ipv6-addresses = [ "2605:e200:d200:1:5054:ff:fe67:d0c1" ];
ssh-fingerprints = [
"2 1 9fe9e689a36316831ffafffc22c85913748670a6"
"2 2 f2ce57bf470c907604b79b6ef031c928a64a81031e78892fd475bbcf65ae728b"
"3 1 5c56e93a20868886ffe76e1fab012989ce8e995f"
"3 2 af4f383cb349fc3b2496a0bf0911da3a09f98a6d4d2a3c81bb0fb23a45bde950"
"4 1 71a1d35c32b4445b98ce339696f155e1d4c39bd5"
"4 2 a9e4810a24bd52082c9bb2b1019a9de7d7983246fecb454dd8d918ac5a11af81"
"1 1 18e8dd7cac48f1ac6103ec21c279e339d8690be1"
"1 2 72e4aa05c733441da57c464e6540486f5306b6768d784dd97c666e16629d77a0"
];
};
probe = {
ip-addresses = [ "208.81.3.119" ];
};
tours = {
ip-addresses = [ "208.81.3.121" ];
ipv6-addresses = [ "2605:e200:d200:1:5054:ff:fe95:34e5" ];
ssh-fingerprints = [
"2 2 41cddf1457880c7e86fa3838eabdbbe7cf803f98998ed406319ba3e43036964c"
"3 1 89b72a740ef6ef7ad9aaf5fe2178d356cdc7ee5b"
"3 2 c39346def56817aaf4c64db5667ccc6aeb400ff1166125fe630b63b5eab0ef29"
"4 1 049b1e6ef1d338d35e97baf312d8a371a266b7d1"
"4 2 1a889e43148ea1ded9f8bc60799ccf1bc32cb084946c8815abed6cc31f212594"
"1 1 bae37560759ec8dba35755473fbb346f9dc4e333"
"1 2 3d0d5efe2da329ea19b191f227c3aaad45271c651717ec3315cda131e992bbcf"
];
};
};
default-host = "208.81.3.117";
srv-records = {
tcp = {
domain = [
{
host = "ns1.fudo.org";
port = 53;
}
{
host = "ns2.fudo.org";
port = 53;
}
{
host = "ns3.fudo.org";
port = 53;
}
{
host = "ns4.fudo.org";
port = 53;
}
];
ssh = [{
host = "france.fudo.org";
port = 22;
}];
smtp = [{
host = "mail.fudo.org";
port = 25;
}];
submission = [{
host = "mail.fudo.org";
port = 587;
}];
kerberos = [{
host = "france.fudo.org";
port = 88;
}];
imaps = [{
host = "mail.fudo.org";
port = 993;
}];
ldap = [{
host = "france.fudo.org";
port = 389;
}];
ldaps = [{
host = "france.fudo.org";
port = 636;
}];
pop3s = [{
host = "mail.fudo.org";
port = 995;
}];
http = [{
host = "wiki.fudo.org";
port = 80;
}];
https = [{
host = "wiki.fudo.org";
port = 80;
}];
xmpp-server = [{
host = "fudo.im";
port = 5269;
}];
xmpp-client = [{
host = "fudo.im";
port = 5222;
}];
};
udp = {
domain = [
{
host = "ns1.fudo.org";
port = 53;
}
{
host = "ns2.fudo.org";
port = 53;
}
{
host = "ns3.fudo.org";
port = 53;
}
{
host = "ns4.fudo.org";
port = 53;
}
];
kerberos = [{
host = "france.fudo.org";
port = 88;
}];
kerberos-master = [{
host = "france.fudo.org";
port = 88;
}];
kpasswd = [{
host = "france.fudo.org";
port = 464;
}];
xmpp-server = [{
host = "fudo.im";
port = 5269;
}];
};
};
aliases = {
pop = "mail.fudo.org.";
smtp = "mail.fudo.org.";
imap = "mail.fudo.org.";
webmail = "france.fudo.org.";
archiva = "france.fudo.org.";
auth = "france.fudo.org.";
backplane = "france.fudo.org.";
chat = "france.fudo.org.";
de = "germany.fudo.org.";
fr = "france.fudo.org.";
git = "france.fudo.org.";
metrics = "france.fudo.org.";
minecraft = "france.fudo.org.";
monitor = "france.fudo.org.";
user = "paris.fudo.org.";
u = "user.fudo.org.";
w = "www.fudo.org.";
ww = "www.fudo.org.";
www = "hanover.fudo.org.";
wiki = "hanover.fudo.org.";
};
extra-dns-records = [
''_kerberos IN TXT "FUDO.ORG"''
''@ IN TXT "v=spf1 mx ip4:208.81.3.112/28 ip6:2605:e200:d200::1/48 -all"''
''@ IN SPF "v=spf1 mx ip4:208.81.3.112/28 ip6:2605:e200:d200::1/48 -all"''
];
dmarc-report-address = "dmarc-report@fudo.org";
}

View File

@ -391,7 +391,8 @@
uid = 10108; uid = 10108;
group = "selby"; group = "selby";
common-name = "Lauren Hotel"; common-name = "Lauren Hotel";
hashed-password = "{SSHA}DKnhrycmXSu4HKWFPeBXA9xvZ0ytgXIpZA10tg=="; hashed-password = "{SSHA}1q/MC5LKROlIT1nDrKrMvcFAXFtcQXIR";
# hashed-password = "{SSHA}DKnhrycmXSu4HKWFPeBXA9xvZ0ytgXIpZA10tg==";
}; };
# Used to send alerts from grafana # Used to send alerts from grafana

View File

@ -186,22 +186,44 @@ in {
}; };
}; };
# fudo.dns = { fudo.dns = {
# enable = true; enable = true;
# dns-hosts = { identity = "france.fudo.org";
# "ns1.fudo.org" = host_ipv4;
# "ns2.fudo.org" = "";
# };
# listen-ips = [host_ipv4]; nameservers = {
ns1 = {
ip-addresses = [ "208.81.3.117" ];
ipv6-addresses = [ "2605:e200:d200:1:5054:ff:fe8c:9738" ];
description = "Nameserver 1, france, in Winnipeg, MB, CA";
rp = "reaper reaper.rp";
};
ns2 = {
ip-addresses = [ "209.117.102.102" ];
ipv6-addresses = [ "2001:470:1f16:40::2" ];
description = "Nameserver 2, musashi, in Winnipeg, MB, CA";
rp = "reaper reaper.rp";
};
ns3 = {
ip-addresses = [ "104.131.53.95" ];
ipv6-addresses = [ "2604:a880:800:10::8:7001" ];
description = "Nameserver 3, ns2.henchmman21.net, in New York City, NY, US";
rp = "reaper reaper.rp";
};
ns4 = {
ip-addresses = [ "204.42.254.5" ];
ipv6-addresses = [ "2001:418:3f4::5" ];
description = "Nameserver 4, puck.nether.net, in Chicago, IL, US";
rp = "reaper reaper.rp";
};
};
# domains = { listen-ips = [host_ipv4];
# "selby.ca" = import ../fudo.org/selby.ca.nix {
# inherit host_ipv4 config; domains = {
# }; "fudo.org" = import ../fudo/fudo.org.nix { inherit config; };
# }; };
# }; };
# Not all users need access to france; don't allow LDAP-user access. # Not all users need access to france; don't allow LDAP-user access.
fudo.authentication.enable = false; fudo.authentication.enable = false;
@ -271,7 +293,7 @@ in {
fudo.mail-server = import ../fudo/email.nix { inherit config; } // { fudo.mail-server = import ../fudo/email.nix { inherit config; } // {
enableContainer = true; enableContainer = true;
# debug = true; debug = true;
monitoring = true; monitoring = true;
hostname = mail-hostname; hostname = mail-hostname;

259
lib/buildLisp.nix Normal file
View File

@ -0,0 +1,259 @@
# buildLisp provides Nix functions to build Common Lisp packages,
# targeting SBCL.
#
# buildLisp is designed to enforce conventions and do away with the
# free-for-all of existing Lisp build systems.
{ pkgs ? import <nixpkgs> {}, ... }:
let
inherit (builtins) map elemAt match filter;
inherit (pkgs) lib runCommandNoCC makeWrapper writeText writeShellScriptBin sbcl;
#
# Internal helper definitions
#
# 'genLoadLisp' generates Lisp code that instructs SBCL to load all
# the provided Lisp libraries.
genLoadLisp = deps: lib.concatStringsSep "\n"
(map (lib: "(load \"${lib}/${lib.lispName}.fasl\")") (allDeps deps));
# 'genCompileLisp' generates a Lisp file that instructs SBCL to
# compile the provided list of Lisp source files to $out.
genCompileLisp = srcs: deps: writeText "compile.lisp" ''
;; This file compiles the specified sources into the Nix build
;; directory, creating one FASL file for each source.
(require 'sb-posix)
${genLoadLisp deps}
(defun nix-compile-lisp (file srcfile)
(let ((outfile (make-pathname :type "fasl"
:directory (or (sb-posix:getenv "NIX_BUILD_TOP")
(error "not running in a Nix build"))
:name (substitute #\- #\/ srcfile))))
(multiple-value-bind (_outfile _warnings-p failure-p)
(compile-file srcfile :output-file outfile)
(if failure-p (sb-posix:exit 1)
(progn
;; For the case of multiple files belonging to the same
;; library being compiled, load them in order:
(load outfile)
;; Write them to the FASL list in the same order:
(format file "cat ~a~%" (namestring outfile)))))))
(let ((*compile-verbose* t)
;; FASL files are compiled into the working directory of the
;; build and *then* moved to the correct out location.
(pwd (sb-posix:getcwd)))
(with-open-file (file "cat_fasls"
:direction :output
:if-does-not-exist :create)
;; These forms were inserted by the Nix build:
${
lib.concatStringsSep "\n" (map (src: "(nix-compile-lisp file \"${src}\")") srcs)
}
))
'';
# 'genTestLisp' generates a Lisp file that loads all sources and deps and
# executes expression
genTestLisp = name: srcs: deps: expression: writeText "${name}.lisp" ''
;; Dependencies
${genLoadLisp deps}
;; Sources
${lib.concatStringsSep "\n" (map (src: "(load \"${src}\")") srcs)}
;; Test expression
(unless ${expression}
(exit :code 1))
'';
# 'dependsOn' determines whether Lisp library 'b' depends on 'a'.
dependsOn = a: b: builtins.elem a b.lispDeps;
# 'allDeps' flattens the list of dependencies (and their
# dependencies) into one ordered list of unique deps.
allDeps = deps: (lib.toposort dependsOn (lib.unique (
lib.flatten (deps ++ (map (d: d.lispDeps) deps))
))).result;
# 'allNative' extracts all native dependencies of a dependency list
# to ensure that library load paths are set correctly during all
# compilations and program assembly.
allNative = native: deps: lib.unique (
lib.flatten (native ++ (map (d: d.lispNativeDeps) deps))
);
# 'genDumpLisp' generates a Lisp file that instructs SBCL to dump
# the currently loaded image as an executable to $out/bin/$name.
#
# TODO(tazjin): Compression is currently unsupported because the
# SBCL in nixpkgs is, by default, not compiled with zlib support.
genDumpLisp = name: main: deps: writeText "dump.lisp" ''
(require 'sb-posix)
${genLoadLisp deps}
(let* ((bindir (concatenate 'string (sb-posix:getenv "out") "/bin"))
(outpath (make-pathname :name "${name}"
:directory bindir)))
(save-lisp-and-die outpath
:executable t
:toplevel (function ${main})
:purify t))
;;
'';
# Add an `overrideLisp` attribute to a function result that works
# similar to `overrideAttrs`, but is used specifically for the
# arguments passed to Lisp builders.
makeOverridable = f: orig: (f orig) // {
overrideLisp = new: makeOverridable f (orig // (new orig));
};
# 'testSuite' builds a Common Lisp test suite that loads all of srcs and deps,
# and then executes expression to check its result
testSuite = { name, expression, srcs, deps ? [], native ? [] }:
let
lispNativeDeps = allNative native deps;
lispDeps = allDeps deps;
in runCommandNoCC name {
LD_LIBRARY_PATH = lib.makeLibraryPath lispNativeDeps;
LANG = "C.UTF-8";
} ''
echo "Running test suite ${name}"
${sbcl}/bin/sbcl --script ${genTestLisp name srcs deps expression} \
| tee $out
echo "Test suite ${name} succeeded"
'';
#
# Public API functions
#
# 'library' builds a list of Common Lisp files into a single FASL
# which can then be loaded into SBCL.
library =
{ name
, srcs
, deps ? []
, native ? []
, tests ? null
}:
let
lispNativeDeps = (allNative native deps);
lispDeps = allDeps deps;
testDrv = if ! isNull tests
then testSuite {
name = tests.name or "${name}-test";
srcs = srcs ++ (tests.srcs or []);
deps = deps ++ (tests.deps or []);
expression = tests.expression;
}
else null;
in lib.fix (self: runCommandNoCC "${name}-cllib" {
LD_LIBRARY_PATH = lib.makeLibraryPath lispNativeDeps;
LANG = "C.UTF-8";
} ''
${if ! isNull testDrv
then "echo 'Test ${testDrv} succeeded'"
else "echo 'No tests run'"}
${sbcl}/bin/sbcl --script ${genCompileLisp srcs lispDeps}
echo "Compilation finished, assembling FASL files"
# FASL files can be combined by simply concatenating them
# together, but it needs to be in the compilation order.
mkdir $out
chmod +x cat_fasls
./cat_fasls > $out/${name}.fasl
'' // {
inherit lispNativeDeps lispDeps;
lispName = name;
lispBinary = false;
tests = testDrv;
sbcl = sbclWith [ self ];
});
# 'program' creates an executable containing a dumped image of the
# specified sources and dependencies.
program =
{ name
, main ? "${name}:main"
, srcs
, deps ? []
, native ? []
, tests ? null
}:
let
lispDeps = allDeps deps;
libPath = lib.makeLibraryPath (allNative native lispDeps);
selfLib = library {
inherit name srcs native;
deps = lispDeps;
};
testDrv = if ! isNull tests
then testSuite {
name = tests.name or "${name}-test";
srcs =
(
srcs ++ (tests.srcs or []));
deps = deps ++ (tests.deps or []);
expression = tests.expression;
}
else null;
in lib.fix (self: runCommandNoCC "${name}" {
nativeBuildInputs = [ makeWrapper ];
LD_LIBRARY_PATH = libPath;
LANG = "C.UTF-8";
} ''
${if ! isNull testDrv
then "echo 'Test ${testDrv} succeeded'"
else ""}
mkdir -p $out/bin
${sbcl}/bin/sbcl --script ${
genDumpLisp name main ([ selfLib ] ++ lispDeps)
}
wrapProgram $out/bin/${name} --prefix LD_LIBRARY_PATH : "${libPath}"
'' // {
lispName = name;
lispDeps = [ selfLib ] ++ (tests.deps or []);
lispNativeDeps = native;
lispBinary = true;
tests = testDrv;
sbcl = sbclWith [ self ];
});
# 'bundled' creates a "library" that calls 'require' on a built-in
# package, such as any of SBCL's sb-* packages.
bundled = name: (makeOverridable library) {
inherit name;
srcs = lib.singleton (builtins.toFile "${name}.lisp" "(require '${name})");
};
# 'sbclWith' creates an image with the specified libraries /
# programs loaded.
sbclWith = deps:
let lispDeps = filter (d: !d.lispBinary) (allDeps deps);
in writeShellScriptBin "sbcl" ''
export LD_LIBRARY_PATH="${lib.makeLibraryPath (allNative [] lispDeps)}"
export LANG="C.UTF-8"
exec ${sbcl}/bin/sbcl ${lib.optionalString (deps != []) "--load ${writeText "load.lisp" (genLoadLisp lispDeps)}"} $@
'';
in {
library = makeOverridable library;
program = makeOverridable program;
sbclWith = makeOverridable sbclWith;
bundled = makeOverridable bundled;
}

View File

@ -1,6 +1,6 @@
{ lib }: { pkgs ? import <nixpkgs> {}, ... }:
with lib; with pkgs.lib;
let let
join-lines = concatStringsSep "\n"; join-lines = concatStringsSep "\n";

View File

@ -1,45 +1,32 @@
{ lib }: { pkgs ? import <nixpkgs> {}, ... }:
with lib; with pkgs.lib;
let let
joinString = lib.concatStringsSep; joinString = concatStringsSep;
pow = x: e: if (e == 0) then 1 else x * (pow x (e - 1)); pow = x: e: if (e == 0) then 1 else x * (pow x (e - 1));
in rec {
generateNBits = n: let generateNBits = n: let
helper = n: c: if (c == n) then pow 2 c else (pow 2 c) + (helper n (c + 1)); helper = n: c: if (c == n) then pow 2 c else (pow 2 c) + (helper n (c + 1));
in if (n <= 0) then throw "Can't generate 0 or fewer bits" else helper (n - 1) 0; in if (n <= 0) then throw "Can't generate 0 or fewer bits" else helper (n - 1) 0;
rightPadBits = int: bits: bitOr int (generateNBits bits);
reverseIpv4 = ip: joinString "." (reverseList (splitString "." ip)); reverseIpv4 = ip: joinString "." (reverseList (splitString "." ip));
intToBinaryList = int: let intToBinaryList = int: let
helper = int: cur: let helper = int: cur: let
curExp = pow 2 cur; curExp = pow 2 cur;
in if (curExp > int) then in if (curExp > int) then
[] []
else else
[(if ((bitAnd curExp int) > 0) then 1 else 0)] ++ (helper int (cur + 1)); [(if ((bitAnd curExp int) > 0) then 1 else 0)] ++ (helper int (cur + 1));
in reverseList (helper int 0); in reverseList (helper int 0);
leftShift = int: n: int * (pow 2 n); leftShift = int: n: int * (pow 2 n);
rightShift = int: n: int / (pow 2 n); rightShift = int: n: int / (pow 2 n);
ipv4ToInt = ip: let
els = map toInt (reverseList (splitString "." ip));
in foldr (a: b: a + b) 0 (imap0 (i: el: (leftShift el (i * 8))) els);
intToIpv4 = int: joinString "." (map (i: toString (bitAnd (rightShift int (i * 8)) 255)) [ 3 2 1 0 ]);
rightPadBits = int: bits: bitOr int (generateNBits bits);
maskFromV32Network = network: let
fullMask = ipv4ToInt "255.255.255.255";
insignificantBits = 32 - (getNetworkMask network);
in intToIpv4 (leftShift (rightShift fullMask insignificantBits) insignificantBits);
getNetworkMask = network: toInt (elemAt (splitString "/" network) 1); getNetworkMask = network: toInt (elemAt (splitString "/" network) 1);
getNetworkBase = network: let getNetworkBase = network: let
@ -47,10 +34,30 @@ in rec {
insignificantBits = 32 - (getNetworkMask network); insignificantBits = 32 - (getNetworkMask network);
in intToIpv4 (leftShift (rightShift (ipv4ToInt ip) insignificantBits) insignificantBits); in intToIpv4 (leftShift (rightShift (ipv4ToInt ip) insignificantBits) insignificantBits);
in rec {
ipv4ToInt = ip: let
els = map toInt (reverseList (splitString "." ip));
in foldr (a: b: a + b) 0 (imap0 (i: el: (leftShift el (i * 8))) els);
intToIpv4 = int: joinString "." (map (i: toString (bitAnd (rightShift int (i * 8)) 255)) [ 3 2 1 0 ]);
maskFromV32Network = network: let
fullMask = ipv4ToInt "255.255.255.255";
insignificantBits = 32 - (getNetworkMask network);
in intToIpv4 (leftShift (rightShift fullMask insignificantBits) insignificantBits);
networkMinIp = network: intToIpv4 (1 + (ipv4ToInt (getNetworkBase network))); networkMinIp = network: intToIpv4 (1 + (ipv4ToInt (getNetworkBase network)));
networkMaxIp = network: intToIpv4 (rightPadBits (ipv4ToInt (getNetworkBase network)) (32 - (getNetworkMask network))); networkMaxIp = network: intToIpv4 (rightPadBits (ipv4ToInt (getNetworkBase network)) (32 - (getNetworkMask network)));
# To avoid broadcast IP... # To avoid broadcast IP...
networkMaxButOneIp = network: intToIpv4 ((rightPadBits (ipv4ToInt (getNetworkBase network)) (32 - (getNetworkMask network))) - 1); networkMaxButOneIp = network: intToIpv4 ((rightPadBits (ipv4ToInt (getNetworkBase network)) (32 - (getNetworkMask network))) - 1);
ipv4OnNetwork = ip: network: let
ip-int = ipv4ToInt ip;
net-min = networkMinIp network;
net-max = networkMaxIp network;
in
(ip-int >= networkMinIp) && (ip-int <= networkMaxIp);
} }