diff options
-rw-r--r-- | .envrc | 2 | ||||
-rw-r--r-- | Biz/Dev/configuration.nix | 18 | ||||
-rw-r--r-- | Biz/buildOS.nix | 56 | ||||
-rw-r--r-- | Hero/App.hs | 2 | ||||
-rw-r--r-- | Hero/Prod.nix | 8 | ||||
-rw-r--r-- | Hero/Server.hs | 2 | ||||
-rw-r--r-- | Que/Prod.nix | 10 | ||||
-rw-r--r-- | README.md | 3 | ||||
-rw-r--r-- | default.nix | 143 | ||||
-rw-r--r-- | nix/build.nix (renamed from biz.nix) | 43 | ||||
-rw-r--r-- | nix/deps.nix (renamed from deps.nix) | 0 | ||||
-rw-r--r-- | nix/nixpkgs.nix | 10 | ||||
-rw-r--r-- | nix/overlay.nix (renamed from overlay.nix) | 0 | ||||
-rw-r--r-- | nix/sources.json | 26 | ||||
-rw-r--r-- | nix/sources.nix | 134 | ||||
-rw-r--r-- | nixpkgs.nix | 5 | ||||
-rw-r--r-- | shell.nix | 9 |
17 files changed, 288 insertions, 183 deletions
@@ -1,5 +1,7 @@ PATH_add $PWD export BIZ_ROOT=$PWD +export HERO_PORT=3000 +export HERO_CLIENT=$BIZ_ROOT/_bild/Hero.Client/static if type lorri &>/dev/null then eval "$(lorri direnv)" diff --git a/Biz/Dev/configuration.nix b/Biz/Dev/configuration.nix index 4a8839e..e822837 100644 --- a/Biz/Dev/configuration.nix +++ b/Biz/Dev/configuration.nix @@ -190,12 +190,18 @@ in { nixos.enable = true; }; - # Since this is the dev machine, we can turn these on at the expense of extra - # disk space. - nix.extraOptions = '' - keep-outputs = true - keep-derivations = true - ''; + + nix = { + # 1 job * 2 cores = 2 maximum cores used at any one time + maxJobs = 1; + buildCores = 2; + # Since this is the dev machine, we can turn these on at the expense + # of extra disk space. + extraOptions = '' + keep-outputs = true + keep-derivations = true + ''; + }; # This value determines the NixOS release with which your system is to be # compatible, in order to avoid breaking some software such as database diff --git a/Biz/buildOS.nix b/Biz/buildOS.nix deleted file mode 100644 index 9e6c2f2..0000000 --- a/Biz/buildOS.nix +++ /dev/null @@ -1,56 +0,0 @@ -nixos: -{ ipAddress ? null -, enableVpn ? false -, vpnConnectTo ? "" -, vpnRsaPrivateKeyFile ? null -, vpnEd25519PrivateKeyFile ? null -, deps ? {} # an attrset overlayed to pkgs -, configuration # see: configuration.nix(5) -}: -# assert enableVpn -> builtins.isString ipAddress; -# assert enableVpn -> builtins.isString vpnRsaPrivateKeyFile; -# assert enableVpn -> builtins.isString vpnEd25519PrivateKeyFile; -let - vpnExtraConfig = if enableVpn then '' - ConnectTo = ${vpnConnectTo} - Ed25519PrivateKeyFile = "${vpnEd25519PrivateKeyFile}" - PrivateKeyFile = "${vpnRsaPrivateKeyFile}" - '' else ""; - overlay = self: super: deps; - defaults = { - boot.cleanTmpDir = true; - #networking.interfaces.simatime-vpn = [{ ipv4.address = ipAddress; }]; - networking.firewall.allowPing = true; - nix.binaryCaches = [ "https://cache.nixos.org" ]; - nix.gc.automatic = true; - nix.gc.dates = "Sunday 02:15"; - nix.maxJobs = 1; # "auto"; - nix.optimise.automatic = true; - nix.optimise.dates = [ "Sunday 02:30" ]; - nixpkgs.overlays = [ overlay ]; - programs.mosh.enable = true; - programs.mosh.withUtempter = true; - security.acme.email = "ben@bsima.me"; - security.acme.acceptTerms = true; - security.sudo.wheelNeedsPassword = false; - services.clamav.daemon.enable = true; # security - services.clamav.updater.enable = true; # security - services.fail2ban.enable = true; # security - services.openssh.enable = true; - services.openssh.openFirewall = true; - services.openssh.forwardX11 = true; - services.openssh.passwordAuthentication = false; - #services.tinc.networks.simatime-vpn.extraConfig = vpnExtraConfig; - #services.tinc.networks.simatime-vpn.debugLevel = 3; - #services.tinc.networks.simatime-vpn.interfaceType = "tap"; - #services.tinc.networks.simatime-vpn.hosts = import ./vpnHosts.nix; - system.autoUpgrade.enable = false; # 'true' breaks our nixpkgs pin - }; - os = nixos { - system = "x86_64-linux"; - configuration = (defaults // configuration); - }; -in { - system = os.system; - vm = os.vm; -} diff --git a/Hero/App.hs b/Hero/App.hs index 39cfa03..a254d80 100644 --- a/Hero/App.hs +++ b/Hero/App.hs @@ -284,7 +284,7 @@ data ComicReaderState deriving (Show, Eq) findComic :: ComicId -> [Comic] -> Maybe Comic -findComic id = List.find . \c -> comicId c == id +findComic id = List.find (\c -> comicId c == id) -- | Main model for the app. -- diff --git a/Hero/Prod.nix b/Hero/Prod.nix index 10650ee..7da2f72 100644 --- a/Hero/Prod.nix +++ b/Hero/Prod.nix @@ -3,14 +3,6 @@ imports = [ <nixpkgs/nixos/modules/profiles/qemu-guest.nix> ]; boot.loader.grub.device = "/dev/vda"; fileSystems."/" = { device = "/dev/vda1"; fsType = "ext4"; }; - - services.herocomics = { - enable = true; - port = 3000; - server = pkgs.herocomics-server; - client = pkgs.herocomics-client; - }; - networking = { firewall.allowedTCPPorts = [ 22 80 443 ]; nameservers = [ diff --git a/Hero/Server.hs b/Hero/Server.hs index bf92f88..4dc80f5 100644 --- a/Hero/Server.hs +++ b/Hero/Server.hs @@ -77,7 +77,7 @@ main = bracket startup shutdown $ uncurry Warp.run Right c -> do db <- Database.dummy say "hero" - say $ "port: " ++ show $ heroPort c + say $ "port: " ++ show (heroPort c) say $ "client: " ++ heroClient c let waiapp = app db c return (heroPort c, waiapp) diff --git a/Que/Prod.nix b/Que/Prod.nix index 97749c8..57a386a 100644 --- a/Que/Prod.nix +++ b/Que/Prod.nix @@ -4,16 +4,6 @@ boot.loader.grub.device = "/dev/vda"; fileSystems."/" = { device = "/dev/vda1"; fsType = "ext4"; }; networking.firewall.allowedTCPPorts = [ 22 80 443 ]; - services.que-server = { - enable = true; - port = 80; - package = pkgs.que-server; - }; - services.que-website = { - enable = true; - namespace = "_"; - package = pkgs.que-website; - }; networking = { nameservers = [ "67.207.67.2" @@ -34,7 +34,8 @@ application. Development aspects should be localized to their sub-namespaces as much as possible. Only after sufficient iteration such that interfaces are solidified and functionality is well-established should some code be -promoted up the namespace hierarchy. +promoted up the namespace hierarchy. The one special namespace/directory +is `nix` which has all of our build rules. Boundaries and interfaces between namespaces should be small and well-defined. Likewise, the functionality and purpose of a particular diff --git a/default.nix b/default.nix index 2d7fb8f..de30805 100644 --- a/default.nix +++ b/default.nix @@ -1,10 +1,6 @@ let - nixpkgs-tar = builtins.fetchTarball (import ./nixpkgs.nix); - overlay = import ./overlay.nix; - bizpkgs = import "${nixpkgs-tar}" { overlays = [ overlay ]; }; - nixos = import "${nixpkgs-tar}/nixos"; - biz = import ./biz.nix { nixpkgs = bizpkgs; }; - buildOS = import ./Biz/buildOS.nix nixos; + nixpkgs = import ./nix/nixpkgs.nix; + build = import ./nix/build.nix { inherit nixpkgs; }; nixos-mailserver = let ver = "v2.3.0"; in builtins.fetchTarball { url = "https://gitlab.com/simple-nixos-mailserver/nixos-mailserver/-/archive/${ver}/nixos-mailserver-${ver}.tar.gz"; sha256 = "0lpz08qviccvpfws2nm83n7m2r8add2wvfg9bljx9yxx8107r919"; @@ -13,91 +9,84 @@ in rec { # Cloud infrastructure, always online. Mostly for messaging-related # stuff. # - Biz.Cloud = buildOS { - enableVpn = true; - ipAddress = "159.89.128.69"; - configuration = { - imports = [ - ./Biz/packages.nix - ./Biz/users.nix - ./Biz/Cloud/chat.nix - ./Biz/Cloud/git.nix - ./Biz/Cloud/hardware.nix - ./Biz/Cloud/mail.nix - ./Biz/Cloud/networking.nix - ./Biz/Cloud/web.nix - ./Biz/Cloud/znc.nix - nixos-mailserver - ]; - networking.hostName = "simatime"; - networking.domain = "simatime.com"; - }; + Biz.Cloud = build.os { + imports = [ + ./Biz/packages.nix + ./Biz/users.nix + ./Biz/Cloud/chat.nix + ./Biz/Cloud/git.nix + ./Biz/Cloud/hardware.nix + ./Biz/Cloud/mail.nix + ./Biz/Cloud/networking.nix + ./Biz/Cloud/web.nix + ./Biz/Cloud/znc.nix + nixos-mailserver + ]; + networking.hostName = "simatime"; + networking.domain = "simatime.com"; }; # Dev machine for work and building stuff. # - Biz.Dev = buildOS { - enableVpn = true; - ipAddress = "73.222.221.63"; - deps = { - wemux = bizpkgs.wemux; - }; - configuration = { - imports = [ - ./Biz/packages.nix - ./Biz/users.nix - ./Biz/Dev/configuration.nix - ./Biz/Dev/hardware.nix - ]; - networking.hostName = "lithium"; - networking.domain = "dev.simatime.com"; - }; + Biz.Dev = build.os { + imports = [ + ./Biz/packages.nix + ./Biz/users.nix + ./Biz/Dev/configuration.nix + ./Biz/Dev/hardware.nix + ]; + networking.hostName = "lithium"; + networking.domain = "dev.simatime.com"; }; # The production server for que.run # - Que.Prod = buildOS { - deps = { - que-server = Que.Server; - que-website = Que.Website; + Que.Prod = build.os { + imports = [ + ./Biz/packages.nix + ./Biz/users.nix + ./Que/Server.nix + ./Que/Website.nix + ./Que/Prod.nix + ]; + networking.hostName = "prod-que"; + networking.domain = "que.run"; + services.que-server = { + enable = true; + port = 80; + package = Que.Server; }; - configuration = { - imports = [ - ./Biz/packages.nix - ./Biz/users.nix - ./Que/Server.nix - ./Que/Website.nix - ./Que/Prod.nix - ]; - networking.hostName = "prod-que"; - networking.domain = "que.run"; + services.que-website = { + enable = true; + namespace = "_"; + package = Que.Website; }; }; # Production server for herocomics.app - Hero.Prod = buildOS { - deps = { - herocomics-server = Hero.Server; - herocomics-client = Hero.Client; - }; - configuration = { - imports = [ - ./Biz/packages.nix - ./Biz/users.nix - ./Hero/Service.nix - ./Hero/Prod.nix - ]; - networking.hostName = "prod-herocomics"; - networking.domain = "herocomcis.app"; + Hero.Prod = build.os { + imports = [ + ./Biz/packages.nix + ./Biz/users.nix + ./Hero/Service.nix + ./Hero/Prod.nix + ]; + networking.hostName = "prod-herocomics"; + networking.domain = "herocomcis.app"; + services.herocomics = { + enable = true; + port = 3000; + server = Hero.Server; + client = Hero.Client; }; }; # Haskell targets # - Biz.Ibb.Server = biz.buildGhc Biz/Ibb/Server.hs; - Biz.Ibb.Client = biz.buildGhcjs Biz/Ibb/Client.hs; - Hero.Server = biz.buildGhc Hero/Server.hs; - Hero.Client = biz.buildGhcjs Hero/Client.hs; - Que.Server = biz.buildGhc ./Que/Server.hs; - Que.Website = biz.buildGhc ./Que/Website.hs; + Biz.Ibb.Server = build.ghc Biz/Ibb/Server.hs; + Biz.Ibb.Client = build.ghcjs Biz/Ibb/Client.hs; + Hero.Server = build.ghc Hero/Server.hs; + Hero.Client = build.ghcjs Hero/Client.hs; + Que.Server = build.ghc ./Que/Server.hs; + Que.Website = build.ghc ./Que/Website.hs; # Development environment - repl = biz.globalGhc; + repl = build.env; # Fall through to any of our overlay packages - inherit bizpkgs; + inherit nixpkgs; } @@ -1,18 +1,17 @@ { nixpkgs }: with nixpkgs; -with nixpkgs.lib; let # provided by .envrc root = builtins.getEnv "BIZ_ROOT"; # general functions to put in a lib - lines = s: strings.splitString "\n" s; + lines = s: lib.strings.splitString "\n" s; removeNull = ls: builtins.filter (x: x != null) ls; depsToPackageSet = packageSet: deps: - attrsets.attrVals deps packageSet; + lib.attrsets.attrVals deps packageSet; # returns true if a is a subset of b, where a and b are attrsets subset = a: b: builtins.all @@ -30,11 +29,11 @@ let # file contents content = builtins.readFile main; # search for the ': exe' declaration - exe = builtins.head (lists.flatten (removeNull + exe = builtins.head (lib.lists.flatten (removeNull (map (builtins.match "^-- : exe ([[:alnum:]._-]*)$") (lines content)))); # collect all of the ': dep' declarations - deps = lists.flatten (removeNull + deps = lib.lists.flatten (removeNull (map (builtins.match "^-- : dep ([[:alnum:]._-]*)$") (lines content))); }; @@ -50,13 +49,13 @@ let ghc_ = mkGhc pkgs.haskell.packages.ghc865.ghcWithHoogle; ghcjs_ = mkGhc pkgs.haskell.packages.ghcjs.ghcWithPackages; in { - buildGhc = main: + ghc = main: let data = analyze main; ghc = ghc_ data.deps; in stdenv.mkDerivation { name = data.module; - src = ./.; + src = ../.; nativeBuildInputs = [ ghc ]; strictDeps = true; buildPhase = '' @@ -71,13 +70,13 @@ in { installPhase = "exit 0"; } // { env = ghc; }; - buildGhcjs = main: + ghcjs = main: let data = analyze main; ghcjs = ghcjs_ data.deps; in stdenv.mkDerivation { name = data.module; - src = ./.; + src = ../.; nativeBuildInputs = [ ghcjs ]; strictDeps = true; buildPhase = '' @@ -94,5 +93,29 @@ in { installPhase = "exit 0"; } // { env = ghcjs; }; - globalGhc = ghc_ allDeps; + env = ghc_ allDeps; + + os = cfg: (nixos (args: lib.attrsets.recursiveUpdate cfg { + boot.cleanTmpDir = true; + networking.firewall.allowPing = true; + nix.binaryCaches = [ "https://cache.nixos.org" ]; + nix.gc.automatic = true; + nix.gc.dates = "Sunday 02:15"; + nix.optimise.automatic = true; + nix.optimise.dates = [ "Sunday 02:30" ]; + nixpkgs.overlays = overlays; + programs.mosh.enable = true; + programs.mosh.withUtempter = true; + security.acme.email = "ben@bsima.me"; + security.acme.acceptTerms = true; + security.sudo.wheelNeedsPassword = false; + services.clamav.daemon.enable = true; # security + services.clamav.updater.enable = true; # security + services.fail2ban.enable = true; # security + services.openssh.enable = true; + services.openssh.openFirewall = true; + services.openssh.forwardX11 = true; + services.openssh.passwordAuthentication = false; + system.autoUpgrade.enable = false; # 'true' breaks our nixpkgs pin + })).toplevel; } diff --git a/nix/nixpkgs.nix b/nix/nixpkgs.nix new file mode 100644 index 0000000..246b8a8 --- /dev/null +++ b/nix/nixpkgs.nix @@ -0,0 +1,10 @@ +let + sources = import ./sources.nix; + nixpkgs = import sources.nixpkgs { + system = "x86_64-linux"; + overlays = [ + (_: _: { niv = import sources.niv {}; }) + (import ./overlay.nix) + ]; + }; +in nixpkgs diff --git a/overlay.nix b/nix/overlay.nix index dcadf34..dcadf34 100644 --- a/overlay.nix +++ b/nix/overlay.nix diff --git a/nix/sources.json b/nix/sources.json new file mode 100644 index 0000000..841f308 --- /dev/null +++ b/nix/sources.json @@ -0,0 +1,26 @@ +{ + "niv": { + "branch": "master", + "description": "Easy dependency management for Nix projects", + "homepage": "https://github.com/nmattia/niv", + "owner": "nmattia", + "repo": "niv", + "rev": "f73bf8d584148677b01859677a63191c31911eae", + "sha256": "0jlmrx633jvqrqlyhlzpvdrnim128gc81q5psz2lpp2af8p8q9qs", + "type": "tarball", + "url": "https://github.com/nmattia/niv/archive/f73bf8d584148677b01859677a63191c31911eae.tar.gz", + "url_template": "https://github.com/<owner>/<repo>/archive/<rev>.tar.gz" + }, + "nixpkgs": { + "branch": "nixos-19.09", + "description": "Nix Packages collection", + "homepage": "https://github.com/NixOS/nixpkgs", + "owner": "NixOS", + "repo": "nixpkgs", + "rev": "b0c285807d6a9f1b7562ec417c24fa1a30ecc31a", + "sha256": "0waapr7aqz0h1fy1fqlx981ygllh91qx9sz1l2j2h59s46cdircl", + "type": "tarball", + "url": "https://github.com/NixOS/nixpkgs/archive/b0c285807d6a9f1b7562ec417c24fa1a30ecc31a.tar.gz", + "url_template": "https://github.com/<owner>/<repo>/archive/<rev>.tar.gz" + } +} diff --git a/nix/sources.nix b/nix/sources.nix new file mode 100644 index 0000000..8a725cb --- /dev/null +++ b/nix/sources.nix @@ -0,0 +1,134 @@ +# This file has been generated by Niv. + +let + + # + # The fetchers. fetch_<type> fetches specs of type <type>. + # + + fetch_file = pkgs: spec: + if spec.builtin or true then + builtins_fetchurl { inherit (spec) url sha256; } + else + pkgs.fetchurl { inherit (spec) url sha256; }; + + fetch_tarball = pkgs: spec: + if spec.builtin or true then + builtins_fetchTarball { inherit (spec) url sha256; } + else + pkgs.fetchzip { inherit (spec) url sha256; }; + + fetch_git = spec: + builtins.fetchGit { url = spec.repo; inherit (spec) rev ref; }; + + fetch_builtin-tarball = spec: + builtins.trace + '' + WARNING: + The niv type "builtin-tarball" will soon be deprecated. You should + instead use `builtin = true`. + + $ niv modify <package> -a type=tarball -a builtin=true + '' + builtins_fetchTarball { inherit (spec) url sha256; }; + + fetch_builtin-url = spec: + builtins.trace + '' + WARNING: + The niv type "builtin-url" will soon be deprecated. You should + instead use `builtin = true`. + + $ niv modify <package> -a type=file -a builtin=true + '' + (builtins_fetchurl { inherit (spec) url sha256; }); + + # + # Various helpers + # + + # The set of packages used when specs are fetched using non-builtins. + mkPkgs = sources: + let + sourcesNixpkgs = + import (builtins_fetchTarball { inherit (sources.nixpkgs) url sha256; }) {}; + hasNixpkgsPath = builtins.any (x: x.prefix == "nixpkgs") builtins.nixPath; + hasThisAsNixpkgsPath = <nixpkgs> == ./.; + in + if builtins.hasAttr "nixpkgs" sources + then sourcesNixpkgs + else if hasNixpkgsPath && ! hasThisAsNixpkgsPath then + import <nixpkgs> {} + else + abort + '' + Please specify either <nixpkgs> (through -I or NIX_PATH=nixpkgs=...) or + add a package called "nixpkgs" to your sources.json. + ''; + + # The actual fetching function. + fetch = pkgs: name: spec: + + if ! builtins.hasAttr "type" spec then + abort "ERROR: niv spec ${name} does not have a 'type' attribute" + else if spec.type == "file" then fetch_file pkgs spec + else if spec.type == "tarball" then fetch_tarball pkgs spec + else if spec.type == "git" then fetch_git spec + else if spec.type == "builtin-tarball" then fetch_builtin-tarball spec + else if spec.type == "builtin-url" then fetch_builtin-url spec + else + abort "ERROR: niv spec ${name} has unknown type ${builtins.toJSON spec.type}"; + + # Ports of functions for older nix versions + + # a Nix version of mapAttrs if the built-in doesn't exist + mapAttrs = builtins.mapAttrs or ( + f: set: with builtins; + listToAttrs (map (attr: { name = attr; value = f attr set.${attr}; }) (attrNames set)) + ); + + # fetchTarball version that is compatible between all the versions of Nix + builtins_fetchTarball = { url, sha256 }@attrs: + let + inherit (builtins) lessThan nixVersion fetchTarball; + in + if lessThan nixVersion "1.12" then + fetchTarball { inherit url; } + else + fetchTarball attrs; + + # fetchurl version that is compatible between all the versions of Nix + builtins_fetchurl = { url, sha256 }@attrs: + let + inherit (builtins) lessThan nixVersion fetchurl; + in + if lessThan nixVersion "1.12" then + fetchurl { inherit url; } + else + fetchurl attrs; + + # Create the final "sources" from the config + mkSources = config: + mapAttrs ( + name: spec: + if builtins.hasAttr "outPath" spec + then abort + "The values in sources.json should not have an 'outPath' attribute" + else + spec // { outPath = fetch config.pkgs name spec; } + ) config.sources; + + # The "config" used by the fetchers + mkConfig = + { sourcesFile ? ./sources.json + , sources ? builtins.fromJSON (builtins.readFile sourcesFile) + , pkgs ? mkPkgs sources + }: rec { + # The sources, i.e. the attribute set of spec name to spec + inherit sources; + + # The "pkgs" (evaluated nixpkgs) to use for e.g. non-builtin fetchers + inherit pkgs; + }; +in +mkSources (mkConfig {}) // { __functor = _: settings: mkSources (mkConfig settings); } diff --git a/nixpkgs.nix b/nixpkgs.nix deleted file mode 100644 index fbf8257..0000000 --- a/nixpkgs.nix +++ /dev/null @@ -1,5 +0,0 @@ -# generated with ~/bin/nixos-pin -{ - url = "https://github.com/NixOS/nixpkgs/archive/b0c285807d6a9f1b7562ec417c24fa1a30ecc31a.tar.gz"; - sha256 = "0waapr7aqz0h1fy1fqlx981ygllh91qx9sz1l2j2h59s46cdircl"; -} @@ -3,10 +3,7 @@ }: let - nixpkgs-tar = builtins.fetchTarball (import ./nixpkgs.nix); - nixpkgs = import "${nixpkgs-tar}" { overlays = [ (import ./overlay.nix) ]; }; - nixos = import "${nixpkgs-tar}/nixos"; - biz = import ./biz.nix { inherit nixpkgs; }; + nixpkgs = import ./nix/nixpkgs.nix; in nixpkgs.mkShell ({ name = "bizdev"; buildInputs = [ @@ -19,10 +16,6 @@ in nixpkgs.mkShell ({ nixpkgs.wemux ]; shellHook = '' - export HERO_PORT=3000 - # TODO: figure out another way to do this - #export HERO_CLIENT=$PWD/_bild/Com.MusicMeetsComics.Client/static - echo "biz" | ${nixpkgs.figlet}/bin/figlet | ${nixpkgs.lolcat}/bin/lolcat ''; }) |