Merge pull request #79175 from helsinki-systems/init/sogo
sogo: init at 4.3.2
This commit is contained in:
commit
d84d8e802e
|
@ -847,6 +847,7 @@
|
|||
./services/web-apps/matomo.nix
|
||||
./services/web-apps/moinmoin.nix
|
||||
./services/web-apps/restya-board.nix
|
||||
./services/web-apps/sogo.nix
|
||||
./services/web-apps/tt-rss.nix
|
||||
./services/web-apps/trac.nix
|
||||
./services/web-apps/trilium.nix
|
||||
|
|
272
nixos/modules/services/web-apps/sogo.nix
Normal file
272
nixos/modules/services/web-apps/sogo.nix
Normal file
|
@ -0,0 +1,272 @@
|
|||
{ config, pkgs, lib, ... }: with lib; let
|
||||
cfg = config.services.sogo;
|
||||
|
||||
preStart = pkgs.writeShellScriptBin "sogo-prestart" ''
|
||||
touch /etc/sogo/sogo.conf
|
||||
chown sogo:sogo /etc/sogo/sogo.conf
|
||||
chmod 640 /etc/sogo/sogo.conf
|
||||
|
||||
${if (cfg.configReplaces != {}) then ''
|
||||
# Insert secrets
|
||||
${concatStringsSep "\n" (mapAttrsToList (k: v: ''export ${k}="$(cat "${v}" | tr -d '\n')"'') cfg.configReplaces)}
|
||||
|
||||
${pkgs.perl}/bin/perl -p ${concatStringsSep " " (mapAttrsToList (k: v: '' -e 's/${k}/''${ENV{"${k}"}}/g;' '') cfg.configReplaces)} /etc/sogo/sogo.conf.raw > /etc/sogo/sogo.conf
|
||||
'' else ''
|
||||
cp /etc/sogo/sogo.conf.raw /etc/sogo/sogo.conf
|
||||
''}
|
||||
'';
|
||||
|
||||
in {
|
||||
options.services.sogo = with types; {
|
||||
enable = mkEnableOption "SOGo groupware";
|
||||
|
||||
vhostName = mkOption {
|
||||
description = "Name of the nginx vhost";
|
||||
type = str;
|
||||
default = "sogo";
|
||||
};
|
||||
|
||||
timezone = mkOption {
|
||||
description = "Timezone of your SOGo instance";
|
||||
type = str;
|
||||
example = "America/Montreal";
|
||||
};
|
||||
|
||||
language = mkOption {
|
||||
description = "Language of SOGo";
|
||||
type = str;
|
||||
default = "English";
|
||||
};
|
||||
|
||||
ealarmsCredFile = mkOption {
|
||||
description = "Optional path to a credentials file for email alarms";
|
||||
type = nullOr str;
|
||||
default = null;
|
||||
};
|
||||
|
||||
configReplaces = mkOption {
|
||||
description = ''
|
||||
Replacement-filepath mapping for sogo.conf.
|
||||
Every key is replaced with the contents of the file specified as value.
|
||||
|
||||
In the example, every occurence of LDAP_BINDPW will be replaced with the text of the
|
||||
specified file.
|
||||
'';
|
||||
type = attrsOf str;
|
||||
default = {};
|
||||
example = {
|
||||
LDAP_BINDPW = "/var/lib/secrets/sogo/ldappw";
|
||||
};
|
||||
};
|
||||
|
||||
extraConfig = mkOption {
|
||||
description = "Extra sogo.conf configuration lines";
|
||||
type = lines;
|
||||
default = "";
|
||||
};
|
||||
};
|
||||
|
||||
config = mkIf cfg.enable {
|
||||
environment.systemPackages = [ pkgs.sogo ];
|
||||
|
||||
environment.etc."sogo/sogo.conf.raw".text = ''
|
||||
{
|
||||
// Mandatory parameters
|
||||
SOGoTimeZone = "${cfg.timezone}";
|
||||
SOGoLanguage = "${cfg.language}";
|
||||
// Paths
|
||||
WOSendMail = "/run/wrappers/bin/sendmail";
|
||||
SOGoMailSpoolPath = "/var/lib/sogo/spool";
|
||||
SOGoZipPath = "${pkgs.zip}/bin/zip";
|
||||
// Enable CSRF protection
|
||||
SOGoXSRFValidationEnabled = YES;
|
||||
// Remove dates from log (jornald does that)
|
||||
NGLogDefaultLogEventFormatterClass = "NGLogEventFormatter";
|
||||
// Extra config
|
||||
${cfg.extraConfig}
|
||||
}
|
||||
'';
|
||||
|
||||
systemd.services.sogo = {
|
||||
description = "SOGo groupware";
|
||||
after = [ "postgresql.service" "mysql.service" "memcached.service" "openldap.service" "dovecot2.service" ];
|
||||
wantedBy = [ "multi-user.target" ];
|
||||
restartTriggers = [ config.environment.etc."sogo/sogo.conf.raw".source ];
|
||||
|
||||
environment.LDAPTLS_CACERT = "/etc/ssl/certs/ca-certificates.crt";
|
||||
|
||||
serviceConfig = {
|
||||
Type = "forking";
|
||||
ExecStartPre = "+" + preStart + "/bin/sogo-prestart";
|
||||
ExecStart = "${pkgs.sogo}/bin/sogod -WOLogFile - -WOPidFile /run/sogo/sogo.pid";
|
||||
|
||||
ProtectSystem = "strict";
|
||||
ProtectHome = true;
|
||||
PrivateTmp = true;
|
||||
PrivateDevices = true;
|
||||
ProtectKernelTunables = true;
|
||||
ProtectKernelModules = true;
|
||||
ProtectControlGroups = true;
|
||||
RuntimeDirectory = "sogo";
|
||||
StateDirectory = "sogo/spool";
|
||||
|
||||
User = "sogo";
|
||||
Group = "sogo";
|
||||
|
||||
CapabilityBoundingSet = "";
|
||||
NoNewPrivileges = true;
|
||||
|
||||
LockPersonality = true;
|
||||
RestrictRealtime = true;
|
||||
PrivateMounts = true;
|
||||
PrivateUsers = true;
|
||||
MemoryDenyWriteExecute = true;
|
||||
SystemCallFilter = "@basic-io @file-system @network-io @system-service @timer";
|
||||
SystemCallArchitectures = "native";
|
||||
RestrictAddressFamilies = "AF_UNIX AF_INET AF_INET6";
|
||||
};
|
||||
};
|
||||
|
||||
systemd.services.sogo-tmpwatch = {
|
||||
description = "SOGo tmpwatch";
|
||||
|
||||
startAt = [ "hourly" ];
|
||||
script = ''
|
||||
SOGOSPOOL=/var/lib/sogo/spool
|
||||
|
||||
find "$SOGOSPOOL" -type f -user sogo -atime +23 -delete > /dev/null
|
||||
find "$SOGOSPOOL" -mindepth 1 -type d -user sogo -empty -delete > /dev/null
|
||||
'';
|
||||
|
||||
serviceConfig = {
|
||||
Type = "oneshot";
|
||||
|
||||
ProtectSystem = "strict";
|
||||
ProtectHome = true;
|
||||
PrivateTmp = true;
|
||||
PrivateDevices = true;
|
||||
ProtectKernelTunables = true;
|
||||
ProtectKernelModules = true;
|
||||
ProtectControlGroups = true;
|
||||
StateDirectory = "sogo/spool";
|
||||
|
||||
User = "sogo";
|
||||
Group = "sogo";
|
||||
|
||||
CapabilityBoundingSet = "";
|
||||
NoNewPrivileges = true;
|
||||
|
||||
LockPersonality = true;
|
||||
RestrictRealtime = true;
|
||||
PrivateMounts = true;
|
||||
PrivateUsers = true;
|
||||
PrivateNetwork = true;
|
||||
SystemCallFilter = "@basic-io @file-system @system-service";
|
||||
SystemCallArchitectures = "native";
|
||||
RestrictAddressFamilies = "";
|
||||
};
|
||||
};
|
||||
|
||||
systemd.services.sogo-ealarms = {
|
||||
description = "SOGo email alarms";
|
||||
|
||||
after = [ "postgresql.service" "mysqld.service" "memcached.service" "openldap.service" "dovecot2.service" "sogo.service" ];
|
||||
restartTriggers = [ config.environment.etc."sogo/sogo.conf.raw".source ];
|
||||
|
||||
startAt = [ "minutely" ];
|
||||
|
||||
serviceConfig = {
|
||||
Type = "oneshot";
|
||||
ExecStart = "${pkgs.sogo}/bin/sogo-ealarms-notify${optionalString (cfg.ealarmsCredFile != null) " -p ${cfg.ealarmsCredFile}"}";
|
||||
|
||||
ProtectSystem = "strict";
|
||||
ProtectHome = true;
|
||||
PrivateTmp = true;
|
||||
PrivateDevices = true;
|
||||
ProtectKernelTunables = true;
|
||||
ProtectKernelModules = true;
|
||||
ProtectControlGroups = true;
|
||||
StateDirectory = "sogo/spool";
|
||||
|
||||
User = "sogo";
|
||||
Group = "sogo";
|
||||
|
||||
CapabilityBoundingSet = "";
|
||||
NoNewPrivileges = true;
|
||||
|
||||
LockPersonality = true;
|
||||
RestrictRealtime = true;
|
||||
PrivateMounts = true;
|
||||
PrivateUsers = true;
|
||||
MemoryDenyWriteExecute = true;
|
||||
SystemCallFilter = "@basic-io @file-system @network-io @system-service";
|
||||
SystemCallArchitectures = "native";
|
||||
RestrictAddressFamilies = "AF_UNIX AF_INET AF_INET6";
|
||||
};
|
||||
};
|
||||
|
||||
# nginx vhost
|
||||
services.nginx.virtualHosts."${cfg.vhostName}" = {
|
||||
locations."/".extraConfig = ''
|
||||
rewrite ^ https://$server_name/SOGo;
|
||||
allow all;
|
||||
'';
|
||||
|
||||
# For iOS 7
|
||||
locations."/principals/".extraConfig = ''
|
||||
rewrite ^ https://$server_name/SOGo/dav;
|
||||
allow all;
|
||||
'';
|
||||
|
||||
locations."^~/SOGo".extraConfig = ''
|
||||
proxy_pass http://127.0.0.1:20000;
|
||||
proxy_redirect http://127.0.0.1:20000 default;
|
||||
|
||||
proxy_set_header X-Real-IP $remote_addr;
|
||||
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
|
||||
proxy_set_header Host $host;
|
||||
proxy_set_header x-webobjects-server-protocol HTTP/1.0;
|
||||
proxy_set_header x-webobjects-remote-host 127.0.0.1;
|
||||
proxy_set_header x-webobjects-server-port $server_port;
|
||||
proxy_set_header x-webobjects-server-name $server_name;
|
||||
proxy_set_header x-webobjects-server-url $scheme://$host;
|
||||
proxy_connect_timeout 90;
|
||||
proxy_send_timeout 90;
|
||||
proxy_read_timeout 90;
|
||||
proxy_buffer_size 4k;
|
||||
proxy_buffers 4 32k;
|
||||
proxy_busy_buffers_size 64k;
|
||||
proxy_temp_file_write_size 64k;
|
||||
client_max_body_size 50m;
|
||||
client_body_buffer_size 128k;
|
||||
break;
|
||||
'';
|
||||
|
||||
locations."/SOGo.woa/WebServerResources/".extraConfig = ''
|
||||
alias ${pkgs.sogo}/lib/GNUstep/SOGo/WebServerResources/;
|
||||
allow all;
|
||||
'';
|
||||
|
||||
locations."/SOGo/WebServerResources/".extraConfig = ''
|
||||
alias ${pkgs.sogo}/lib/GNUstep/SOGo/WebServerResources/;
|
||||
allow all;
|
||||
'';
|
||||
|
||||
locations."~ ^/SOGo/so/ControlPanel/Products/([^/]*)/Resources/(.*)$".extraConfig = ''
|
||||
alias ${pkgs.sogo}/lib/GNUstep/SOGo/$1.SOGo/Resources/$2;
|
||||
'';
|
||||
|
||||
locations."~ ^/SOGo/so/ControlPanel/Products/[^/]*UI/Resources/.*\\.(jpg|png|gif|css|js)$".extraConfig = ''
|
||||
alias ${pkgs.sogo}/lib/GNUstep/SOGo/$1.SOGo/Resources/$2;
|
||||
'';
|
||||
};
|
||||
|
||||
# User and group
|
||||
users.groups.sogo = {};
|
||||
users.users.sogo = {
|
||||
group = "sogo";
|
||||
isSystemUser = true;
|
||||
description = "SOGo service user";
|
||||
};
|
||||
};
|
||||
}
|
|
@ -292,6 +292,7 @@ in
|
|||
slurm = handleTest ./slurm.nix {};
|
||||
smokeping = handleTest ./smokeping.nix {};
|
||||
snapper = handleTest ./snapper.nix {};
|
||||
sogo = handleTest ./sogo.nix {};
|
||||
solr = handleTest ./solr.nix {};
|
||||
spacecookie = handleTest ./spacecookie.nix {};
|
||||
spike = handleTest ./spike.nix {};
|
||||
|
|
58
nixos/tests/sogo.nix
Normal file
58
nixos/tests/sogo.nix
Normal file
|
@ -0,0 +1,58 @@
|
|||
import ./make-test-python.nix ({ pkgs, ... }: {
|
||||
name = "sogo";
|
||||
meta = with pkgs.stdenv.lib.maintainers; {
|
||||
maintainers = [ ajs124 das_j ];
|
||||
};
|
||||
|
||||
nodes = {
|
||||
sogo = { config, pkgs, ... }: {
|
||||
services.nginx.enable = true;
|
||||
|
||||
services.mysql = {
|
||||
enable = true;
|
||||
package = pkgs.mysql;
|
||||
ensureDatabases = [ "sogo" ];
|
||||
ensureUsers = [{
|
||||
name = "sogo";
|
||||
ensurePermissions = {
|
||||
"sogo.*" = "ALL PRIVILEGES";
|
||||
};
|
||||
}];
|
||||
};
|
||||
|
||||
services.sogo = {
|
||||
enable = true;
|
||||
timezone = "Europe/Berlin";
|
||||
extraConfig = ''
|
||||
WOWorkersCount = 1;
|
||||
|
||||
SOGoUserSources = (
|
||||
{
|
||||
type = sql;
|
||||
userPasswordAlgorithm = md5;
|
||||
viewURL = "mysql://sogo@%2Frun%2Fmysqld%2Fmysqld.sock/sogo/sogo_users";
|
||||
canAuthenticate = YES;
|
||||
id = users;
|
||||
}
|
||||
);
|
||||
|
||||
SOGoProfileURL = "mysql://sogo@%2Frun%2Fmysqld%2Fmysqld.sock/sogo/sogo_user_profile";
|
||||
OCSFolderInfoURL = "mysql://sogo@%2Frun%2Fmysqld%2Fmysqld.sock/sogo/sogo_folder_info";
|
||||
OCSSessionsFolderURL = "mysql://sogo@%2Frun%2Fmysqld%2Fmysqld.sock/sogo/sogo_sessions_folder";
|
||||
OCSEMailAlarmsFolderURL = "mysql://sogo@%2Frun%2Fmysqld%2Fmysqld.sock/sogo/sogo_alarms_folder";
|
||||
OCSStoreURL = "mysql://sogo@%2Frun%2Fmysqld%2Fmysqld.sock/sogo/sogo_store";
|
||||
OCSAclURL = "mysql://sogo@%2Frun%2Fmysqld%2Fmysqld.sock/sogo/sogo_acl";
|
||||
OCSCacheFolderURL = "mysql://sogo@%2Frun%2Fmysqld%2Fmysqld.sock/sogo/sogo_cache_folder";
|
||||
'';
|
||||
};
|
||||
};
|
||||
};
|
||||
|
||||
testScript = ''
|
||||
start_all()
|
||||
sogo.wait_for_unit("multi-user.target")
|
||||
sogo.wait_for_open_port(20000)
|
||||
sogo.wait_for_open_port(80)
|
||||
sogo.succeed("curl -sSfL http://sogo/SOGo")
|
||||
'';
|
||||
})
|
|
@ -2,13 +2,13 @@
|
|||
|
||||
stdenv.mkDerivation rec {
|
||||
pname = "libobjc2";
|
||||
version = "2.0";
|
||||
version = "1.9";
|
||||
|
||||
src = fetchFromGitHub {
|
||||
owner = "gnustep";
|
||||
repo = "libobjc2";
|
||||
rev = "v${version}";
|
||||
sha256 = "1b4h0a4pqr8j6300qr2wmi33r7ysvp705gs0ypx69hbmifln0mlf";
|
||||
sha256 = "00pscl3ly3rv6alf9vk70kxnnxq2rfgpc1ylcv6cgjs9jxdnrqmn";
|
||||
};
|
||||
|
||||
nativeBuildInputs = [ cmake ];
|
||||
|
|
46
pkgs/development/libraries/sope/default.nix
Normal file
46
pkgs/development/libraries/sope/default.nix
Normal file
|
@ -0,0 +1,46 @@
|
|||
{ gnustep, lib, fetchFromGitHub , libxml2, openssl_1_1
|
||||
, openldap, mysql, libmysqlclient, postgresql }: with lib; gnustep.stdenv.mkDerivation rec {
|
||||
pname = "sope";
|
||||
version = "4.3.2";
|
||||
|
||||
src = fetchFromGitHub {
|
||||
owner = "inverse-inc";
|
||||
repo = pname;
|
||||
rev = "SOPE-${version}";
|
||||
sha256 = "0ny1ihx38gd25w8f3dfybyswvyjfljvb2fhfmkajgg6hhjrkfar2";
|
||||
};
|
||||
|
||||
nativeBuildInputs = [ gnustep.make ];
|
||||
buildInputs = flatten ([ gnustep.base libxml2 openssl_1_1 ]
|
||||
++ optional (openldap != null) openldap
|
||||
++ optionals (mysql != null) [ libmysqlclient mysql ]
|
||||
++ optional (postgresql != null) postgresql);
|
||||
|
||||
postPatch = ''
|
||||
# Exclude NIX_ variables
|
||||
sed -i 's/grep GNUSTEP_/grep ^GNUSTEP_/g' configure
|
||||
'';
|
||||
|
||||
preConfigure = ''
|
||||
export DESTDIR="$out"
|
||||
'';
|
||||
|
||||
configureFlags = [ "--prefix=" "--disable-debug" "--enable-xml" "--with-ssl=ssl" ]
|
||||
++ optional (openldap != null) "--enable-openldap"
|
||||
++ optional (mysql != null) "--enable-mysql"
|
||||
++ optional (postgresql != null) "--enable-postgresql";
|
||||
|
||||
# Yes, this is ugly.
|
||||
preFixup = ''
|
||||
cp -rlPa $out/nix/store/*/* $out
|
||||
rm -rf $out/nix/store
|
||||
'';
|
||||
|
||||
meta = {
|
||||
description = "SOPE is an extensive set of frameworks which form a complete Web application server environment";
|
||||
license = licenses.publicDomain;
|
||||
homepage = "https://github.com/inverse-inc/sope";
|
||||
platforms = platforms.linux;
|
||||
maintainers = with maintainers; [ ajs124 das_j ];
|
||||
};
|
||||
}
|
76
pkgs/servers/web-apps/sogo/default.nix
Normal file
76
pkgs/servers/web-apps/sogo/default.nix
Normal file
|
@ -0,0 +1,76 @@
|
|||
{ gnustep, lib, fetchFromGitHub, fetchpatch, makeWrapper, python2, lndir
|
||||
, openssl_1_1, openldap, sope, libmemcached, curl }: with lib; gnustep.stdenv.mkDerivation rec {
|
||||
pname = "SOGo";
|
||||
version = "4.3.2";
|
||||
|
||||
src = fetchFromGitHub {
|
||||
owner = "inverse-inc";
|
||||
repo = pname;
|
||||
rev = "SOGo-${version}";
|
||||
sha256 = "1xxad23a8zy6w850x5nrrf54db0x73lc9drmc5kpfk870fk2lmr0";
|
||||
};
|
||||
|
||||
nativeBuildInputs = [ gnustep.make makeWrapper python2 ];
|
||||
buildInputs = [ gnustep.base sope openssl_1_1 libmemcached (curl.override { openssl = openssl_1_1; }) ]
|
||||
++ optional (openldap != null) openldap;
|
||||
|
||||
patches = [
|
||||
# TODO: take a closer look at other patches in https://sources.debian.org/patches/sogo/ and https://github.com/Skrupellos/sogo-patches
|
||||
(fetchpatch {
|
||||
url = "https://sources.debian.org/data/main/s/sogo/4.3.0-1/debian/patches/0005-Remove-build-date.patch";
|
||||
sha256 = "0lrh3bkfj3r0brahfkyb0g7zx7r2jjd5cxzjl43nqla0fs09wsh8";
|
||||
})
|
||||
];
|
||||
|
||||
postPatch = ''
|
||||
# Exclude NIX_ variables
|
||||
sed -i 's/grep GNUSTEP_/grep ^GNUSTEP_/g' configure
|
||||
|
||||
# Disable argument verification because $out is not a GNUStep prefix
|
||||
sed -i 's/^validateArgs$//g' configure
|
||||
|
||||
# Patch exception-generating python scripts
|
||||
patchShebangs .
|
||||
|
||||
# Move all GNUStep makefiles to a common directory
|
||||
mkdir -p makefiles
|
||||
cp -r {${gnustep.make},${sope}}/share/GNUstep/Makefiles/* makefiles
|
||||
|
||||
# Modify the search path for GNUStep makefiles
|
||||
find . -type f -name GNUmakefile -exec sed -i "s:\\$.GNUSTEP_MAKEFILES.:$PWD/makefiles:g" {} +
|
||||
'';
|
||||
|
||||
configureFlags = [ "--disable-debug" "--with-ssl=ssl" ];
|
||||
|
||||
preFixup = ''
|
||||
# Create gnustep.conf
|
||||
mkdir -p $out/share/GNUstep
|
||||
cp ${gnustep.make}/etc/GNUstep/GNUstep.conf $out/share/GNUstep/
|
||||
sed -i "s:${gnustep.make}:$out:g" $out/share/GNUstep/GNUstep.conf
|
||||
|
||||
# Link in GNUstep base
|
||||
${lndir}/bin/lndir ${gnustep.base}/lib/GNUstep/ $out/lib/GNUstep/
|
||||
|
||||
# Link in sope
|
||||
${lndir}/bin/lndir ${sope}/ $out/
|
||||
|
||||
# sbin fixup
|
||||
mkdir -p $out/bin
|
||||
mv $out/sbin/* $out/bin
|
||||
rmdir $out/sbin
|
||||
|
||||
# Make sogo find its files
|
||||
for bin in $out/bin/*; do
|
||||
wrapProgram $bin --prefix LD_LIBRARY_PATH : $out/lib/sogo --prefix GNUSTEP_CONFIG_FILE : $out/share/GNUstep/GNUstep.conf
|
||||
done
|
||||
'';
|
||||
|
||||
meta = {
|
||||
description = "SOGo is a very fast and scalable modern collaboration suite (groupware)";
|
||||
license = with licenses; [ gpl2 lgpl21 ];
|
||||
homepage = "https://sogo.nu/";
|
||||
platforms = platforms.linux;
|
||||
maintainers = with maintainers; [ ajs124 das_j ];
|
||||
};
|
||||
}
|
||||
|
|
@ -14612,6 +14612,8 @@ in
|
|||
|
||||
sonic = callPackage ../development/libraries/sonic { };
|
||||
|
||||
sope = callPackage ../development/libraries/sope { };
|
||||
|
||||
soprano = callPackage ../development/libraries/soprano { };
|
||||
|
||||
soqt = callPackage ../development/libraries/soqt { };
|
||||
|
@ -16222,6 +16224,8 @@ in
|
|||
|
||||
smcroute = callPackage ../servers/smcroute { };
|
||||
|
||||
sogo = callPackage ../servers/web-apps/sogo { };
|
||||
|
||||
spawn_fcgi = callPackage ../servers/http/spawn-fcgi { };
|
||||
|
||||
spring-boot-cli = callPackage ../development/tools/spring-boot-cli { };
|
||||
|
|
Loading…
Reference in a new issue