uboot: (firmwareOdroidC2/C4) don't invoke patch tool, use patches = [] instead

https://github.com/NixOS/nixpkgs/blob/master/pkgs/stdenv/generic/setup.sh#L948
this can do it nicely.

Signed-off-by: Anton Arapov <anton@deadbeef.mx>
This commit is contained in:
Anton Arapov 2021-04-03 12:58:10 +02:00 committed by Alan Daniels
commit 56de2bcd43
30691 changed files with 3076956 additions and 0 deletions

View file

@ -0,0 +1,95 @@
{ config, lib, pkgs, ... }:
with lib;
let
cfg = config.services.elasticsearch-curator;
curatorConfig = pkgs.writeTextFile {
name = "config.yaml";
text = ''
---
# Remember, leave a key empty if there is no value. None will be a string,
# not a Python "NoneType"
client:
hosts: ${builtins.toJSON cfg.hosts}
port: ${toString cfg.port}
url_prefix:
use_ssl: False
certificate:
client_cert:
client_key:
ssl_no_validate: False
http_auth:
timeout: 30
master_only: False
logging:
loglevel: INFO
logfile:
logformat: default
blacklist: ['elasticsearch', 'urllib3']
'';
};
curatorAction = pkgs.writeTextFile {
name = "action.yaml";
text = cfg.actionYAML;
};
in {
options.services.elasticsearch-curator = {
enable = mkEnableOption "elasticsearch curator";
interval = mkOption {
description = "The frequency to run curator, a systemd.time such as 'hourly'";
default = "hourly";
type = types.str;
};
hosts = mkOption {
description = "a list of elasticsearch hosts to connect to";
type = types.listOf types.str;
default = ["localhost"];
};
port = mkOption {
description = "the port that elasticsearch is listening on";
type = types.int;
default = 9200;
};
actionYAML = mkOption {
description = "curator action.yaml file contents, alternatively use curator-cli which takes a simple action command";
type = types.lines;
example = ''
---
actions:
1:
action: delete_indices
description: >-
Delete indices older than 45 days (based on index name), for logstash-
prefixed indices. Ignore the error if the filter does not result in an
actionable list of indices (ignore_empty_list) and exit cleanly.
options:
ignore_empty_list: True
disable_action: False
filters:
- filtertype: pattern
kind: prefix
value: logstash-
- filtertype: age
source: name
direction: older
timestring: '%Y.%m.%d'
unit: days
unit_count: 45
'';
};
};
config = mkIf cfg.enable {
systemd.services.elasticsearch-curator = {
startAt = cfg.interval;
serviceConfig = {
ExecStart =
"${pkgs.elasticsearch-curator}/bin/curator" +
" --config ${curatorConfig} ${curatorAction}";
};
};
};
}

View file

@ -0,0 +1,239 @@
{ config, lib, pkgs, ... }:
with lib;
let
cfg = config.services.elasticsearch;
es7 = builtins.compareVersions cfg.package.version "7" >= 0;
esConfig = ''
network.host: ${cfg.listenAddress}
cluster.name: ${cfg.cluster_name}
${lib.optionalString cfg.single_node "discovery.type: single-node"}
${lib.optionalString (cfg.single_node && es7) "gateway.auto_import_dangling_indices: true"}
http.port: ${toString cfg.port}
transport.port: ${toString cfg.tcp_port}
${cfg.extraConf}
'';
configDir = cfg.dataDir + "/config";
elasticsearchYml = pkgs.writeTextFile {
name = "elasticsearch.yml";
text = esConfig;
};
loggingConfigFilename = "log4j2.properties";
loggingConfigFile = pkgs.writeTextFile {
name = loggingConfigFilename;
text = cfg.logging;
};
esPlugins = pkgs.buildEnv {
name = "elasticsearch-plugins";
paths = cfg.plugins;
postBuild = "${pkgs.coreutils}/bin/mkdir -p $out/plugins";
};
in
{
###### interface
options.services.elasticsearch = {
enable = mkOption {
description = "Whether to enable elasticsearch.";
default = false;
type = types.bool;
};
package = mkOption {
description = "Elasticsearch package to use.";
default = pkgs.elasticsearch;
defaultText = literalExpression "pkgs.elasticsearch";
type = types.package;
};
listenAddress = mkOption {
description = "Elasticsearch listen address.";
default = "127.0.0.1";
type = types.str;
};
port = mkOption {
description = "Elasticsearch port to listen for HTTP traffic.";
default = 9200;
type = types.int;
};
tcp_port = mkOption {
description = "Elasticsearch port for the node to node communication.";
default = 9300;
type = types.int;
};
cluster_name = mkOption {
description = "Elasticsearch name that identifies your cluster for auto-discovery.";
default = "elasticsearch";
type = types.str;
};
single_node = mkOption {
description = "Start a single-node cluster";
default = true;
type = types.bool;
};
extraConf = mkOption {
description = "Extra configuration for elasticsearch.";
default = "";
type = types.str;
example = ''
node.name: "elasticsearch"
node.master: true
node.data: false
'';
};
logging = mkOption {
description = "Elasticsearch logging configuration.";
default = ''
logger.action.name = org.elasticsearch.action
logger.action.level = info
appender.console.type = Console
appender.console.name = console
appender.console.layout.type = PatternLayout
appender.console.layout.pattern = [%d{ISO8601}][%-5p][%-25c{1.}] %marker%m%n
rootLogger.level = info
rootLogger.appenderRef.console.ref = console
'';
type = types.str;
};
dataDir = mkOption {
type = types.path;
default = "/var/lib/elasticsearch";
description = ''
Data directory for elasticsearch.
'';
};
extraCmdLineOptions = mkOption {
description = "Extra command line options for the elasticsearch launcher.";
default = [ ];
type = types.listOf types.str;
};
extraJavaOptions = mkOption {
description = "Extra command line options for Java.";
default = [ ];
type = types.listOf types.str;
example = [ "-Djava.net.preferIPv4Stack=true" ];
};
plugins = mkOption {
description = "Extra elasticsearch plugins";
default = [ ];
type = types.listOf types.package;
example = lib.literalExpression "[ pkgs.elasticsearchPlugins.discovery-ec2 ]";
};
restartIfChanged = mkOption {
type = types.bool;
description = ''
Automatically restart the service on config change.
This can be set to false to defer restarts on a server or cluster.
Please consider the security implications of inadvertently running an older version,
and the possibility of unexpected behavior caused by inconsistent versions across a cluster when disabling this option.
'';
default = true;
};
};
###### implementation
config = mkIf cfg.enable {
systemd.services.elasticsearch = {
description = "Elasticsearch Daemon";
wantedBy = [ "multi-user.target" ];
after = [ "network.target" ];
path = [ pkgs.inetutils ];
inherit (cfg) restartIfChanged;
environment = {
ES_HOME = cfg.dataDir;
ES_JAVA_OPTS = toString cfg.extraJavaOptions;
ES_PATH_CONF = configDir;
};
serviceConfig = {
ExecStart = "${cfg.package}/bin/elasticsearch ${toString cfg.extraCmdLineOptions}";
User = "elasticsearch";
PermissionsStartOnly = true;
LimitNOFILE = "1024000";
Restart = "always";
TimeoutStartSec = "infinity";
};
preStart = ''
${optionalString (!config.boot.isContainer) ''
# Only set vm.max_map_count if lower than ES required minimum
# This avoids conflict if configured via boot.kernel.sysctl
if [ `${pkgs.procps}/bin/sysctl -n vm.max_map_count` -lt 262144 ]; then
${pkgs.procps}/bin/sysctl -w vm.max_map_count=262144
fi
''}
mkdir -m 0700 -p ${cfg.dataDir}
# Install plugins
ln -sfT ${esPlugins}/plugins ${cfg.dataDir}/plugins
ln -sfT ${cfg.package}/lib ${cfg.dataDir}/lib
ln -sfT ${cfg.package}/modules ${cfg.dataDir}/modules
# elasticsearch needs to create the elasticsearch.keystore in the config directory
# so this directory needs to be writable.
mkdir -m 0700 -p ${configDir}
# Note that we copy config files from the nix store instead of symbolically linking them
# because otherwise X-Pack Security will raise the following exception:
# java.security.AccessControlException:
# access denied ("java.io.FilePermission" "/var/lib/elasticsearch/config/elasticsearch.yml" "read")
cp ${elasticsearchYml} ${configDir}/elasticsearch.yml
# Make sure the logging configuration for old elasticsearch versions is removed:
rm -f "${configDir}/logging.yml"
cp ${loggingConfigFile} ${configDir}/${loggingConfigFilename}
mkdir -p ${configDir}/scripts
cp ${cfg.package}/config/jvm.options ${configDir}/jvm.options
# redirect jvm logs to the data directory
mkdir -m 0700 -p ${cfg.dataDir}/logs
${pkgs.sd}/bin/sd 'logs/gc.log' '${cfg.dataDir}/logs/gc.log' ${configDir}/jvm.options \
if [ "$(id -u)" = 0 ]; then chown -R elasticsearch:elasticsearch ${cfg.dataDir}; fi
'';
postStart = ''
# Make sure elasticsearch is up and running before dependents
# are started
while ! ${pkgs.curl}/bin/curl -sS -f http://${cfg.listenAddress}:${toString cfg.port} 2>/dev/null; do
sleep 1
done
'';
};
environment.systemPackages = [ cfg.package ];
users = {
groups.elasticsearch.gid = config.ids.gids.elasticsearch;
users.elasticsearch = {
uid = config.ids.uids.elasticsearch;
description = "Elasticsearch daemon user";
home = cfg.dataDir;
group = "elasticsearch";
};
};
};
}

View file

@ -0,0 +1,127 @@
{ config, lib, pkgs, ... }:
with lib;
let
cfg = config.services.hound;
in {
options = {
services.hound = {
enable = mkOption {
type = types.bool;
default = false;
description = ''
Whether to enable the hound code search daemon.
'';
};
user = mkOption {
default = "hound";
type = types.str;
description = ''
User the hound daemon should execute under.
'';
};
group = mkOption {
default = "hound";
type = types.str;
description = ''
Group the hound daemon should execute under.
'';
};
extraGroups = mkOption {
type = types.listOf types.str;
default = [ ];
example = [ "dialout" ];
description = ''
List of extra groups that the "hound" user should be a part of.
'';
};
home = mkOption {
default = "/var/lib/hound";
type = types.path;
description = ''
The path to use as hound's $HOME. If the default user
"hound" is configured then this is the home of the "hound"
user.
'';
};
package = mkOption {
default = pkgs.hound;
defaultText = literalExpression "pkgs.hound";
type = types.package;
description = ''
Package for running hound.
'';
};
config = mkOption {
type = types.str;
description = ''
The full configuration of the Hound daemon. Note the dbpath
should be an absolute path to a writable location on disk.
'';
example = literalExpression ''
'''
{
"max-concurrent-indexers" : 2,
"dbpath" : "''${services.hound.home}/data",
"repos" : {
"nixpkgs": {
"url" : "https://www.github.com/NixOS/nixpkgs.git"
}
}
}
'''
'';
};
listen = mkOption {
type = types.str;
default = "0.0.0.0:6080";
example = "127.0.0.1:6080 or just :6080";
description = ''
Listen on this IP:port / :port
'';
};
};
};
config = mkIf cfg.enable {
users.groups = optionalAttrs (cfg.group == "hound") {
hound.gid = config.ids.gids.hound;
};
users.users = optionalAttrs (cfg.user == "hound") {
hound = {
description = "hound code search";
createHome = true;
home = cfg.home;
group = cfg.group;
extraGroups = cfg.extraGroups;
uid = config.ids.uids.hound;
};
};
systemd.services.hound = {
description = "Hound Code Search";
wantedBy = [ "multi-user.target" ];
after = [ "network.target" ];
serviceConfig = {
User = cfg.user;
Group = cfg.group;
WorkingDirectory = cfg.home;
ExecStartPre = "${pkgs.git}/bin/git config --global --replace-all http.sslCAinfo /etc/ssl/certs/ca-certificates.crt";
ExecStart = "${cfg.package}/bin/houndd" +
" -addr ${cfg.listen}" +
" -conf ${pkgs.writeText "hound.json" cfg.config}";
};
path = [ pkgs.git pkgs.mercurial pkgs.openssh ];
};
};
}

View file

@ -0,0 +1,213 @@
{ config, lib, options, pkgs, ... }:
with lib;
let
cfg = config.services.kibana;
opt = options.services.kibana;
ge7 = builtins.compareVersions cfg.package.version "7" >= 0;
lt6_6 = builtins.compareVersions cfg.package.version "6.6" < 0;
cfgFile = pkgs.writeText "kibana.json" (builtins.toJSON (
(filterAttrsRecursive (n: v: v != null && v != []) ({
server.host = cfg.listenAddress;
server.port = cfg.port;
server.ssl.certificate = cfg.cert;
server.ssl.key = cfg.key;
kibana.index = cfg.index;
kibana.defaultAppId = cfg.defaultAppId;
elasticsearch.url = cfg.elasticsearch.url;
elasticsearch.hosts = cfg.elasticsearch.hosts;
elasticsearch.username = cfg.elasticsearch.username;
elasticsearch.password = cfg.elasticsearch.password;
elasticsearch.ssl.certificate = cfg.elasticsearch.cert;
elasticsearch.ssl.key = cfg.elasticsearch.key;
elasticsearch.ssl.certificateAuthorities = cfg.elasticsearch.certificateAuthorities;
} // cfg.extraConf)
)));
in {
options.services.kibana = {
enable = mkEnableOption "kibana service";
listenAddress = mkOption {
description = "Kibana listening host";
default = "127.0.0.1";
type = types.str;
};
port = mkOption {
description = "Kibana listening port";
default = 5601;
type = types.int;
};
cert = mkOption {
description = "Kibana ssl certificate.";
default = null;
type = types.nullOr types.path;
};
key = mkOption {
description = "Kibana ssl key.";
default = null;
type = types.nullOr types.path;
};
index = mkOption {
description = "Elasticsearch index to use for saving kibana config.";
default = ".kibana";
type = types.str;
};
defaultAppId = mkOption {
description = "Elasticsearch default application id.";
default = "discover";
type = types.str;
};
elasticsearch = {
url = mkOption {
description = ''
Elasticsearch url.
Defaults to <literal>"http://localhost:9200"</literal>.
Don't set this when using Kibana >= 7.0.0 because it will result in a
configuration error. Use <option>services.kibana.elasticsearch.hosts</option>
instead.
'';
default = null;
type = types.nullOr types.str;
};
hosts = mkOption {
description = ''
The URLs of the Elasticsearch instances to use for all your queries.
All nodes listed here must be on the same cluster.
Defaults to <literal>[ "http://localhost:9200" ]</literal>.
This option is only valid when using kibana >= 6.6.
'';
default = null;
type = types.nullOr (types.listOf types.str);
};
username = mkOption {
description = "Username for elasticsearch basic auth.";
default = null;
type = types.nullOr types.str;
};
password = mkOption {
description = "Password for elasticsearch basic auth.";
default = null;
type = types.nullOr types.str;
};
ca = mkOption {
description = ''
CA file to auth against elasticsearch.
It's recommended to use the <option>certificateAuthorities</option> option
when using kibana-5.4 or newer.
'';
default = null;
type = types.nullOr types.path;
};
certificateAuthorities = mkOption {
description = ''
CA files to auth against elasticsearch.
Please use the <option>ca</option> option when using kibana &lt; 5.4
because those old versions don't support setting multiple CA's.
This defaults to the singleton list [ca] when the <option>ca</option> option is defined.
'';
default = if cfg.elasticsearch.ca == null then [] else [ca];
defaultText = literalExpression ''
if config.${opt.elasticsearch.ca} == null then [ ] else [ ca ]
'';
type = types.listOf types.path;
};
cert = mkOption {
description = "Certificate file to auth against elasticsearch.";
default = null;
type = types.nullOr types.path;
};
key = mkOption {
description = "Key file to auth against elasticsearch.";
default = null;
type = types.nullOr types.path;
};
};
package = mkOption {
description = "Kibana package to use";
default = pkgs.kibana;
defaultText = literalExpression "pkgs.kibana";
type = types.package;
};
dataDir = mkOption {
description = "Kibana data directory";
default = "/var/lib/kibana";
type = types.path;
};
extraConf = mkOption {
description = "Kibana extra configuration";
default = {};
type = types.attrs;
};
};
config = mkIf (cfg.enable) {
assertions = [
{
assertion = ge7 -> cfg.elasticsearch.url == null;
message =
"The option services.kibana.elasticsearch.url has been removed when using kibana >= 7.0.0. " +
"Please use option services.kibana.elasticsearch.hosts instead.";
}
{
assertion = lt6_6 -> cfg.elasticsearch.hosts == null;
message =
"The option services.kibana.elasticsearch.hosts is only valid for kibana >= 6.6.";
}
];
systemd.services.kibana = {
description = "Kibana Service";
wantedBy = [ "multi-user.target" ];
after = [ "network.target" "elasticsearch.service" ];
environment = { BABEL_CACHE_PATH = "${cfg.dataDir}/.babelcache.json"; };
serviceConfig = {
ExecStart =
"${cfg.package}/bin/kibana" +
" --config ${cfgFile}" +
" --path.data ${cfg.dataDir}";
User = "kibana";
WorkingDirectory = cfg.dataDir;
};
};
environment.systemPackages = [ cfg.package ];
users.users.kibana = {
isSystemUser = true;
description = "Kibana service user";
home = cfg.dataDir;
createHome = true;
group = "kibana";
};
users.groups.kibana = {};
};
}

View file

@ -0,0 +1,39 @@
# Meilisearch {#module-services-meilisearch}
Meilisearch is a lightweight, fast and powerful search engine. Think elastic search with a much smaller footprint.
## Quickstart
the minimum to start meilisearch is
```nix
services.meilisearch.enable = true;
```
this will start the http server included with meilisearch on port 7700.
test with `curl -X GET 'http://localhost:7700/health'`
## Usage
you first need to add documents to an index before you can search for documents.
### Add a documents to the `movies` index
`curl -X POST 'http://127.0.0.1:7700/indexes/movies/documents' --data '[{"id": "123", "title": "Superman"}, {"id": 234, "title": "Batman"}]'`
### Search documents in the `movies` index
`curl 'http://127.0.0.1:7700/indexes/movies/search' --data '{ "q": "botman" }'` (note the typo is intentional and there to demonstrate the typo tolerant capabilities)
## Defaults
- The default nixos package doesn't come with the [dashboard](https://docs.meilisearch.com/learn/getting_started/quick_start.html#search), since the dashboard features makes some assets downloads at compile time.
- Anonimized Analytics sent to meilisearch are disabled by default.
- Default deployment is development mode. It doesn't require a secret master key. All routes are not protected and accessible.
## Missing
- the snapshot feature is not yet configurable from the module, it's just a matter of adding the relevant environment variables.

View file

@ -0,0 +1,132 @@
{ config, lib, pkgs, ... }:
with lib;
let
cfg = config.services.meilisearch;
in
{
meta.maintainers = with maintainers; [ Br1ght0ne happysalada ];
# Don't edit the docbook xml directly, edit the md and generate it:
# `pandoc meilisearch.md -t docbook --top-level-division=chapter --extract-media=media -f markdown+smart > meilisearch.xml`
meta.doc = ./meilisearch.xml;
###### interface
options.services.meilisearch = {
enable = mkEnableOption "MeiliSearch - a RESTful search API";
package = mkOption {
description = "The package to use for meilisearch. Use this if you require specific features to be enabled. The default package has no features.";
default = pkgs.meilisearch;
defaultText = "pkgs.meilisearch";
type = types.package;
};
listenAddress = mkOption {
description = "MeiliSearch listen address.";
default = "127.0.0.1";
type = types.str;
};
listenPort = mkOption {
description = "MeiliSearch port to listen on.";
default = 7700;
type = types.port;
};
environment = mkOption {
description = "Defines the running environment of MeiliSearch.";
default = "development";
type = types.enum [ "development" "production" ];
};
# TODO change this to LoadCredentials once possible
masterKeyEnvironmentFile = mkOption {
description = ''
Path to file which contains the master key.
By doing so, all routes will be protected and will require a key to be accessed.
If no master key is provided, all routes can be accessed without requiring any key.
The format is the following:
MEILI_MASTER_KEY=my_secret_key
'';
default = null;
type = with types; nullOr path;
};
noAnalytics = mkOption {
description = ''
Deactivates analytics.
Analytics allow MeiliSearch to know how many users are using MeiliSearch,
which versions and which platforms are used.
This process is entirely anonymous.
'';
default = true;
type = types.bool;
};
logLevel = mkOption {
description = ''
Defines how much detail should be present in MeiliSearch's logs.
MeiliSearch currently supports four log levels, listed in order of increasing verbosity:
- 'ERROR': only log unexpected events indicating MeiliSearch is not functioning as expected
- 'WARN:' log all unexpected events, regardless of their severity
- 'INFO:' log all events. This is the default value
- 'DEBUG': log all events and including detailed information on MeiliSearch's internal processes.
Useful when diagnosing issues and debugging
'';
default = "INFO";
type = types.str;
};
maxIndexSize = mkOption {
description = ''
Sets the maximum size of the index.
Value must be given in bytes or explicitly stating a base unit.
For example, the default value can be written as 107374182400, '107.7Gb', or '107374 Mb'.
Default is 100 GiB
'';
default = "107374182400";
type = types.str;
};
payloadSizeLimit = mkOption {
description = ''
Sets the maximum size of accepted JSON payloads.
Value must be given in bytes or explicitly stating a base unit.
For example, the default value can be written as 107374182400, '107.7Gb', or '107374 Mb'.
Default is ~ 100 MB
'';
default = "104857600";
type = types.str;
};
};
###### implementation
config = mkIf cfg.enable {
systemd.services.meilisearch = {
description = "MeiliSearch daemon";
wantedBy = [ "multi-user.target" ];
after = [ "network.target" ];
environment = {
MEILI_DB_PATH = "/var/lib/meilisearch";
MEILI_HTTP_ADDR = "${cfg.listenAddress}:${toString cfg.listenPort}";
MEILI_NO_ANALYTICS = toString cfg.noAnalytics;
MEILI_ENV = cfg.environment;
MEILI_DUMPS_DIR = "/var/lib/meilisearch/dumps";
MEILI_LOG_LEVEL = cfg.logLevel;
MEILI_MAX_INDEX_SIZE = cfg.maxIndexSize;
};
serviceConfig = {
ExecStart = "${cfg.package}/bin/meilisearch";
DynamicUser = true;
StateDirectory = "meilisearch";
EnvironmentFile = mkIf (cfg.masterKeyEnvironmentFile != null) cfg.masterKeyEnvironmentFile;
};
};
};
}

View file

@ -0,0 +1,85 @@
<chapter xmlns="http://docbook.org/ns/docbook" xmlns:xlink="http://www.w3.org/1999/xlink" xml:id="module-services-meilisearch">
<title>Meilisearch</title>
<para>
Meilisearch is a lightweight, fast and powerful search engine. Think
elastic search with a much smaller footprint.
</para>
<section xml:id="quickstart">
<title>Quickstart</title>
<para>
the minimum to start meilisearch is
</para>
<programlisting language="bash">
services.meilisearch.enable = true;
</programlisting>
<para>
this will start the http server included with meilisearch on port
7700.
</para>
<para>
test with
<literal>curl -X GET 'http://localhost:7700/health'</literal>
</para>
</section>
<section xml:id="usage">
<title>Usage</title>
<para>
you first need to add documents to an index before you can search
for documents.
</para>
<section xml:id="add-a-documents-to-the-movies-index">
<title>Add a documents to the <literal>movies</literal>
index</title>
<para>
<literal>curl -X POST 'http://127.0.0.1:7700/indexes/movies/documents' --data '[{&quot;id&quot;: &quot;123&quot;, &quot;title&quot;: &quot;Superman&quot;}, {&quot;id&quot;: 234, &quot;title&quot;: &quot;Batman&quot;}]'</literal>
</para>
</section>
<section xml:id="search-documents-in-the-movies-index">
<title>Search documents in the <literal>movies</literal>
index</title>
<para>
<literal>curl 'http://127.0.0.1:7700/indexes/movies/search' --data '{ &quot;q&quot;: &quot;botman&quot; }'</literal>
(note the typo is intentional and there to demonstrate the typo
tolerant capabilities)
</para>
</section>
</section>
<section xml:id="defaults">
<title>Defaults</title>
<itemizedlist>
<listitem>
<para>
The default nixos package doesnt come with the
<link xlink:href="https://docs.meilisearch.com/learn/getting_started/quick_start.html#search">dashboard</link>,
since the dashboard features makes some assets downloads at
compile time.
</para>
</listitem>
<listitem>
<para>
Anonimized Analytics sent to meilisearch are disabled by
default.
</para>
</listitem>
<listitem>
<para>
Default deployment is development mode. It doesnt require a
secret master key. All routes are not protected and
accessible.
</para>
</listitem>
</itemizedlist>
</section>
<section xml:id="missing">
<title>Missing</title>
<itemizedlist spacing="compact">
<listitem>
<para>
the snapshot feature is not yet configurable from the module,
its just a matter of adding the relevant environment
variables.
</para>
</listitem>
</itemizedlist>
</section>
</chapter>

View file

@ -0,0 +1,110 @@
{ config, lib, pkgs, ... }:
with lib;
let
cfg = config.services.solr;
in
{
options = {
services.solr = {
enable = mkEnableOption "Solr";
package = mkOption {
type = types.package;
default = pkgs.solr;
defaultText = literalExpression "pkgs.solr";
description = "Which Solr package to use.";
};
port = mkOption {
type = types.int;
default = 8983;
description = "Port on which Solr is ran.";
};
stateDir = mkOption {
type = types.path;
default = "/var/lib/solr";
description = "The solr home directory containing config, data, and logging files.";
};
extraJavaOptions = mkOption {
type = types.listOf types.str;
default = [];
description = "Extra command line options given to the java process running Solr.";
};
user = mkOption {
type = types.str;
default = "solr";
description = "User under which Solr is ran.";
};
group = mkOption {
type = types.str;
default = "solr";
description = "Group under which Solr is ran.";
};
};
};
config = mkIf cfg.enable {
environment.systemPackages = [ cfg.package ];
systemd.services.solr = {
after = [ "network.target" "remote-fs.target" "nss-lookup.target" "systemd-journald-dev-log.socket" ];
wantedBy = [ "multi-user.target" ];
environment = {
SOLR_HOME = "${cfg.stateDir}/data";
LOG4J_PROPS = "${cfg.stateDir}/log4j2.xml";
SOLR_LOGS_DIR = "${cfg.stateDir}/logs";
SOLR_PORT = "${toString cfg.port}";
};
path = with pkgs; [
gawk
procps
];
preStart = ''
mkdir -p "${cfg.stateDir}/data";
mkdir -p "${cfg.stateDir}/logs";
if ! test -e "${cfg.stateDir}/data/solr.xml"; then
install -D -m0640 ${cfg.package}/server/solr/solr.xml "${cfg.stateDir}/data/solr.xml"
install -D -m0640 ${cfg.package}/server/solr/zoo.cfg "${cfg.stateDir}/data/zoo.cfg"
fi
if ! test -e "${cfg.stateDir}/log4j2.xml"; then
install -D -m0640 ${cfg.package}/server/resources/log4j2.xml "${cfg.stateDir}/log4j2.xml"
fi
'';
serviceConfig = {
User = cfg.user;
Group = cfg.group;
ExecStart="${cfg.package}/bin/solr start -f -a \"${concatStringsSep " " cfg.extraJavaOptions}\"";
ExecStop="${cfg.package}/bin/solr stop";
};
};
users.users = optionalAttrs (cfg.user == "solr") {
solr = {
group = cfg.group;
home = cfg.stateDir;
createHome = true;
uid = config.ids.uids.solr;
};
};
users.groups = optionalAttrs (cfg.group == "solr") {
solr.gid = config.ids.gids.solr;
};
};
}