on master help sign in
default.nix: Add ob deploy payload (backend + js frontend + assets + config)
commit374f328477bc7e15c9e9f8cd537fe58579d7d00c authorAli Abrar <aliabrar@gmail.com> dateWed 9 May 2018, 15:15 (8 years ago) parentb9e3baf
1 file changed+104−49
default.nix+104−49
default.nix+104−49
@@ -101,57 +101,112 @@ rec {
101101 touch "$out"
102102 obelisk-asset-manifest-generate "$src" "$haskellManifest" ${packageName} ${moduleName} "$symlinked"
103103 '';
104− # An Obelisk project is a reflex-platform project with a predefined layout and role for each component
105− project = base: projectDefinition: reflex-platform.project (args@{ nixpkgs, ... }:
106− let mkProject = { android ? null #TODO: Better error when missing
107− , ios ? null #TODO: Better error when missing
108− , packages ? {}
109− }:
110− let frontendName = "frontend";
111− backendName = "backend";
112− commonName = "common";
113− staticName = "static";
114− staticPath = base + "/static";
115− assets = processAssets { src = base + "/static"; };
116− # The packages whose names and roles are defined by this package
117− predefinedPackages = filterAttrs (_: x: x != null) {
118− ${frontendName} = nullIfAbsent (base + "/frontend");
119− ${commonName} = nullIfAbsent (base + "/common");
120− ${backendName} = nullIfAbsent (base + "/backend");
121− };
122− combinedPackages = predefinedPackages // packages;
123− projectOverrides = self: super: {
124− ${staticName} = dontHaddock (self.callCabal2nix "static" assets.haskellManifest {});
125− };
126− overrides = composeExtensions defaultHaskellOverrides projectOverrides;
127− in {
128− inherit overrides;
129− packages = combinedPackages;
130− shells = {
131− ghc = filter (x: hasAttr x combinedPackages) [
132− backendName
133− commonName
134− frontendName
135− ];
136− ghcjs = filter (x: hasAttr x combinedPackages) [
137− frontendName
138− commonName
139− ];
140− };
141− android = {
142− ${if android == null then null else frontendName} = {
143− executableName = "frontend";
144− ${if builtins.pathExists staticPath then "assets" else null} = assets.symlinked;
145− } // android;
146− };
147− ios = {
148− ${if ios == null then null else frontendName} = {
149− executableName = "frontend";
150− ${if builtins.pathExists staticPath then "staticSrc" else null} = assets.symlinked;
151− } // ios;
104+ serverExe = exe: assets: config:
105+ pkgs.runCommand "serverExe" {} ''
106+ mkdir $out
107+ set -eux
108+ ln -s "${exe}"/* $out/
109+ ln -s $out/ghc/backend/bin/backend $out/
110+ ln -s $out/ghcjs/frontend/bin/frontend.jsexe $out/
111+ ln -s "${assets}" $out/static
112+ ln -s "${config}" $out/config
113+ '';
114+ server = exe: hostName:
115+ let system = "x86_64-linux";
116+ nixos = import (pkgs.path + /nixos);
117+ cfg = args: {
118+ };
119+ in nixos {
120+ inherit system;
121+ configuration = args: {
122+ imports = [
123+ (pkgs.path + /nixos/modules/virtualisation/amazon-image.nix)
124+ ];
125+ networking = { inherit hostName; };
126+ systemd.services.backend = {
127+ wantedBy = [ "multi-user-target" ];
128+ after = [ "network.target" ];
129+ restartIfChanged = true;
130+ script = ''
131+ ln -sft . "${exe}"/*
132+ mkdir -p log
133+ exec ./backend >>backend.out 2>>backend.err </dev/null
134+ '';
135+ serviceConfig = {
136+ User = "backend";
137+ KillMode = "process";
138+ WorkingDirectory = "~";
139+ Restart = "always";
140+ RestartSec = 5;
152141 };
153142 };
154− in mkProject (projectDefinition args));
143+ users.extraUsers.backend = {
144+ description = "backend service";
145+ home = "/var/lib/backend";
146+ createHome = true;
147+ isSystemUser = true;
148+ group = "backend";
149+ };
150+ ec2.hvm = true;
151+ };
152+ };
153+ # An Obelisk project is a reflex-platform project with a predefined layout and role for each component
154+ project = base: projectDefinition:
155+ let assets = processAssets { src = base + "/static"; };
156+ configPath = base + "/config";
157+ p = reflex-platform.project (args@{ nixpkgs, ... }:
158+ let mkProject = { android ? null #TODO: Better error when missing
159+ , ios ? null #TODO: Better error when missing
160+ , packages ? {}
161+ }:
162+ let frontendName = "frontend";
163+ backendName = "backend";
164+ commonName = "common";
165+ staticName = "static";
166+ staticPath = base + "/static";
167+
168+ # The packages whose names and roles are defined by this package
169+ predefinedPackages = filterAttrs (_: x: x != null) {
170+ ${frontendName} = nullIfAbsent (base + "/frontend");
171+ ${commonName} = nullIfAbsent (base + "/common");
172+ ${backendName} = nullIfAbsent (base + "/backend");
173+ };
174+ combinedPackages = predefinedPackages // packages;
175+ projectOverrides = self: super: {
176+ ${staticName} = dontHaddock (self.callCabal2nix "static" assets.haskellManifest {});
177+ };
178+ overrides = composeExtensions defaultHaskellOverrides projectOverrides;
179+ in {
180+ inherit overrides;
181+ packages = combinedPackages;
182+ shells = {
183+ ghc = filter (x: hasAttr x combinedPackages) [
184+ backendName
185+ commonName
186+ frontendName
187+ ];
188+ ghcjs = filter (x: hasAttr x combinedPackages) [
189+ frontendName
190+ commonName
191+ ];
192+ };
193+ android = {
194+ ${if android == null then null else frontendName} = {
195+ executableName = "frontend";
196+ ${if builtins.pathExists staticPath then "assets" else null} = assets.symlinked;
197+ } // android;
198+ };
199+ ios = {
200+ ${if ios == null then null else frontendName} = {
201+ executableName = "frontend";
202+ ${if builtins.pathExists staticPath then "staticSrc" else null} = assets.symlinked;
203+ } // ios;
204+ };
205+
206+ };
207+ in mkProject (projectDefinition args));
208+ in p // { server = { hostName }: server (serverExe p.all assets.symlinked configPath) hostName;
209+ };
155210 haskellPackageSets = {
156211 ghc = reflex-platform.ghc.override {
157212 overrides = defaultHaskellOverrides;