chore(docker): build production container

This commit is contained in:
Gregor Kleen 2021-09-13 17:09:06 +02:00
parent 1c9fe6e0cb
commit fd89f34746
12 changed files with 426 additions and 333 deletions

View File

@ -18,6 +18,10 @@ module.exports = {
{
filename: 'package.yaml',
updater: standardVersionUpdaterYaml
},
{
filename: 'nix/docker/version.json',
type: 'json'
}
],
commitUrlFormat: 'https://gitlab2.rz.ifi.lmu.de/uni2work/uni2work/commit/{{hash}}',

View File

@ -75,11 +75,12 @@
"^(assets|frontend)(/.*)?$"
"^config(/(favicon\.json|robots\.txt))?$"
"^(webpack|postcss)\.config\.js$"
"^(package|jsconfig)\.json$"
"^karma\.conf\.js$"
"^(package|jsconfig|\.eslintrc)\.json$"
"^\.babelrc$"
];
backendSource = pkgs.lib.sourceByRegex ./. [
"^(package|stack-flake)\.yaml$"
"^(\.hlint|package|stack-flake)\.yaml$"
"^stack\.yaml\.lock$"
"^(assets|app|hlint|load|messages|models|src|templates|test|testdata|wflint)(/.*)?$"
"^config(/(archive-types|mimetypes|personalised-sheet-files-collate|settings\.yml|submission-blacklist|test-settings\.yml|video-types|wordlist\.txt))?$"
@ -94,27 +95,36 @@
(import ./nix/maildev)
haskell-nix.overlay
(import ./nix/uniworx { inherit inputs frontendSource backendSource; })
(import ./nix/docker-demo { inherit self; })
(import ./nix/docker { inherit self; })
];
haskellFlake = pkgs.uniworx.flake {};
pushUniworxDemoDocker = pkgs.writeScriptBin "push-uniworx-demo-docker" ''
mkPushUniworxDocker = dockerImage: pkgs.writeScriptBin "push-${dockerImage.name}" ''
#!${pkgs.zsh}/bin/zsh -xe
target=''${1-docker://registry.gitlab.com/fradrive/fradrive/uniworx-demo:${pkgs.uniworxDemoDocker.imageTag}}
target=''${1-docker://registry.gitlab.com/fradrive/fradrive/uniworx-demo:${dockerImage.imageTag}}
[[ -n "''${1}" ]] && shift
${pkgs.skopeo}/bin/skopeo ''${@} --insecure-policy copy docker-archive://${pkgs.uniworxDemoDocker} ''${target}
${pkgs.skopeo}/bin/skopeo ''${@} --insecure-policy copy docker-archive://${dockerImage} ''${target}
'';
in {
packages = haskellFlake.packages // { inherit (pkgs) uniworx-node-dependencies uniworx-well-known uniworx-frontend uniworxDemoDocker; inherit (pkgs.uniworx.stack-nix.passthru) calculateMaterializedSha; };
apps = haskellFlake.apps // { push-uniworx-demo-docker = flake-utils.lib.mkApp { drv = pushUniworxDemoDocker; }; };
inherit (haskellFlake) checks;
packages = haskellFlake.packages // {
inherit (pkgs) uniworxNodeDependencies uniworxWellKnown uniworxFrontend uniworxDemoDocker uniworxDocker;
};
apps = haskellFlake.apps // {
pushUniworxDemoDocker = flake-utils.lib.mkApp { drv = mkPushUniworxDocker pkgs.uniworxDemoDocker; };
pushUniworxDocker = flake-utils.lib.mkApp { drv = mkPushUniworxDocker pkgs.uniworxDocker; };
calculateMaterializedSha = flake-utils.lib.mkApp { drv = pkgs.uniworx.stack-nix.passthru.calculateMaterializedSha; exePath = ""; };
};
checks = haskellFlake.checks // {
uniworxFrontend = pkgs.uniworxFrontend.check;
};
devShell = import ./shell.nix { inherit pkgs; };
legacyPackages = pkgs;
defaultPackage = pkgs.uniworxDemoDocker;
defaultPackage = self.packages.${system}."uniworx:exe:uniworx";
defaultApp = self.apps.${system}."uniworx:exe:uniworx";
}
);
}

212
nix/develop.nix Normal file
View File

@ -0,0 +1,212 @@
{ pkgs
, doPortOffset ? true
, doDevelopEnv ? true
}:
with pkgs.lib;
let
withDevelop = action: ''
#!${pkgs.zsh}/bin/zsh -e
${optionalString doDevelopEnv ''
basePath=$(pwd)
exec 4<>''${basePath}/.develop.env
flockRes=
set +e
${pkgs.util-linux}/bin/flock -en 4; flockRes=$?
set -e
if [[ ''${flockRes} -ne 0 ]]; then
echo "Could not take exclusive lock; is another develop running?" >&2
exit ''${flockRes}
fi
''}
cleanup() {
set +e -x
type cleanup_postgres &>/dev/null && cleanup_postgres
type cleanup_widget_memcached &>/dev/null && cleanup_widget_memcached
type cleanup_session_memcached &>/dev/null && cleanup_session_memcached
type cleanup_cache_memcached &>/dev/null && cleanup_cache_memcached
type cleanup_minio &>/dev/null && cleanup_minio
type cleanup_maildev &>/dev/null && cleanup_maildev
${optionalString doDevelopEnv ''
[ -f "''${basePath}/.develop.env" ] && rm -vf "''${basePath}/.develop.env"
''}
set +x
}
trap cleanup EXIT
export PORT_OFFSET=${if doPortOffset then "$(((16#$(echo \"fradrive $(whoami)\" | sha256sum | head -c 16)) % 1000))" else "0"}
if [[ -z "$PGHOST" ]]; then
set -xe
pgDir=$(mktemp -d --tmpdir=''${XDG_RUNTIME_DIR} postgresql.XXXXXX)
pgSockDir=$(mktemp -d --tmpdir=''${XDG_RUNTIME_DIR} postgresql.sock.XXXXXX)
pgLogFile=$(mktemp --tmpdir=''${XDG_RUNTIME_DIR} postgresql.XXXXXX.log)
initdb --no-locale -D ''${pgDir}
pg_ctl start -D ''${pgDir} -l ''${pgLogFile} -w -o "-k ''${pgSockDir} -c listen_addresses=''' -c hba_file='${postgresHba}' -c unix_socket_permissions=0700 -c max_connections=9990 -c shared_preload_libraries=pg_stat_statements -c auto_explain.log_min_duration=100ms"
psql -h ''${pgSockDir} -f ${postgresSchema} postgres
printf "Postgres logfile is %s\nPostgres socket directory is %s\n" ''${pgLogFile} ''${pgSockDir}
export PGHOST=''${pgSockDir}
export PGLOG=''${pgLogFile}
cleanup_postgres() {
set +e -x
pg_ctl stop -D ''${pgDir}
rm -rvf ''${pgDir} ''${pgSockDir} ''${pgLogFile}
set +x
}
set +xe
fi
if [[ -z "$WIDGET_MEMCACHED_HOST" ]]; then
set -xe
memcached -l localhost -p $(($PORT_OFFSET + 11211)) &>/dev/null &
widget_memcached_pid=$!
export WIDGET_MEMCACHED_HOST=localhost
export WIDGET_MEMCACHED_PORT=$(($PORT_OFFSET + 11211))
cleanup_widget_memcached() {
[[ -n "$widget_memcached_pid" ]] && kill $widget_memcached_pid
}
set +xe
fi
if [[ -z "$SESSION_MEMCACHED_HOST" ]]; then
set -xe
memcached -l localhost -p $(($PORT_OFFSET + 11212)) &>/dev/null &
session_memcached_pid=$!
export SESSION_MEMCACHED_HOST=localhost
export SESSION_MEMCACHED_PORT=$(($PORT_OFFSET + 11212))
cleanup_session_memcached() {
[[ -n "$session_memcached_pid" ]] && kill $session_memcached_pid
}
set +xe
fi
if [[ -z "$MEMCACHED_HOST" ]]; then
set -xe
memcached -l localhost -p $(($PORT_OFFSET + 11213)) &>/dev/null &
memcached_pid=$!
export MEMCACHED_HOST=localhost
export MEMCACHED_PORT=$(($PORT_OFFSET + 11212))
cleanup_session_memcached() {
[[ -n "$memcached_pid" ]] && kill $memcached_pid
}
set +xe
fi
if [[ -z "$UPLOAD_S3_HOST" ]]; then
set -xe
cleanup_minio() {
[[ -n "$minio_pid" ]] && kill $minio_pid
[[ -n "''${MINIO_DIR}" ]] && rm -rvf ''${MINIO_DIR}
[[ -n "''${MINIO_LOGFILE}" ]] && rm -rvf ''${MINIO_LOGFILE}
}
export MINIO_DIR=$(mktemp -d --tmpdir=''${XDG_RUNTIME_DIR} minio.XXXXXX)
export MINIO_LOGFILE=$(mktemp --tmpdir=''${XDG_RUNTIME_DIR} minio.XXXXXX.log)
export MINIO_ACCESS_KEY=$(${pkgs.pwgen}/bin/pwgen -s 16 1)
export MINIO_SECRET_KEY=$(${pkgs.pwgen}/bin/pwgen -s 32 1)
minio server --address localhost:$(($PORT_OFFSET + 9000)) ''${MINIO_DIR} &>''${MINIO_LOGFILE} &
minio_pid=$!
export UPLOAD_S3_HOST=localhost
export UPLOAD_S3_PORT=$(($PORT_OFFSET + 9000))
export UPLOAD_S3_SSL=false
export UPLOAD_S3_KEY_ID=''${MINIO_ACCESS_KEY}
export UPLOAD_S3_KEY=''${MINIO_SECRET_KEY}
sleep 1
set +xe
fi
${optionalString (pkgs.nodePackages ? "maildev") ''
if [[ -z "$SMTPHOST" ]]; then
set -xe
cleanup_maildev() {
[[ -n "$maildev_pid" ]] && kill $maildev_pid
}
TMPDIR=''${XDG_RUNTIME_DIR} ${pkgs.nodePackages.maildev}/bin/maildev --smtp $(($PORT_OFFSET + 1025)) --web $(($PORT_OFFSET + 8080)) --ip localhost --web-ip localhost &>/dev/null &
maildev_pid=$!
export SMTPHOST=localhost
export SMTPPORT=$(($PORT_OFFSET + 1025))
export SMTPSSL=none
set +xe
fi
''}
${optionalString doDevelopEnv ''
set -xe
cat >&4 <<EOF
PORT_OFFSET=''${PORT_OFFSET}
PGHOST=''${pgSockDir}
PGLOG=''${pgLogFile}
WIDGET_MEMCACHED_HOST=localhost
WIDGET_MEMCACHED_PORT=$(($PORT_OFFSET + 11211))
SESSION_MEMCACHED_HOST=localhost
SESSION_MEMCACHED_PORT=$(($PORT_OFFSET + 11212))
MEMCACHED_HOST=localhost
MEMCACHED_PORT=$(($PORT_OFFSET + 11212))
MINIO_DIR=''${MINIO_DIR}
MINIO_LOGFILE=''${MINIO_LOGFILE}
UPLOAD_S3_HOST=localhost
UPLOAD_S3_PORT=$(($PORT_OFFSET + 9000))
UPLOAD_S3_SSL=false
UPLOAD_S3_KEY_ID=''${MINIO_ACCESS_KEY}
UPLOAD_S3_KEY=''${MINIO_SECRET_KEY}
SMTPHOST=''${SMTPHOST}
SMTPPORT=''${SMTPPORT}
SMTPSSL=''${SMTPSSL}
EOF
set +xe
''}
${action}
'';
postgresSchema = pkgs.writeText "schema.sql" ''
CREATE USER uniworx WITH SUPERUSER;
CREATE DATABASE uniworx_test;
GRANT ALL ON DATABASE uniworx_test TO uniworx;
CREATE DATABASE uniworx;
GRANT ALL ON DATABASE uniworx TO uniworx;
'';
postgresHba = pkgs.writeText "hba_file" ''
local all all trust
'';
in withDevelop

View File

@ -1,111 +0,0 @@
{ self }: final: prev: {
uniworxDemoDocker = prev.dockerTools.buildImage {
name = "uniworx-demo";
tag = (builtins.fromJSON (prev.lib.readFile ./version.json)).version;
created =
let
fromDate = builtins.readFile (prev.runCommand "date" { nativeBuildInputs = with final; [ coreutils ]; } ''
printf '%s' $(date -Is -d '@${toString self.lastModified}') > $out
'');
in if self ? lastModified then fromDate else "1970-01-01T00:00:01Z";
contents = with final; [
uniworx.uniworx.components.exes.uniworx
prev.dockerTools.binSh postgresql_12
memcached
];
runAsRoot = ''
#!${final.stdenv.shell}
${prev.dockerTools.shadowSetup}
mkdir -p /var/lib
groupadd -r postgres
useradd -r -g postgres -d /var/lib/postgres -M postgres
install -d -g postgres -o postgres -m 0750 /var/lib/postgres
groupadd -r memcached
useradd -r -g memcached -d /var/lib/memcached -M memcached
install -d -g memcached -o memcached -m 0750 /var/lib/memcached
groupadd -r uniworx
useradd -r -g uniworx -d /var/lib/uniworx -M uniworx
install -d -g uniworx -o uniworx -m 0750 /var/lib/uniworx
gpasswd -a uniworx postgres
mkdir -p /var/log
install -d -g postgres -o postgres -m 0755 /var/log/postgres
install -d -g memcached -o memcached -m 0755 /var/log/memcached
install -d -g uniworx -o uniworx -m 0755 /var/log/uniworx
mkdir -p /run
install -d -g postgres -o postgres -m 0755 /run/postgres
'';
config =
let
entrypoint = prev.writeScriptBin "uniworx-entrypoint" ''
#!${final.zsh}/bin/zsh -xe
export PATH=${final.su}/bin:${final.findutils}/bin:${final.coreutils}/bin:/bin
cTime=$(date -Is)
pgDir=/var/lib/postgres
pgSockDir=/run/postgres
pgLogFile=/var/log/postgres/''${cTime}.log
export PGHOST=''${pgSockDir}
export PGLOG=''${pgLogFile}
pgNew=
if [[ -n "$(find ''${pgDir} -maxdepth 0 -type d -empty 2>/dev/null)" ]]; then
pgNew=1
fi
[[ -z "''${pgNew}" ]] || su postgres -c "initdb --no-locale --encoding=UTF8 -D ''${pgDir}"
su postgres -c "pg_ctl start -D ''${pgDir} -l ''${pgLogFile} -w -o '-k ''${pgSockDir} -c listen_addresses= -c hba_file=${postgresHba} -c unix_socket_permissions=0777 -c max_connections=9990 -c shared_preload_libraries=pg_stat_statements -c auto_explain.log_min_duration=100ms'"
[[ -z "''${pgNew}" ]] || psql -f ${postgresSchema} postgres postgres
su memcached -c "cd /var/lib/memcached; memcached -p 11212" &>/var/log/memcached/''${cTime}.log &
export SESSION_MEMCACHED_HOST=localhost
export SESSION_MEMCACHED_PORT=11212
export LOGDEST=/var/log/uniworx/''${cTime}.log
typeset -a configs
configs=()
configDir=''${CONFIG_DIR-/cfg}
if [[ -d "''${configDir}" ]]; then
while IFS= read -d $'\0' cfg; do
configs+=("''${(q)cfg}")
done < <(find "''${configDir}" \( -name '*.yml' -o -name '*.yaml' \) -print0 | sort -rz)
fi
configs+=('${uniworxConfig}')
exec -- su uniworx -c "cd /var/lib/uniworx; uniworx ''${configs}"
'';
postgresSchema = prev.writeText "schema.sql" ''
CREATE USER uniworx WITH SUPERUSER;
CREATE DATABASE uniworx;
GRANT ALL ON DATABASE uniworx TO uniworx;
'';
postgresHba = prev.writeText "hba_file" ''
local all all trust
'';
uniworxConfig = prev.writeText "uni2work.yml" ''
port: 8080
approot: "_env:APPROOT:http://localhost:8080"
'';
in {
Cmd = [ "${entrypoint}/bin/uniworx-entrypoint" ];
ExposedPorts = {
"8080/tcp" = {};
};
Volumes = {
"/var/lib/postgres" = {};
"/var/lib/uniworx" = {};
"/var/log" = {};
};
};
};
}

127
nix/docker/default.nix Normal file
View File

@ -0,0 +1,127 @@
{ self }: final: prev:
with prev.lib;
let
mkUniworxDocker = { isDemo }: prev.dockerTools.buildImage {
name = "uniworx${optionalString isDemo "-demo"}";
tag =
let
versionFile = if isDemo then ./demo-version.json else ./version.json;
in (builtins.fromJSON (prev.lib.readFile versionFile)).version;
created =
let
fromDate = builtins.readFile (prev.runCommand "date" { nativeBuildInputs = with final; [ coreutils ]; } ''
printf '%s' $(date -Is -d '@${toString self.lastModified}') > $out
'');
in if self ? lastModified then fromDate else "1970-01-01T00:00:01Z";
contents = with final; [
uniworx.uniworx.components.exes.uniworx
prev.dockerTools.binSh
] ++ optionals isDemo [ postgresql_12 memcached ];
runAsRoot = ''
#!${final.stdenv.shell}
${prev.dockerTools.shadowSetup}
mkdir -p /var/lib
groupadd -r uniworx
useradd -r -g uniworx -d /var/lib/uniworx -M uniworx
install -d -g uniworx -o uniworx -m 0750 /var/lib/uniworx
mkdir -p /var/log
install -d -g uniworx -o uniworx -m 0755 /var/log/uniworx
${optionalString isDemo ''
groupadd -r postgres
useradd -r -g postgres -d /var/lib/postgres -M postgres
install -d -g postgres -o postgres -m 0750 /var/lib/postgres
groupadd -r memcached
useradd -r -g memcached -d /var/lib/memcached -M memcached
install -d -g memcached -o memcached -m 0750 /var/lib/memcached
gpasswd -a uniworx postgres
install -d -g postgres -o postgres -m 0755 /var/log/postgres
install -d -g memcached -o memcached -m 0755 /var/log/memcached
mkdir -p /run
install -d -g postgres -o postgres -m 0755 /run/postgres
''}
'';
config =
let
entrypoint = prev.writeScriptBin "uniworx-entrypoint" ''
#!${final.zsh}/bin/zsh -xe
export PATH=${final.su}/bin:${final.findutils}/bin:${final.coreutils}/bin:/bin
cTime=$(date -Is)
${optionalString isDemo ''
pgDir=/var/lib/postgres
pgSockDir=/run/postgres
pgLogFile=/var/log/postgres/''${cTime}.log
export PGHOST=''${pgSockDir}
export PGLOG=''${pgLogFile}
pgNew=
if [[ -n "$(find ''${pgDir} -maxdepth 0 -type d -empty 2>/dev/null)" ]]; then
pgNew=1
fi
[[ -z "''${pgNew}" ]] || su postgres -c "initdb --no-locale --encoding=UTF8 -D ''${pgDir}"
su postgres -c "pg_ctl start -D ''${pgDir} -l ''${pgLogFile} -w -o '-k ''${pgSockDir} -c listen_addresses= -c hba_file=${postgresHba} -c unix_socket_permissions=0777 -c max_connections=9990 -c shared_preload_libraries=pg_stat_statements -c auto_explain.log_min_duration=100ms'"
[[ -z "''${pgNew}" ]] || psql -f ${postgresSchema} postgres postgres
su memcached -c "cd /var/lib/memcached; memcached -p 11212" &>/var/log/memcached/''${cTime}.log &
export SESSION_MEMCACHED_HOST=localhost
export SESSION_MEMCACHED_PORT=11212
''}
export LOGDEST=/var/log/uniworx/''${cTime}.log
typeset -a configs
configs=()
configDir=''${CONFIG_DIR-/cfg}
if [[ -d "''${configDir}" ]]; then
while IFS= read -d $'\0' cfg; do
configs+=("''${(q)cfg}")
done < <(find "''${configDir}" \( -name '*.yml' -o -name '*.yaml' \) -print0 | sort -rz)
fi
configs+=('${uniworxConfig}')
exec -- su uniworx -c "cd /var/lib/uniworx; uniworx ''${configs}"
'';
postgresSchema = prev.writeText "schema.sql" ''
CREATE USER uniworx WITH SUPERUSER;
CREATE DATABASE uniworx;
GRANT ALL ON DATABASE uniworx TO uniworx;
'';
postgresHba = prev.writeText "hba_file" ''
local all all trust
'';
uniworxConfig = prev.writeText "uni2work.yml" ''
port: 8080
approot: "_env:APPROOT:http://localhost:8080"
'';
in {
Cmd = [ "${entrypoint}/bin/uniworx-entrypoint" ];
ExposedPorts = {
"8080/tcp" = {};
};
Volumes = {
"/var/lib/uniworx" = {};
"/var/log" = {};
} // optionalAttrs isDemo {
"/var/lib/postgres" = {};
};
};
};
in mapAttrs (_name: mkUniworxDocker) {
uniworxDemoDocker = { isDemo = true; };
uniworxDocker = { isDemo = false; };
}

3
nix/docker/version.json Normal file
View File

@ -0,0 +1,3 @@
{
"version": "25.21.0"
}

View File

@ -1,4 +1,7 @@
{ inputs, backendSource, ... }: final: prev:
with prev.lib;
let
haskellInputs = ["encoding" "memcached-binary" "conduit-resumablesink" "HaskellNet-SSL" "ldap-client" "serversession" "xss-sanitize" "colonnade" "minio-hs" "cryptoids" "zip-stream" "yesod" "cryptonite" "esqueleto"];
in {
@ -11,7 +14,7 @@ in {
patchPhase = ''
substitute stack-flake.yaml stack.yaml \
${prev.lib.concatMapStringsSep " \\\n" (pkgName: "--replace @${pkgName}@ ${inputs."${pkgName}"}") haskellInputs}
${concatMapStringsSep " \\\n" (pkgName: "--replace @${pkgName}@ ${inputs."${pkgName}"}") haskellInputs}
'';
installPhase = ''
@ -20,7 +23,7 @@ in {
'';
};
compiler-nix-name = "ghc8104";
# stack-sha256 = "1n7z294ldv2rjkfj1vs3kqmnbp34m2scrmyrp5kwmga9vp86fd9z";
# stack-sha256 = "1n7z294ldv2rjkfj1vs3kqmnbp34m2scrmyrp5kwmga9vp86fd9z"; # produces errors gregor does not understand :(
modules = [
{
packages = {
@ -54,7 +57,7 @@ in {
{
packages.uniworx = {
postUnpack = ''
cp -pr --reflink=auto ${prev.uniworx-frontend}/. $sourceRoot
${final.xorg.lndir}/bin/lndir -silent ${prev.uniworxFrontend} $sourceRoot
chmod a+w -R $sourceRoot
'';
preBuild = ''
@ -65,8 +68,14 @@ in {
components.exes.uniworxdb.build-tools = with final.pkgs; [ llvm_9 ];
components.exes.uniworxload.build-tools = with final.pkgs; [ llvm_9 ];
components.exes.uniworx-wflint.build-tools = with final.pkgs; [ llvm_9 ];
components.tests.yesod.build-tools = with final.pkgs; [ llvm_9 ];
components.tests.hlint.build-tools = with final.pkgs; [ llvm_9 ];
components.tests.yesod = {
build-tools = with final.pkgs; [ llvm_9 final.uniworx.hsPkgs.hspec-discover ];
testWrapper =
let
testWrapper = prev.writeScript "test-wrapper" (import ../develop.nix { inherit pkgs; doDevelopEnv = false; } "$@");
in singleton (toString testWrapper);
};
components.tests.hlint.build-tools = with final.pkgs; [ llvm_9 final.uniworx.hsPkgs.hlint-test ];
};
}
];

View File

@ -1,19 +1,43 @@
{ frontendSource, ... }: final: prev: {
uniworx-frontend = prev.stdenv.mkDerivation {
{ frontendSource, ... }: final: prev:
let
setupNodeDeps = ''
ln -s ${final.uniworxNodeDependencies}/lib/node_modules ./node_modules
export PATH="${final.uniworxNodeDependencies}/bin:$PATH"
'';
in {
uniworxFrontend = prev.stdenv.mkDerivation {
name = "uniworx-frontend";
srcs = [frontendSource prev.uniworx-well-known];
srcs = [frontendSource prev.uniworxWellKnown];
sourceRoot = "source";
phases = ["unpackPhase" "buildPhase" "installPhase"];
phases = ["unpackPhase" "checkPhase" "buildPhase" "installPhase"];
postUnpack = ''
cp -pr --reflink=auto uniworx-well-known/. $sourceRoot
${final.xorg.lndir}/bin/lndir -silent ../uniworx-well-known $sourceRoot
'';
preBuild = setupNodeDeps;
buildPhase = ''
ln -s ${prev.uniworx-node-dependencies}/lib/node_modules ./node_modules
export PATH="${prev.uniworx-node-dependencies}/bin:$PATH"
runHook preBuild
webpack --progress
runHook postBuild
'';
preCheck = ''
${setupNodeDeps}
export FONTCONFIG_FILE="${final.fontconfig.out}/etc/fonts/fonts.conf"
export FONTCONFIG_PATH="${final.fontconfig.out}/etc/fonts/"
export CHROME_BIN="${final.chromium}/bin/chromium-browser"
'';
checkPhase = ''
runHook preCheck
eslint frontend/src
karma start --conf karma.conf.js
runHook postCheck
'';
installPhase = ''
@ -21,5 +45,14 @@
cp -r --reflink=auto well-known static $out
cp -r --reflink=auto config/webpack.yml $out/config
'';
passthru.check = final.uniworxFrontend.overrideAttrs (oldAttrs: {
name = "${oldAttrs.name}-check";
phases = ["unpackPhase" "buildPhase"];
buildPhase = ''
mkdir $out
( ${oldAttrs.checkPhase} ) | tee $out/test-stdout
'';
});
};
}

View File

@ -1,5 +1,5 @@
{ inputs, ... }: final: prev: {
uniworx-node-dependencies = (prev.callPackage ../frontend {}).nodeDependencies.override (oldArgs: {
uniworxNodeDependencies = (prev.callPackage ../frontend {}).nodeDependencies.override (oldArgs: {
dependencies =
let
srcOverrides = {

View File

@ -1,13 +1,13 @@
{ frontendSource, ... }: final: prev: {
uniworx-well-known = prev.stdenv.mkDerivation {
uniworxWellKnown = prev.stdenv.mkDerivation {
name = "uniworx-well-known";
src = frontendSource;
phases = ["unpackPhase" "buildPhase" "installPhase" "fixupPhase"];
buildPhase = ''
ln -s ${prev.uniworx-node-dependencies}/lib/node_modules ./node_modules
export PATH="${prev.uniworx-node-dependencies}/bin:${prev.exiftool}/bin:$PATH"
ln -s ${final.uniworxNodeDependencies}/lib/node_modules ./node_modules
export PATH="${final.uniworxNodeDependencies}/bin:${prev.exiftool}/bin:$PATH"
webpack --progress
'';

198
shell.nix
View File

@ -5,201 +5,7 @@ let
haskellPackages = pkgs.haskellPackages;
postgresSchema = pkgs.writeText "schema.sql" ''
CREATE USER uniworx WITH SUPERUSER;
CREATE DATABASE uniworx_test;
GRANT ALL ON DATABASE uniworx_test TO uniworx;
CREATE DATABASE uniworx;
GRANT ALL ON DATABASE uniworx TO uniworx;
'';
postgresHba = pkgs.writeText "hba_file" ''
local all all trust
'';
develop = pkgs.writeScriptBin "develop" ''
#!${pkgs.zsh}/bin/zsh -e
basePath=$(pwd)
exec 4<>''${basePath}/.develop.env
flockRes=
set +e
${pkgs.util-linux}/bin/flock -en 4; flockRes=$?
set -e
if [[ ''${flockRes} -ne 0 ]]; then
echo "Could not take exclusive lock; is another develop running?" >&2
exit ''${flockRes}
fi
cleanup() {
set +e -x
type cleanup_postgres &>/dev/null && cleanup_postgres
type cleanup_widget_memcached &>/dev/null && cleanup_widget_memcached
type cleanup_session_memcached &>/dev/null && cleanup_session_memcached
type cleanup_cache_memcached &>/dev/null && cleanup_cache_memcached
type cleanup_minio &>/dev/null && cleanup_minio
type cleanup_maildev &>/dev/null && cleanup_maildev
[ -f "''${basePath}/.develop.env" ] && rm -vf "''${basePath}/.develop.env"
set +x
}
trap cleanup EXIT
export PORT_OFFSET=$(((16#$(echo "fradrive $(whoami)" | sha256sum | head -c 16)) % 1000))
if [[ -z "$PGHOST" ]]; then
set -xe
pgDir=$(mktemp -d --tmpdir=''${XDG_RUNTIME_DIR} postgresql.XXXXXX)
pgSockDir=$(mktemp -d --tmpdir=''${XDG_RUNTIME_DIR} postgresql.sock.XXXXXX)
pgLogFile=$(mktemp --tmpdir=''${XDG_RUNTIME_DIR} postgresql.XXXXXX.log)
initdb --no-locale -D ''${pgDir}
pg_ctl start -D ''${pgDir} -l ''${pgLogFile} -w -o "-k ''${pgSockDir} -c listen_addresses=''' -c hba_file='${postgresHba}' -c unix_socket_permissions=0700 -c max_connections=9990 -c shared_preload_libraries=pg_stat_statements -c auto_explain.log_min_duration=100ms"
psql -h ''${pgSockDir} -f ${postgresSchema} postgres
printf "Postgres logfile is %s\nPostgres socket directory is %s\n" ''${pgLogFile} ''${pgSockDir}
export PGHOST=''${pgSockDir}
export PGLOG=''${pgLogFile}
cleanup_postgres() {
set +e -x
pg_ctl stop -D ''${pgDir}
rm -rvf ''${pgDir} ''${pgSockDir} ''${pgLogFile}
set +x
}
set +xe
fi
if [[ -z "$WIDGET_MEMCACHED_HOST" ]]; then
set -xe
memcached -l localhost -p $(($PORT_OFFSET + 11211)) &>/dev/null &
widget_memcached_pid=$!
export WIDGET_MEMCACHED_HOST=localhost
export WIDGET_MEMCACHED_PORT=$(($PORT_OFFSET + 11211))
cleanup_widget_memcached() {
[[ -n "$widget_memcached_pid" ]] && kill $widget_memcached_pid
}
set +xe
fi
if [[ -z "$SESSION_MEMCACHED_HOST" ]]; then
set -xe
memcached -l localhost -p $(($PORT_OFFSET + 11212)) &>/dev/null &
session_memcached_pid=$!
export SESSION_MEMCACHED_HOST=localhost
export SESSION_MEMCACHED_PORT=$(($PORT_OFFSET + 11212))
cleanup_session_memcached() {
[[ -n "$session_memcached_pid" ]] && kill $session_memcached_pid
}
set +xe
fi
if [[ -z "$MEMCACHED_HOST" ]]; then
set -xe
memcached -l localhost -p $(($PORT_OFFSET + 11213)) &>/dev/null &
memcached_pid=$!
export MEMCACHED_HOST=localhost
export MEMCACHED_PORT=$(($PORT_OFFSET + 11212))
cleanup_session_memcached() {
[[ -n "$memcached_pid" ]] && kill $memcached_pid
}
set +xe
fi
if [[ -z "$UPLOAD_S3_HOST" ]]; then
set -xe
cleanup_minio() {
[[ -n "$minio_pid" ]] && kill $minio_pid
[[ -n "''${MINIO_DIR}" ]] && rm -rvf ''${MINIO_DIR}
[[ -n "''${MINIO_LOGFILE}" ]] && rm -rvf ''${MINIO_LOGFILE}
}
export MINIO_DIR=$(mktemp -d --tmpdir=''${XDG_RUNTIME_DIR} minio.XXXXXX)
export MINIO_LOGFILE=$(mktemp --tmpdir=''${XDG_RUNTIME_DIR} minio.XXXXXX.log)
export MINIO_ACCESS_KEY=$(${pkgs.pwgen}/bin/pwgen -s 16 1)
export MINIO_SECRET_KEY=$(${pkgs.pwgen}/bin/pwgen -s 32 1)
minio server --address localhost:$(($PORT_OFFSET + 9000)) ''${MINIO_DIR} &>''${MINIO_LOGFILE} &
minio_pid=$!
export UPLOAD_S3_HOST=localhost
export UPLOAD_S3_PORT=$(($PORT_OFFSET + 9000))
export UPLOAD_S3_SSL=false
export UPLOAD_S3_KEY_ID=''${MINIO_ACCESS_KEY}
export UPLOAD_S3_KEY=''${MINIO_SECRET_KEY}
sleep 1
set +xe
fi
${optionalString (pkgs.nodePackages ? "maildev") ''
if [[ -z "$SMTPHOST" ]]; then
set -xe
cleanup_maildev() {
[[ -n "$maildev_pid" ]] && kill $maildev_pid
}
TMPDIR=''${XDG_RUNTIME_DIR} ${pkgs.nodePackages.maildev}/bin/maildev --smtp $(($PORT_OFFSET + 1025)) --web $(($PORT_OFFSET + 8080)) --ip localhost --web-ip localhost &>/dev/null &
maildev_pid=$!
export SMTPHOST=localhost
export SMTPPORT=$(($PORT_OFFSET + 1025))
export SMTPSSL=none
set +xe
fi
''}
set -xe
cat >&4 <<EOF
PORT_OFFSET=''${PORT_OFFSET}
PGHOST=''${pgSockDir}
PGLOG=''${pgLogFile}
WIDGET_MEMCACHED_HOST=localhost
WIDGET_MEMCACHED_PORT=$(($PORT_OFFSET + 11211))
SESSION_MEMCACHED_HOST=localhost
SESSION_MEMCACHED_PORT=$(($PORT_OFFSET + 11212))
MEMCACHED_HOST=localhost
MEMCACHED_PORT=$(($PORT_OFFSET + 11212))
MINIO_DIR=''${MINIO_DIR}
MINIO_LOGFILE=''${MINIO_LOGFILE}
UPLOAD_S3_HOST=localhost
UPLOAD_S3_PORT=$(($PORT_OFFSET + 9000))
UPLOAD_S3_SSL=false
UPLOAD_S3_KEY_ID=''${MINIO_ACCESS_KEY}
UPLOAD_S3_KEY=''${MINIO_SECRET_KEY}
SMTPHOST=''${SMTPHOST}
SMTPPORT=''${SMTPPORT}
SMTPSSL=''${SMTPSSL}
EOF
set +xe
develop = pkgs.writeScriptBin "develop" (import ./nix/develop.nix { inherit pkgs; } ''
if [ -n "$ZSH_VERSION" ]; then
autoload -U +X compinit && compinit
autoload -U +X bashcompinit && bashcompinit
@ -207,7 +13,7 @@ let
eval "$(stack --bash-completion-script stack)"
$(getent passwd $USER | cut -d: -f 7)
'';
'');
inDevelop = pkgs.writeScriptBin "in-develop" ''
#!${pkgs.zsh}/bin/zsh -e