Move all of NixOS to nixos/ in preparation of the repository merge
This commit is contained in:
@@ -0,0 +1,72 @@
|
||||
{ config, pkgs, ... }:
|
||||
let
|
||||
cfg = config.services.fourStoreEndpoint;
|
||||
endpointUser = "fourstorehttp";
|
||||
run = "${pkgs.su}/bin/su -s ${pkgs.stdenv.shell} ${endpointUser} -c";
|
||||
in
|
||||
with pkgs.lib;
|
||||
{
|
||||
|
||||
###### interface
|
||||
|
||||
options = {
|
||||
|
||||
services.fourStoreEndpoint = {
|
||||
|
||||
enable = mkOption {
|
||||
default = false;
|
||||
description = "Whether to enable 4Store SPARQL endpoint.";
|
||||
};
|
||||
|
||||
database = mkOption {
|
||||
default = config.services.fourStore.database;
|
||||
description = "RDF database name to expose via the endpoint. Defaults to local 4Store database name.";
|
||||
};
|
||||
|
||||
listenAddress = mkOption {
|
||||
default = null;
|
||||
description = "IP address to listen on.";
|
||||
};
|
||||
|
||||
port = mkOption {
|
||||
default = 8080;
|
||||
description = "port to listen on.";
|
||||
};
|
||||
|
||||
options = mkOption {
|
||||
default = "";
|
||||
description = "Extra CLI options to pass to 4Store's 4s-httpd process.";
|
||||
};
|
||||
|
||||
};
|
||||
|
||||
};
|
||||
|
||||
|
||||
###### implementation
|
||||
|
||||
config = mkIf cfg.enable (
|
||||
mkAssert (cfg.enable -> cfg.database != "")
|
||||
"Must specify database name" {
|
||||
|
||||
users.extraUsers = singleton
|
||||
{ name = endpointUser;
|
||||
uid = config.ids.uids.fourStoreEndpoint;
|
||||
description = "4Store SPARQL endpoint user";
|
||||
# home = stateDir;
|
||||
};
|
||||
|
||||
services.avahi.enable = true;
|
||||
|
||||
jobs.fourStoreEndpoint = {
|
||||
name = "4store-endpoint";
|
||||
startOn = "filesystem";
|
||||
|
||||
exec = ''
|
||||
${run} '${pkgs.rdf4store}/bin/4s-httpd -D ${cfg.options} ${if cfg.listenAddress!=null then "-H ${cfg.listenAddress}" else "" } -p ${toString cfg.port} ${cfg.database}'
|
||||
'';
|
||||
};
|
||||
|
||||
});
|
||||
|
||||
}
|
||||
@@ -0,0 +1,71 @@
|
||||
{ config, pkgs, ... }:
|
||||
let
|
||||
cfg = config.services.fourStore;
|
||||
stateDir = "/var/lib/4store";
|
||||
fourStoreUser = "fourstore";
|
||||
run = "${pkgs.su}/bin/su -s ${pkgs.stdenv.shell} ${fourStoreUser}";
|
||||
in
|
||||
with pkgs.lib;
|
||||
{
|
||||
|
||||
###### interface
|
||||
|
||||
options = {
|
||||
|
||||
services.fourStore = {
|
||||
|
||||
enable = mkOption {
|
||||
default = false;
|
||||
description = "Whether to enable 4Store RDF database server.";
|
||||
};
|
||||
|
||||
database = mkOption {
|
||||
default = "";
|
||||
description = "RDF database name. If it doesn't exist, it will be created. Databases are stored in ${stateDir}.";
|
||||
};
|
||||
|
||||
options = mkOption {
|
||||
default = "";
|
||||
description = "Extra CLI options to pass to 4Store.";
|
||||
};
|
||||
|
||||
};
|
||||
|
||||
};
|
||||
|
||||
|
||||
###### implementation
|
||||
|
||||
config = mkIf cfg.enable (
|
||||
mkAssert (cfg.enable -> cfg.database != "")
|
||||
"Must specify database name" {
|
||||
|
||||
users.extraUsers = singleton
|
||||
{ name = fourStoreUser;
|
||||
uid = config.ids.uids.fourStore;
|
||||
description = "4Store database user";
|
||||
home = stateDir;
|
||||
};
|
||||
|
||||
services.avahi.enable = true;
|
||||
|
||||
jobs.fourStore = {
|
||||
name = "4store";
|
||||
startOn = "filesystem";
|
||||
|
||||
preStart = ''
|
||||
mkdir -p ${stateDir}/
|
||||
chown ${fourStoreUser} ${stateDir}
|
||||
if ! test -e "${stateDir}/${cfg.database}"; then
|
||||
${run} -c '${pkgs.rdf4store}/bin/4s-backend-setup ${cfg.database}'
|
||||
fi
|
||||
'';
|
||||
|
||||
exec = ''
|
||||
${run} -c '${pkgs.rdf4store}/bin/4s-backend -D ${cfg.options} ${cfg.database}'
|
||||
'';
|
||||
};
|
||||
|
||||
});
|
||||
|
||||
}
|
||||
@@ -0,0 +1,149 @@
|
||||
{ config, pkgs, ... }:
|
||||
|
||||
# TODO: this file needs some additional work - at least you can connect to
|
||||
# firebird ..
|
||||
# Example how to connect:
|
||||
# isql /var/db/firebird/data/your-db.fdb -u sysdba -p <default password>
|
||||
|
||||
# There are at least two ways to run firebird. superserver has been choosen
|
||||
# however there are no strong reasons to prefer this or the other one AFAIK
|
||||
# Eg superserver is said to be most efficiently using resources according to
|
||||
# http://www.firebirdsql.org/manual/qsg25-classic-or-super.html
|
||||
|
||||
with pkgs.lib;
|
||||
|
||||
let
|
||||
|
||||
cfg = config.services.firebird;
|
||||
|
||||
firebird = cfg.package;
|
||||
|
||||
pidFile = "${cfg.pidDir}/firebirdd.pid";
|
||||
|
||||
in
|
||||
|
||||
{
|
||||
|
||||
###### interface
|
||||
|
||||
options = {
|
||||
|
||||
services.firebird = {
|
||||
|
||||
enable = mkOption {
|
||||
default = false;
|
||||
description = "
|
||||
Whether to enable the firebird super server.
|
||||
";
|
||||
};
|
||||
|
||||
package = mkOption {
|
||||
default = pkgs.firebirdSuper;
|
||||
/*
|
||||
Example: <code>package = pkgs.firebirdSuper.override { icu =
|
||||
pkgs.icu; };</code> which is not recommended for compatibility
|
||||
reasons. See comments at the firebirdSuper derivation
|
||||
*/
|
||||
|
||||
description = "
|
||||
Which firebird derivation to use.
|
||||
";
|
||||
};
|
||||
|
||||
port = mkOption {
|
||||
default = "3050";
|
||||
description = "Port of Firebird.";
|
||||
};
|
||||
|
||||
user = mkOption {
|
||||
default = "firebird";
|
||||
description = "User account under which firebird runs.";
|
||||
};
|
||||
|
||||
dataDir = mkOption {
|
||||
default = "/var/db/firebird/data"; # ubuntu is using /var/lib/firebird/2.1/data/.. ?
|
||||
description = "Location where firebird databases are stored.";
|
||||
};
|
||||
|
||||
pidDir = mkOption {
|
||||
default = "/run/firebird";
|
||||
description = "Location of the file which stores the PID of the firebird server.";
|
||||
};
|
||||
|
||||
};
|
||||
|
||||
};
|
||||
|
||||
|
||||
###### implementation
|
||||
|
||||
config = mkIf config.services.firebird.enable {
|
||||
|
||||
users.extraUsers.firebird.description = "Firebird server user";
|
||||
|
||||
environment.systemPackages = [firebird];
|
||||
|
||||
systemd.services.firebird =
|
||||
{ description = "firebird super server";
|
||||
|
||||
wantedBy = [ "multi-user.target" ];
|
||||
|
||||
# TODO: moving security2.fdb into the data directory works, maybe there
|
||||
# is a better way
|
||||
preStart =
|
||||
''
|
||||
secureDir="${cfg.dataDir}/../system"
|
||||
|
||||
mkdir -m 0700 -p \
|
||||
"${cfg.dataDir}" \
|
||||
"${cfg.pidDir}" \
|
||||
/var/log/firebird \
|
||||
"$secureDir"
|
||||
|
||||
if ! test -e "$secureDir/security2.fdb"; then
|
||||
cp ${firebird}/security2.fdb "$secureDir"
|
||||
fi
|
||||
|
||||
chown -R ${cfg.user} "${cfg.pidDir}" "${cfg.dataDir}" "$secureDir" /var/log/firebird
|
||||
chmod -R 700 "${cfg.pidDir}" "${cfg.dataDir}" "$secureDir" /var/log/firebird
|
||||
'';
|
||||
|
||||
serviceConfig.PermissionsStartOnly = true; # preStart must be run as root
|
||||
serviceConfig.User = cfg.user;
|
||||
serviceConfig.ExecStart = ''${firebird}/bin/fbserver -d'';
|
||||
|
||||
# TODO think about shutdown
|
||||
};
|
||||
|
||||
environment.etc."firebird/firebird.msg".source = "${firebird}/firebird.msg";
|
||||
|
||||
# think about this again - and eventually make it an option
|
||||
environment.etc."firebird/firebird.conf".text = ''
|
||||
# RootDirectory = Restrict ${cfg.dataDir}
|
||||
DatabaseAccess = Restrict ${cfg.dataDir}
|
||||
ExternalFileAccess = Restrict ${cfg.dataDir}
|
||||
# what is this? is None allowed?
|
||||
UdfAccess = None
|
||||
# "Native" = traditional interbase/firebird, "mixed" is windows only
|
||||
Authentication = Native
|
||||
|
||||
# defaults to -1 on non Win32
|
||||
#MaxUnflushedWrites = 100
|
||||
#MaxUnflushedWriteTime = 100
|
||||
|
||||
# show trace if trouble occurs (does this require debug build?)
|
||||
# BugcheckAbort = 0
|
||||
# ConnectionTimeout = 180
|
||||
|
||||
#RemoteServiceName = gds_db
|
||||
RemoteServicePort = ${cfg.port}
|
||||
|
||||
# randomly choose port for server Event Notification
|
||||
#RemoteAuxPort = 0
|
||||
# rsetrict connections to a network card:
|
||||
#RemoteBindAddress =
|
||||
# there are some more settings ..
|
||||
'';
|
||||
};
|
||||
|
||||
}
|
||||
@@ -0,0 +1,97 @@
|
||||
{ config, pkgs, ... }:
|
||||
|
||||
with pkgs.lib;
|
||||
|
||||
let
|
||||
|
||||
cfg = config.services.memcached;
|
||||
|
||||
memcached = pkgs.memcached;
|
||||
|
||||
in
|
||||
|
||||
{
|
||||
|
||||
###### interface
|
||||
|
||||
options = {
|
||||
|
||||
services.memcached = {
|
||||
|
||||
enable = mkOption {
|
||||
default = false;
|
||||
description = "
|
||||
Whether to enable Memcached.
|
||||
";
|
||||
};
|
||||
|
||||
user = mkOption {
|
||||
default = "memcached";
|
||||
description = "The user to run Memcached as";
|
||||
};
|
||||
|
||||
listen = mkOption {
|
||||
default = "127.0.0.1";
|
||||
description = "The IP address to bind to";
|
||||
};
|
||||
|
||||
port = mkOption {
|
||||
default = 11211;
|
||||
description = "The port to bind to";
|
||||
};
|
||||
|
||||
socket = mkOption {
|
||||
default = "";
|
||||
description = "Unix socket path to listen on. Setting this will disable network support";
|
||||
example = "/var/run/memcached";
|
||||
};
|
||||
|
||||
maxMemory = mkOption {
|
||||
default = 64;
|
||||
description = "The maximum amount of memory to use for storage, in megabytes.";
|
||||
};
|
||||
|
||||
maxConnections = mkOption {
|
||||
default = 1024;
|
||||
description = "The maximum number of simultaneous connections";
|
||||
};
|
||||
|
||||
extraOptions = mkOption {
|
||||
default = [];
|
||||
description = "A list of extra options that will be added as a suffix when running memcached";
|
||||
};
|
||||
};
|
||||
|
||||
};
|
||||
|
||||
###### implementation
|
||||
|
||||
config = mkIf config.services.memcached.enable {
|
||||
|
||||
users.extraUsers = singleton
|
||||
{ name = cfg.user;
|
||||
description = "Memcached server user";
|
||||
};
|
||||
|
||||
environment.systemPackages = [ memcached ];
|
||||
|
||||
systemd.services.memcached =
|
||||
{ description = "Memcached server";
|
||||
|
||||
wantedBy = [ "multi-user.target" ];
|
||||
after = [ "network.target" ];
|
||||
|
||||
serviceConfig = {
|
||||
ExecStart =
|
||||
let
|
||||
networking = if cfg.socket != ""
|
||||
then "-s ${cfg.socket}"
|
||||
else "-l ${cfg.listen} -p ${toString cfg.port}";
|
||||
in "${memcached}/bin/memcached ${networking} -m ${toString cfg.maxMemory} -c ${toString cfg.maxConnections} ${concatStringsSep " " cfg.extraOptions}";
|
||||
|
||||
User = cfg.user;
|
||||
};
|
||||
};
|
||||
};
|
||||
|
||||
}
|
||||
@@ -0,0 +1,130 @@
|
||||
{ config, pkgs, ... }:
|
||||
|
||||
with pkgs.lib;
|
||||
|
||||
let
|
||||
|
||||
b2s = x: if x then "true" else "false";
|
||||
|
||||
cfg = config.services.mongodb;
|
||||
|
||||
mongodb = cfg.package;
|
||||
|
||||
mongoCnf = pkgs.writeText "mongodb.conf"
|
||||
''
|
||||
bind_ip = ${cfg.bind_ip}
|
||||
${optionalString cfg.quiet "quiet = true"}
|
||||
dbpath = ${cfg.dbpath}
|
||||
logpath = ${cfg.logpath}
|
||||
logappend = ${b2s cfg.logappend}
|
||||
${optionalString (cfg.replSetName != "") "replSet = ${cfg.replSetName}"}
|
||||
'';
|
||||
|
||||
in
|
||||
|
||||
{
|
||||
|
||||
###### interface
|
||||
|
||||
options = {
|
||||
|
||||
services.mongodb = {
|
||||
|
||||
enable = mkOption {
|
||||
default = false;
|
||||
description = "
|
||||
Whether to enable the MongoDB server.
|
||||
";
|
||||
};
|
||||
|
||||
package = mkOption {
|
||||
default = pkgs.mongodb;
|
||||
description = "
|
||||
Which MongoDB derivation to use.
|
||||
";
|
||||
};
|
||||
|
||||
user = mkOption {
|
||||
default = "mongodb";
|
||||
description = "User account under which MongoDB runs";
|
||||
};
|
||||
|
||||
bind_ip = mkOption {
|
||||
default = "127.0.0.1";
|
||||
description = "IP to bind to";
|
||||
};
|
||||
|
||||
quiet = mkOption {
|
||||
default = false;
|
||||
description = "quieter output";
|
||||
};
|
||||
|
||||
dbpath = mkOption {
|
||||
default = "/var/db/mongodb";
|
||||
description = "Location where MongoDB stores its files";
|
||||
};
|
||||
|
||||
logpath = mkOption {
|
||||
default = "/var/log/mongodb/mongod.log";
|
||||
description = "Location where MongoDB stores its logfile";
|
||||
};
|
||||
|
||||
logappend = mkOption {
|
||||
default = true;
|
||||
description = "Append logfile instead over overwriting";
|
||||
};
|
||||
|
||||
replSetName = mkOption {
|
||||
default = "";
|
||||
description = ''
|
||||
If this instance is part of a replica set, set its name here.
|
||||
Otherwise, leave empty to run as single node.
|
||||
'';
|
||||
};
|
||||
};
|
||||
|
||||
};
|
||||
|
||||
|
||||
###### implementation
|
||||
|
||||
config = mkIf config.services.mongodb.enable {
|
||||
|
||||
users.extraUsers = singleton
|
||||
{ name = cfg.user;
|
||||
description = "MongoDB server user";
|
||||
};
|
||||
|
||||
environment.systemPackages = [ mongodb ];
|
||||
|
||||
systemd.services.mongodb_init =
|
||||
{ description = "MongoDB server initialisation";
|
||||
|
||||
wantedBy = [ "mongodb.service" ];
|
||||
before = [ "mongodb.service" ];
|
||||
|
||||
serviceConfig.Type = "oneshot";
|
||||
|
||||
script = ''
|
||||
if ! test -e ${cfg.dbpath}; then
|
||||
install -d -m0700 -o ${cfg.user} ${cfg.dbpath}
|
||||
install -d -m0755 -o ${cfg.user} `dirname ${cfg.logpath}`
|
||||
fi
|
||||
'';
|
||||
};
|
||||
|
||||
systemd.services.mongodb =
|
||||
{ description = "MongoDB server";
|
||||
|
||||
wantedBy = [ "multi-user.target" ];
|
||||
after = [ "network.target" ];
|
||||
|
||||
serviceConfig = {
|
||||
ExecStart = "${mongodb}/bin/mongod --quiet --config ${mongoCnf}";
|
||||
User = cfg.user;
|
||||
};
|
||||
};
|
||||
|
||||
};
|
||||
|
||||
}
|
||||
@@ -0,0 +1,245 @@
|
||||
{ config, pkgs, ... }:
|
||||
|
||||
with pkgs.lib;
|
||||
|
||||
let
|
||||
|
||||
cfg = config.services.mysql;
|
||||
|
||||
mysql = cfg.package;
|
||||
|
||||
pidFile = "${cfg.pidDir}/mysqld.pid";
|
||||
|
||||
mysqldOptions =
|
||||
"--user=${cfg.user} --datadir=${cfg.dataDir} " +
|
||||
"--pid-file=${pidFile}";
|
||||
|
||||
myCnf = pkgs.writeText "my.cnf"
|
||||
''
|
||||
[mysqld]
|
||||
${optionalString (cfg.replication.role == "master" || cfg.replication.role == "slave") "log-bin=mysql-bin"}
|
||||
${optionalString (cfg.replication.role == "master" || cfg.replication.role == "slave") "server-id = ${toString cfg.replication.serverId}"}
|
||||
${optionalString (cfg.replication.role == "slave")
|
||||
''
|
||||
master-host = ${cfg.replication.masterHost}
|
||||
master-user = ${cfg.replication.masterUser}
|
||||
master-password = ${cfg.replication.masterPassword}
|
||||
master-port = ${toString cfg.replication.masterPort}
|
||||
''}
|
||||
${cfg.extraOptions}
|
||||
'';
|
||||
|
||||
in
|
||||
|
||||
{
|
||||
|
||||
###### interface
|
||||
|
||||
options = {
|
||||
|
||||
services.mysql = {
|
||||
|
||||
enable = mkOption {
|
||||
default = false;
|
||||
description = "
|
||||
Whether to enable the MySQL server.
|
||||
";
|
||||
};
|
||||
|
||||
package = mkOption {
|
||||
default = pkgs.mysql;
|
||||
description = "
|
||||
Which MySQL derivation to use.
|
||||
";
|
||||
};
|
||||
|
||||
port = mkOption {
|
||||
default = "3306";
|
||||
description = "Port of MySQL";
|
||||
};
|
||||
|
||||
user = mkOption {
|
||||
default = "mysql";
|
||||
description = "User account under which MySQL runs";
|
||||
};
|
||||
|
||||
dataDir = mkOption {
|
||||
default = "/var/mysql"; # !!! should be /var/db/mysql
|
||||
description = "Location where MySQL stores its table files";
|
||||
};
|
||||
|
||||
pidDir = mkOption {
|
||||
default = "/var/run/mysql";
|
||||
description = "Location of the file which stores the PID of the MySQL server";
|
||||
};
|
||||
|
||||
extraOptions = mkOption {
|
||||
default = "";
|
||||
example = ''
|
||||
key_buffer_size = 6G
|
||||
table_cache = 1600
|
||||
log-error = /var/log/mysql_err.log
|
||||
'';
|
||||
description = ''
|
||||
Provide extra options to the MySQL configuration file.
|
||||
|
||||
Please note, that these options are added to the
|
||||
<literal>[mysqld]</literal> section so you don't need to explicitly
|
||||
state it again.
|
||||
'';
|
||||
};
|
||||
|
||||
initialDatabases = mkOption {
|
||||
default = [];
|
||||
description = "List of database names and their initial schemas that should be used to create databases on the first startup of MySQL";
|
||||
example = [
|
||||
{ name = "foodatabase"; schema = ./foodatabase.sql; }
|
||||
{ name = "bardatabase"; schema = ./bardatabase.sql; }
|
||||
];
|
||||
};
|
||||
|
||||
initialScript = mkOption {
|
||||
default = null;
|
||||
description = "A file containing SQL statements to be executed on the first startup. Can be used for granting certain permissions on the database";
|
||||
};
|
||||
|
||||
# FIXME: remove this option; it's a really bad idea.
|
||||
rootPassword = mkOption {
|
||||
default = null;
|
||||
description = "Path to a file containing the root password, modified on the first startup. Not specifying a root password will leave the root password empty.";
|
||||
};
|
||||
|
||||
replication = {
|
||||
role = mkOption {
|
||||
default = "none";
|
||||
description = "Role of the MySQL server instance. Can be either: master, slave or none";
|
||||
};
|
||||
|
||||
serverId = mkOption {
|
||||
default = 1;
|
||||
description = "Id of the MySQL server instance. This number must be unique for each instance";
|
||||
};
|
||||
|
||||
masterHost = mkOption {
|
||||
description = "Hostname of the MySQL master server";
|
||||
};
|
||||
|
||||
masterUser = mkOption {
|
||||
description = "Username of the MySQL replication user";
|
||||
};
|
||||
|
||||
masterPassword = mkOption {
|
||||
description = "Password of the MySQL replication user";
|
||||
};
|
||||
|
||||
masterPort = mkOption {
|
||||
default = 3306;
|
||||
description = "Port number on which the MySQL master server runs";
|
||||
};
|
||||
};
|
||||
};
|
||||
|
||||
};
|
||||
|
||||
|
||||
###### implementation
|
||||
|
||||
config = mkIf config.services.mysql.enable {
|
||||
|
||||
users.extraUsers.mysql = {
|
||||
description = "MySQL server user";
|
||||
group = "mysql";
|
||||
uid = config.ids.uids.mysql;
|
||||
};
|
||||
|
||||
users.extraGroups.mysql.gid = config.ids.gids.mysql;
|
||||
|
||||
environment.systemPackages = [mysql];
|
||||
|
||||
systemd.services.mysql =
|
||||
{ description = "MySQL Server";
|
||||
|
||||
wantedBy = [ "multi-user.target" ];
|
||||
|
||||
unitConfig.RequiresMountsFor = "${cfg.dataDir}";
|
||||
|
||||
preStart =
|
||||
''
|
||||
if ! test -e ${cfg.dataDir}/mysql; then
|
||||
mkdir -m 0700 -p ${cfg.dataDir}
|
||||
chown -R ${cfg.user} ${cfg.dataDir}
|
||||
${mysql}/bin/mysql_install_db ${mysqldOptions}
|
||||
touch /tmp/mysql_init
|
||||
fi
|
||||
|
||||
mkdir -m 0700 -p ${cfg.pidDir}
|
||||
chown -R ${cfg.user} ${cfg.pidDir}
|
||||
'';
|
||||
|
||||
serviceConfig.ExecStart = "${mysql}/libexec/mysqld --defaults-extra-file=${myCnf} ${mysqldOptions}";
|
||||
|
||||
postStart =
|
||||
''
|
||||
# Wait until the MySQL server is available for use
|
||||
count=0
|
||||
while [ ! -e /tmp/mysql.sock ]
|
||||
do
|
||||
if [ $count -eq 30 ]
|
||||
then
|
||||
echo "Tried 30 times, giving up..."
|
||||
exit 1
|
||||
fi
|
||||
|
||||
echo "MySQL daemon not yet started. Waiting for 1 second..."
|
||||
count=$((count++))
|
||||
sleep 1
|
||||
done
|
||||
|
||||
if [ -f /tmp/mysql_init ]
|
||||
then
|
||||
${concatMapStrings (database:
|
||||
''
|
||||
# Create initial databases
|
||||
if ! test -e "${cfg.dataDir}/${database.name}"; then
|
||||
echo "Creating initial database: ${database.name}"
|
||||
( echo "create database ${database.name};"
|
||||
echo "use ${database.name};"
|
||||
|
||||
if [ -f "${database.schema}" ]
|
||||
then
|
||||
cat ${database.schema}
|
||||
elif [ -d "${database.schema}" ]
|
||||
then
|
||||
cat ${database.schema}/mysql-databases/*.sql
|
||||
fi
|
||||
) | ${mysql}/bin/mysql -u root -N
|
||||
fi
|
||||
'') cfg.initialDatabases}
|
||||
|
||||
${optionalString (cfg.initialScript != null)
|
||||
''
|
||||
# Execute initial script
|
||||
cat ${cfg.initialScript} | ${mysql}/bin/mysql -u root -N
|
||||
''}
|
||||
|
||||
${optionalString (cfg.rootPassword != null)
|
||||
''
|
||||
# Change root password
|
||||
|
||||
( echo "use mysql;"
|
||||
echo "update user set Password=password('$(cat ${cfg.rootPassword})') where User='root';"
|
||||
echo "flush privileges;"
|
||||
) | ${mysql}/bin/mysql -u root -N
|
||||
''}
|
||||
|
||||
rm /tmp/mysql_init
|
||||
fi
|
||||
''; # */
|
||||
|
||||
serviceConfig.ExecStop =
|
||||
"${mysql}/bin/mysqladmin ${optionalString (cfg.rootPassword != null) "--user=root --password=\"$(cat ${cfg.rootPassword})\""} shutdown";
|
||||
};
|
||||
|
||||
};
|
||||
|
||||
}
|
||||
@@ -0,0 +1,248 @@
|
||||
{ config, pkgs, ... }:
|
||||
|
||||
with pkgs.lib;
|
||||
|
||||
let
|
||||
|
||||
cfg = config.services.mysql55;
|
||||
|
||||
mysql = cfg.package;
|
||||
|
||||
pidFile = "${cfg.pidDir}/mysqld.pid";
|
||||
|
||||
mysqldOptions =
|
||||
"--user=${cfg.user} --datadir=${cfg.dataDir} " +
|
||||
"--pid-file=${pidFile}";
|
||||
|
||||
myCnf = pkgs.writeText "my.cnf"
|
||||
''
|
||||
[mysqld]
|
||||
${optionalString (cfg.replication.role == "master" || cfg.replication.role == "slave") "log-bin=mysql-bin"}
|
||||
${optionalString (cfg.replication.role == "master" || cfg.replication.role == "slave") "server-id = ${toString cfg.replication.serverId}"}
|
||||
${cfg.extraOptions}
|
||||
'';
|
||||
|
||||
in
|
||||
|
||||
{
|
||||
|
||||
###### interface
|
||||
|
||||
options = {
|
||||
|
||||
services.mysql55 = {
|
||||
|
||||
enable = mkOption {
|
||||
default = false;
|
||||
description = "
|
||||
Whether to enable the MySQL server.
|
||||
";
|
||||
};
|
||||
|
||||
package = mkOption {
|
||||
default = pkgs.mysql55;
|
||||
description = "
|
||||
Which MySQL derivation to use.
|
||||
";
|
||||
};
|
||||
|
||||
port = mkOption {
|
||||
default = "3306";
|
||||
description = "Port of MySQL";
|
||||
};
|
||||
|
||||
user = mkOption {
|
||||
default = "mysql";
|
||||
description = "User account under which MySQL runs";
|
||||
};
|
||||
|
||||
dataDir = mkOption {
|
||||
default = "/var/mysql"; # !!! should be /var/db/mysql
|
||||
description = "Location where MySQL stores its table files";
|
||||
};
|
||||
|
||||
pidDir = mkOption {
|
||||
default = "/var/run/mysql";
|
||||
description = "Location of the file which stores the PID of the MySQL server";
|
||||
};
|
||||
|
||||
extraOptions = mkOption {
|
||||
default = "";
|
||||
example = ''
|
||||
key_buffer_size = 6G
|
||||
table_cache = 1600
|
||||
log-error = /var/log/mysql_err.log
|
||||
'';
|
||||
description = ''
|
||||
Provide extra options to the MySQL configuration file.
|
||||
|
||||
Please note, that these options are added to the
|
||||
<literal>[mysqld]</literal> section so you don't need to explicitly
|
||||
state it again.
|
||||
'';
|
||||
};
|
||||
|
||||
initialDatabases = mkOption {
|
||||
default = [];
|
||||
description = "List of database names and their initial schemas that should be used to create databases on the first startup of MySQL";
|
||||
example = [
|
||||
{ name = "foodatabase"; schema = ./foodatabase.sql; }
|
||||
{ name = "bardatabase"; schema = ./bardatabase.sql; }
|
||||
];
|
||||
};
|
||||
|
||||
initialScript = mkOption {
|
||||
default = null;
|
||||
description = "A file containing SQL statements to be executed on the first startup. Can be used for granting certain permissions on the database";
|
||||
};
|
||||
|
||||
# FIXME: remove this option; it's a really bad idea.
|
||||
rootPassword = mkOption {
|
||||
default = null;
|
||||
description = "Path to a file containing the root password, modified on the first startup. Not specifying a root password will leave the root password empty.";
|
||||
};
|
||||
|
||||
replication = {
|
||||
role = mkOption {
|
||||
default = "none";
|
||||
description = "Role of the MySQL server instance. Can be either: master, slave or none";
|
||||
};
|
||||
|
||||
serverId = mkOption {
|
||||
default = 1;
|
||||
description = "Id of the MySQL server instance. This number must be unique for each instance";
|
||||
};
|
||||
|
||||
masterHost = mkOption {
|
||||
description = "Hostname of the MySQL master server";
|
||||
};
|
||||
|
||||
masterUser = mkOption {
|
||||
description = "Username of the MySQL replication user";
|
||||
};
|
||||
|
||||
masterPassword = mkOption {
|
||||
description = "Password of the MySQL replication user";
|
||||
};
|
||||
|
||||
masterPort = mkOption {
|
||||
default = 3306;
|
||||
description = "Port number on which the MySQL master server runs";
|
||||
};
|
||||
};
|
||||
};
|
||||
|
||||
};
|
||||
|
||||
|
||||
###### implementation
|
||||
|
||||
config = mkIf config.services.mysql55.enable {
|
||||
|
||||
users.extraUsers.mysql = {
|
||||
description = "MySQL server user";
|
||||
group = "mysql";
|
||||
uid = config.ids.uids.mysql;
|
||||
};
|
||||
|
||||
users.extraGroups.mysql.gid = config.ids.gids.mysql;
|
||||
|
||||
environment.systemPackages = [mysql];
|
||||
|
||||
systemd.services.mysql =
|
||||
{ description = "MySQL Server";
|
||||
|
||||
wantedBy = [ "multi-user.target" ];
|
||||
|
||||
unitConfig.RequiresMountsFor = "${cfg.dataDir}";
|
||||
|
||||
preStart =
|
||||
''
|
||||
if ! test -e ${cfg.dataDir}/mysql; then
|
||||
mkdir -m 0700 -p ${cfg.dataDir}
|
||||
chown -R ${cfg.user} ${cfg.dataDir}
|
||||
${mysql}/bin/mysql_install_db ${mysqldOptions}
|
||||
touch /tmp/mysql_init
|
||||
fi
|
||||
|
||||
mkdir -m 0700 -p ${cfg.pidDir}
|
||||
chown -R ${cfg.user} ${cfg.pidDir}
|
||||
'';
|
||||
|
||||
serviceConfig.ExecStart = "${mysql}/bin/mysqld --defaults-extra-file=${myCnf} ${mysqldOptions}";
|
||||
|
||||
postStart =
|
||||
''
|
||||
# Wait until the MySQL server is available for use
|
||||
count=0
|
||||
while [ ! -e /tmp/mysql.sock ]
|
||||
do
|
||||
if [ $count -eq 30 ]
|
||||
then
|
||||
echo "Tried 30 times, giving up..."
|
||||
exit 1
|
||||
fi
|
||||
|
||||
echo "MySQL daemon not yet started. Waiting for 1 second..."
|
||||
count=$((count++))
|
||||
sleep 1
|
||||
done
|
||||
|
||||
if [ -f /tmp/mysql_init ]
|
||||
then
|
||||
${concatMapStrings (database:
|
||||
''
|
||||
# Create initial databases
|
||||
if ! test -e "${cfg.dataDir}/${database.name}"; then
|
||||
echo "Creating initial database: ${database.name}"
|
||||
( echo "create database ${database.name};"
|
||||
echo "use ${database.name};"
|
||||
|
||||
if [ -f "${database.schema}" ]
|
||||
then
|
||||
cat ${database.schema}
|
||||
elif [ -d "${database.schema}" ]
|
||||
then
|
||||
cat ${database.schema}/mysql-databases/*.sql
|
||||
fi
|
||||
) | ${mysql}/bin/mysql -u root -N
|
||||
fi
|
||||
'') cfg.initialDatabases}
|
||||
|
||||
${optionalString (cfg.replication.role == "slave")
|
||||
''
|
||||
# Set up the replication master
|
||||
|
||||
( echo "stop slave;"
|
||||
echo "change master to master_host='${cfg.replication.masterHost}', master_user='${cfg.replication.masterUser}', master_password='${cfg.replication.masterPassword}';"
|
||||
echo "start slave;"
|
||||
) | ${mysql}/bin/mysql -u root -N
|
||||
''}
|
||||
|
||||
${optionalString (cfg.initialScript != null)
|
||||
''
|
||||
# Execute initial script
|
||||
cat ${cfg.initialScript} | ${mysql}/bin/mysql -u root -N
|
||||
''}
|
||||
|
||||
${optionalString (cfg.rootPassword != null)
|
||||
''
|
||||
# Change root password
|
||||
|
||||
( echo "use mysql;"
|
||||
echo "update user set Password=password('$(cat ${cfg.rootPassword})') where User='root';"
|
||||
echo "flush privileges;"
|
||||
) | ${mysql}/bin/mysql -u root -N
|
||||
''}
|
||||
|
||||
rm /tmp/mysql_init
|
||||
fi
|
||||
''; # */
|
||||
|
||||
serviceConfig.ExecStop =
|
||||
"${mysql}/bin/mysqladmin ${optionalString (cfg.rootPassword != null) "--user=root --password=\"$(cat ${cfg.rootPassword})\""} shutdown";
|
||||
};
|
||||
|
||||
};
|
||||
|
||||
}
|
||||
@@ -0,0 +1,58 @@
|
||||
{ config, pkgs, ... }:
|
||||
|
||||
with pkgs.lib;
|
||||
|
||||
let
|
||||
|
||||
cfg = config.services.openldap;
|
||||
openldap = pkgs.openldap;
|
||||
|
||||
configFile = pkgs.writeText "slapd.conf" cfg.extraConfig;
|
||||
|
||||
in
|
||||
|
||||
{
|
||||
|
||||
###### interface
|
||||
|
||||
options = {
|
||||
|
||||
services.openldap = {
|
||||
|
||||
enable = mkOption {
|
||||
default = false;
|
||||
description = "
|
||||
Whether to enable the ldap server.
|
||||
";
|
||||
};
|
||||
|
||||
extraConfig = mkOption {
|
||||
default = "";
|
||||
description = "
|
||||
sldapd.conf configuration
|
||||
";
|
||||
};
|
||||
};
|
||||
|
||||
};
|
||||
|
||||
|
||||
###### implementation
|
||||
|
||||
config = mkIf config.services.openldap.enable {
|
||||
|
||||
environment.systemPackages = [ openldap ];
|
||||
|
||||
systemd.services.openldap = {
|
||||
description = "LDAP server";
|
||||
wantedBy = [ "multi-user.target" ];
|
||||
after = [ "network.target" ];
|
||||
preStart = ''
|
||||
mkdir -p /var/run/slapd
|
||||
'';
|
||||
serviceConfig.ExecStart = "${openldap}/libexec/slapd -d 0 -f ${configFile}";
|
||||
};
|
||||
|
||||
};
|
||||
|
||||
}
|
||||
@@ -0,0 +1,232 @@
|
||||
{ config, pkgs, ... }:
|
||||
|
||||
with pkgs.lib;
|
||||
|
||||
let
|
||||
|
||||
cfg = config.services.postgresql;
|
||||
|
||||
# see description of extraPlugins
|
||||
postgresqlAndPlugins = pg:
|
||||
if cfg.extraPlugins == [] then pg
|
||||
else pkgs.buildEnv {
|
||||
name = "postgresql-and-plugins-${(builtins.parseDrvName pg.name).version}";
|
||||
paths = [ pg ] ++ cfg.extraPlugins;
|
||||
postBuild =
|
||||
''
|
||||
mkdir -p $out/bin
|
||||
rm $out/bin/{pg_config,postgres,pg_ctl}
|
||||
cp --target-directory=$out/bin ${pg}/bin/{postgres,pg_config,pg_ctl}
|
||||
'';
|
||||
};
|
||||
|
||||
postgresql = postgresqlAndPlugins cfg.package;
|
||||
|
||||
flags = optional cfg.enableTCPIP "-i";
|
||||
|
||||
# The main PostgreSQL configuration file.
|
||||
configFile = pkgs.writeText "postgresql.conf"
|
||||
''
|
||||
hba_file = '${pkgs.writeText "pg_hba.conf" cfg.authentication}'
|
||||
ident_file = '${pkgs.writeText "pg_ident.conf" cfg.identMap}'
|
||||
log_destination = 'stderr'
|
||||
${cfg.extraConfig}
|
||||
'';
|
||||
|
||||
pre84 = versionOlder (builtins.parseDrvName postgresql.name).version "8.4";
|
||||
|
||||
in
|
||||
|
||||
{
|
||||
|
||||
###### interface
|
||||
|
||||
options = {
|
||||
|
||||
services.postgresql = {
|
||||
|
||||
enable = mkOption {
|
||||
default = false;
|
||||
description = ''
|
||||
Whether to run PostgreSQL.
|
||||
'';
|
||||
};
|
||||
|
||||
package = mkOption {
|
||||
example = literalExample "pkgs.postgresql92";
|
||||
description = ''
|
||||
PostgreSQL package to use.
|
||||
'';
|
||||
};
|
||||
|
||||
port = mkOption {
|
||||
default = "5432";
|
||||
description = ''
|
||||
Port for PostgreSQL.
|
||||
'';
|
||||
};
|
||||
|
||||
dataDir = mkOption {
|
||||
default = "/var/db/postgresql";
|
||||
description = ''
|
||||
Data directory for PostgreSQL.
|
||||
'';
|
||||
};
|
||||
|
||||
authentication = mkOption {
|
||||
default = "";
|
||||
description = ''
|
||||
Defines how users authenticate themselves to the server.
|
||||
'';
|
||||
};
|
||||
|
||||
identMap = mkOption {
|
||||
default = "";
|
||||
description = ''
|
||||
Defines the mapping from system users to database users.
|
||||
'';
|
||||
};
|
||||
|
||||
initialScript = mkOption {
|
||||
default = null;
|
||||
type = types.nullOr types.path;
|
||||
description = ''
|
||||
A file containing SQL statements to execute on first startup.
|
||||
'';
|
||||
};
|
||||
|
||||
authMethod = mkOption {
|
||||
default = " ident sameuser ";
|
||||
description = ''
|
||||
How to authorize users.
|
||||
Note: ident needs absolute trust to all allowed client hosts.
|
||||
'';
|
||||
};
|
||||
|
||||
enableTCPIP = mkOption {
|
||||
default = false;
|
||||
description = ''
|
||||
Whether to run PostgreSQL with -i flag to enable TCP/IP connections.
|
||||
'';
|
||||
};
|
||||
|
||||
extraPlugins = mkOption {
|
||||
default = [];
|
||||
example = "pkgs.postgis"; # of course don't use a string here!
|
||||
description = ''
|
||||
When this list contains elements a new store path is created.
|
||||
PostgreSQL and the elments are symlinked into it. Then pg_config,
|
||||
postgres and pc_ctl are copied to make them use the new
|
||||
$out/lib directory as pkglibdir. This makes it possible to use postgis
|
||||
without patching the .sql files which reference $libdir/postgis-1.5.
|
||||
'';
|
||||
# Note: the duplication of executables is about 4MB size.
|
||||
# So a nicer solution was patching postgresql to allow setting the
|
||||
# libdir explicitely.
|
||||
};
|
||||
|
||||
extraConfig = mkOption {
|
||||
default = "";
|
||||
description = "Additional text to be appended to <filename>postgresql.conf</filename>.";
|
||||
};
|
||||
|
||||
recoveryConfig = mkOption {
|
||||
default = null;
|
||||
type = types.nullOr types.string;
|
||||
description = ''
|
||||
Values to put into recovery.conf file.
|
||||
'';
|
||||
};
|
||||
};
|
||||
|
||||
};
|
||||
|
||||
|
||||
###### implementation
|
||||
|
||||
config = mkIf config.services.postgresql.enable {
|
||||
|
||||
services.postgresql.authentication =
|
||||
''
|
||||
# Generated file; do not edit!
|
||||
local all all ident ${optionalString pre84 "sameuser"}
|
||||
host all all 127.0.0.1/32 md5
|
||||
host all all ::1/128 md5
|
||||
'';
|
||||
|
||||
users.extraUsers.postgres =
|
||||
{ name = "postgres";
|
||||
uid = config.ids.uids.postgres;
|
||||
group = "postgres";
|
||||
description = "PostgreSQL server user";
|
||||
};
|
||||
|
||||
users.extraGroups.postgres.gid = config.ids.gids.postgres;
|
||||
|
||||
environment.systemPackages = [postgresql];
|
||||
|
||||
systemd.services.postgresql =
|
||||
{ description = "PostgreSQL Server";
|
||||
|
||||
wantedBy = [ "multi-user.target" ];
|
||||
after = [ "network.target" ];
|
||||
|
||||
environment.PGDATA = cfg.dataDir;
|
||||
|
||||
path = [ pkgs.su postgresql ];
|
||||
|
||||
preStart =
|
||||
''
|
||||
# Initialise the database.
|
||||
if ! test -e ${cfg.dataDir}; then
|
||||
mkdir -m 0700 -p ${cfg.dataDir}
|
||||
chown -R postgres ${cfg.dataDir}
|
||||
su -s ${pkgs.stdenv.shell} postgres -c 'initdb -U root'
|
||||
rm -f ${cfg.dataDir}/*.conf
|
||||
touch "${cfg.dataDir}/.first_startup"
|
||||
fi
|
||||
|
||||
ln -sfn "${configFile}" "${cfg.dataDir}/postgresql.conf"
|
||||
${optionalString (cfg.recoveryConfig != null) ''
|
||||
ln -sfn "${pkgs.writeText "recovery.conf" cfg.recoveryConfig}" \
|
||||
"${cfg.dataDir}/recovery.conf"
|
||||
''}
|
||||
''; # */
|
||||
|
||||
serviceConfig =
|
||||
{ ExecStart = "@${postgresql}/bin/postgres postgres ${toString flags}";
|
||||
User = "postgres";
|
||||
Group = "postgres";
|
||||
PermissionsStartOnly = true;
|
||||
|
||||
# Shut down Postgres using SIGINT ("Fast Shutdown mode"). See
|
||||
# http://www.postgresql.org/docs/current/static/server-shutdown.html
|
||||
KillSignal = "SIGINT";
|
||||
|
||||
# Give Postgres a decent amount of time to clean up after
|
||||
# receiving systemd's SIGINT.
|
||||
TimeoutSec = 120;
|
||||
};
|
||||
|
||||
# Wait for PostgreSQL to be ready to accept connections.
|
||||
postStart =
|
||||
''
|
||||
while ! psql postgres -c "" 2> /dev/null; do
|
||||
if ! kill -0 "$MAINPID"; then exit 1; fi
|
||||
sleep 0.1
|
||||
done
|
||||
|
||||
if test -e "${cfg.dataDir}/.first_startup"; then
|
||||
${optionalString (cfg.initialScript != null) ''
|
||||
cat "${cfg.initialScript}" | psql postgres
|
||||
''}
|
||||
rm -f "${cfg.dataDir}/.first_startup"
|
||||
fi
|
||||
'';
|
||||
|
||||
unitConfig.RequiresMountsFor = "${cfg.dataDir}";
|
||||
};
|
||||
|
||||
};
|
||||
|
||||
}
|
||||
@@ -0,0 +1,216 @@
|
||||
{ config, pkgs, ... }:
|
||||
|
||||
with pkgs.lib;
|
||||
|
||||
let
|
||||
cfg = config.services.redis;
|
||||
redisBool = b: if b then "yes" else "no";
|
||||
condOption = name: value: if value != null then "${name} ${toString value}" else "";
|
||||
|
||||
redisConfig = pkgs.writeText "redis.conf" ''
|
||||
pidfile ${cfg.pidFile}
|
||||
port ${toString cfg.port}
|
||||
${condOption "bind" cfg.bind}
|
||||
${condOption "unixsocket" cfg.unixSocket}
|
||||
loglevel ${cfg.logLevel}
|
||||
logfile ${cfg.logfile}
|
||||
databases ${toString cfg.databases}
|
||||
${concatMapStrings (d: "save ${toString (builtins.elemAt d 0)} ${toString (builtins.elemAt d 1)}\n") cfg.save}
|
||||
dbfilename ${cfg.dbFilename}
|
||||
dir ${toString cfg.dbpath}
|
||||
${if cfg.slaveOf != null then "slaveof ${cfg.slaveOf.ip} ${toString cfg.slaveOf.port}" else ""}
|
||||
${condOption "masterauth" cfg.masterAuth}
|
||||
${condOption "requirepass" cfg.requirePass}
|
||||
appendOnly ${redisBool cfg.appendOnly}
|
||||
appendfsync ${cfg.appendFsync}
|
||||
slowlog-log-slower-than ${toString cfg.slowLogLogSlowerThan}
|
||||
slowlog-max-len ${toString cfg.slowLogMaxLen}
|
||||
${cfg.extraConfig}
|
||||
'';
|
||||
in
|
||||
{
|
||||
|
||||
###### interface
|
||||
|
||||
options = {
|
||||
|
||||
services.redis = {
|
||||
|
||||
enable = mkOption {
|
||||
default = false;
|
||||
description = "Whether to enable the Redis server.";
|
||||
};
|
||||
|
||||
package = mkOption {
|
||||
default = pkgs.redis;
|
||||
description = "Which Redis derivation to use.";
|
||||
};
|
||||
|
||||
user = mkOption {
|
||||
default = "redis";
|
||||
description = "User account under which Redis runs";
|
||||
};
|
||||
|
||||
pidFile = mkOption {
|
||||
default = "/var/lib/redis/redis.pid";
|
||||
description = "";
|
||||
};
|
||||
|
||||
port = mkOption {
|
||||
default = 6379;
|
||||
description = "The port for Redis to listen to";
|
||||
type = with types; int;
|
||||
};
|
||||
|
||||
bind = mkOption {
|
||||
default = null; # All interfaces
|
||||
description = "The IP interface to bind to";
|
||||
example = "127.0.0.1";
|
||||
};
|
||||
|
||||
unixSocket = mkOption {
|
||||
default = null;
|
||||
description = "The path to the socket to bind to";
|
||||
example = "/var/run/redis.sock";
|
||||
};
|
||||
|
||||
logLevel = mkOption {
|
||||
default = "notice"; # debug, verbose, notice, warning
|
||||
example = "debug";
|
||||
description = "Specify the server verbosity level, options: debug, verbose, notice, warning";
|
||||
type = with types; string;
|
||||
};
|
||||
|
||||
logfile = mkOption {
|
||||
default = "stdout";
|
||||
description = "Specify the log file name. Also 'stdout' can be used to force Redis to log on the standard output.";
|
||||
example = "/var/log/redis.log";
|
||||
type = with types; string;
|
||||
};
|
||||
|
||||
databases = mkOption {
|
||||
default = 16;
|
||||
description = "Set the number of databases.";
|
||||
type = with types; int;
|
||||
};
|
||||
|
||||
save = mkOption {
|
||||
default = [ [900 1] [300 10] [60 10000] ];
|
||||
description = "The schedule in which data is persisted to disk, represented as a list of lists where the first element represent the amount of seconds and the second the number of changes.";
|
||||
example = [ [900 1] [300 10] [60 10000] ];
|
||||
};
|
||||
|
||||
dbFilename = mkOption {
|
||||
default = "dump.rdb";
|
||||
description = "The filename where to dump the DB";
|
||||
type = with types; string;
|
||||
};
|
||||
|
||||
dbpath = mkOption {
|
||||
default = "/var/lib/redis";
|
||||
description = "The DB will be written inside this directory, with the filename specified using the 'dbFilename' configuration";
|
||||
type = with types; string;
|
||||
};
|
||||
|
||||
slaveOf = mkOption {
|
||||
default = null; # { ip, port }
|
||||
description = "An attribute set with two attributes: ip and port to which this redis instance acts as a slave";
|
||||
example = { ip = "192.168.1.100"; port = 6379; };
|
||||
};
|
||||
|
||||
masterAuth = mkOption {
|
||||
default = null;
|
||||
description = ''If the master is password protected (using the requirePass configuration)
|
||||
it is possible to tell the slave to authenticate before starting the replication synchronization
|
||||
process, otherwise the master will refuse the slave request.
|
||||
(STORED PLAIN TEXT, WORLD-READABLE IN NIX STORE)'';
|
||||
};
|
||||
|
||||
requirePass = mkOption {
|
||||
default = null;
|
||||
description = "Password for database (STORED PLAIN TEXT, WORLD-READABLE IN NIX STORE)";
|
||||
example = "letmein!";
|
||||
};
|
||||
|
||||
appendOnly = mkOption {
|
||||
default = false;
|
||||
description = "By default data is only periodically persisted to disk, enable this option to use an append-only file for improved persistence.";
|
||||
type = with types; bool;
|
||||
};
|
||||
|
||||
appendOnlyFilename = mkOption {
|
||||
default = "appendonly.aof";
|
||||
description = "Filename for the append-only file (stored inside of dbpath)";
|
||||
type = with types; string;
|
||||
};
|
||||
|
||||
appendFsync = mkOption {
|
||||
default = "everysec"; # no, always, everysec
|
||||
description = "How often to fsync the append-only log, options: no, always, everysec";
|
||||
type = with types; string;
|
||||
};
|
||||
|
||||
slowLogLogSlowerThan = mkOption {
|
||||
default = 10000;
|
||||
description = "Log queries whose execution take longer than X in milliseconds";
|
||||
example = 1000;
|
||||
type = with types; int;
|
||||
};
|
||||
|
||||
slowLogMaxLen = mkOption {
|
||||
default = 128;
|
||||
description = "Maximum number of items to keep in slow log";
|
||||
type = with types; int;
|
||||
};
|
||||
|
||||
extraConfig = mkOption {
|
||||
default = "";
|
||||
description = "Extra configuration options for redis.conf";
|
||||
type = with types; string;
|
||||
};
|
||||
};
|
||||
|
||||
};
|
||||
|
||||
|
||||
###### implementation
|
||||
|
||||
config = mkIf config.services.redis.enable {
|
||||
|
||||
users.extraUsers = singleton
|
||||
{ name = cfg.user;
|
||||
description = "Redis database user";
|
||||
};
|
||||
|
||||
environment.systemPackages = [ cfg.package ];
|
||||
|
||||
systemd.services.redis_init =
|
||||
{ description = "Redis server initialisation";
|
||||
|
||||
wantedBy = [ "redis.service" ];
|
||||
before = [ "redis.service" ];
|
||||
|
||||
serviceConfig.Type = "oneshot";
|
||||
|
||||
script = ''
|
||||
if ! test -e ${cfg.dbpath}; then
|
||||
install -d -m0700 -o ${cfg.user} ${cfg.dbpath}
|
||||
fi
|
||||
'';
|
||||
};
|
||||
|
||||
systemd.services.redis =
|
||||
{ description = "Redis server";
|
||||
|
||||
wantedBy = [ "multi-user.target" ];
|
||||
after = [ "network.target" ];
|
||||
|
||||
serviceConfig = {
|
||||
ExecStart = "${cfg.package}/bin/redis-server ${redisConfig}";
|
||||
User = cfg.user;
|
||||
};
|
||||
};
|
||||
|
||||
};
|
||||
|
||||
}
|
||||
@@ -0,0 +1,98 @@
|
||||
{ config, pkgs, ... }:
|
||||
let
|
||||
cfg = config.services.virtuoso;
|
||||
virtuosoUser = "virtuoso";
|
||||
stateDir = "/var/lib/virtuoso";
|
||||
in
|
||||
with pkgs.lib;
|
||||
{
|
||||
|
||||
###### interface
|
||||
|
||||
options = {
|
||||
|
||||
services.virtuoso = {
|
||||
|
||||
enable = mkOption {
|
||||
default = false;
|
||||
description = "Whether to enable Virtuoso Opensource database server.";
|
||||
};
|
||||
|
||||
config = mkOption {
|
||||
default = "";
|
||||
description = "Extra options to put into Virtuoso configuration file.";
|
||||
};
|
||||
|
||||
parameters = mkOption {
|
||||
default = "";
|
||||
description = "Extra options to put into [Parameters] section of Virtuoso configuration file.";
|
||||
};
|
||||
|
||||
listenAddress = mkOption {
|
||||
default = "1111";
|
||||
example = "myserver:1323";
|
||||
description = "ip:port or port to listen on.";
|
||||
};
|
||||
|
||||
httpListenAddress = mkOption {
|
||||
default = null;
|
||||
example = "myserver:8080";
|
||||
description = "ip:port or port for Virtuoso HTTP server to listen on.";
|
||||
};
|
||||
|
||||
dirsAllowed = mkOption {
|
||||
default = null;
|
||||
example = "/www, /home/";
|
||||
description = "A list of directories Virtuoso is allowed to access";
|
||||
};
|
||||
};
|
||||
|
||||
};
|
||||
|
||||
|
||||
###### implementation
|
||||
|
||||
config = mkIf cfg.enable {
|
||||
|
||||
users.extraUsers = singleton
|
||||
{ name = virtuosoUser;
|
||||
uid = config.ids.uids.virtuoso;
|
||||
description = "virtuoso user";
|
||||
home = stateDir;
|
||||
};
|
||||
|
||||
jobs.virtuoso = {
|
||||
name = "virtuoso";
|
||||
startOn = "filesystem";
|
||||
|
||||
preStart = ''
|
||||
mkdir -p ${stateDir}
|
||||
chown ${virtuosoUser} ${stateDir}
|
||||
'';
|
||||
|
||||
script = ''
|
||||
cd ${stateDir}
|
||||
${pkgs.virtuoso}/bin/virtuoso-t +foreground +configfile ${pkgs.writeText "virtuoso.ini" cfg.config}
|
||||
'';
|
||||
};
|
||||
|
||||
services.virtuoso.config = ''
|
||||
[Database]
|
||||
DatabaseFile=${stateDir}/x-virtuoso.db
|
||||
TransactionFile=${stateDir}/x-virtuoso.trx
|
||||
ErrorLogFile=${stateDir}/x-virtuoso.log
|
||||
xa_persistent_file=${stateDir}/x-virtuoso.pxa
|
||||
|
||||
[Parameters]
|
||||
ServerPort=${cfg.listenAddress}
|
||||
RunAs=${virtuosoUser}
|
||||
${optionalString (cfg.dirsAllowed != null) "DirsAllowed=${cfg.dirsAllowed}"}
|
||||
${cfg.parameters}
|
||||
|
||||
[HTTPServer]
|
||||
${optionalString (cfg.httpListenAddress != null) "ServerPort=${cfg.httpListenAddress}"}
|
||||
'';
|
||||
|
||||
};
|
||||
|
||||
}
|
||||
Reference in New Issue
Block a user