Merge staging-next into staging
This commit is contained in:
commit
06efb52369
@ -11,8 +11,7 @@
|
||||
</para>
|
||||
|
||||
<para>
|
||||
It makes virtio modules available on the initrd, sets the system time from
|
||||
the hardware clock to work around a bug in qemu-kvm, and
|
||||
<link linkend="opt-security.rngd.enable">enables rngd</link>.
|
||||
It makes virtio modules available on the initrd and sets the system time from
|
||||
the hardware clock to work around a bug in qemu-kvm.
|
||||
</para>
|
||||
</section>
|
||||
|
@ -610,6 +610,15 @@ self: super:
|
||||
been dropped from upstream releases.
|
||||
</para>
|
||||
</listitem>
|
||||
<listitem>
|
||||
<para>
|
||||
In the ACME module, the data used to build the hash for the account
|
||||
directory has changed to accomodate new features to reduce account
|
||||
rate limit issues. This will trigger new account creation on the first
|
||||
rebuild following this update. No issues are expected to arise from this,
|
||||
thanks to the new account creation handling.
|
||||
</para>
|
||||
</listitem>
|
||||
<listitem>
|
||||
<para>
|
||||
<xref linkend="opt-users.users._name_.createHome" /> now always ensures home directory permissions to be <literal>0700</literal>.
|
||||
|
@ -71,7 +71,7 @@ in
|
||||
#utmp = 29; # unused
|
||||
# ddclient = 30; # converted to DynamicUser = true
|
||||
davfs2 = 31;
|
||||
#disnix = 33; # unused
|
||||
#disnix = 33; # module removed
|
||||
osgi = 34;
|
||||
tor = 35;
|
||||
cups = 36;
|
||||
@ -387,7 +387,7 @@ in
|
||||
utmp = 29;
|
||||
# ddclient = 30; # converted to DynamicUser = true
|
||||
davfs2 = 31;
|
||||
disnix = 33;
|
||||
#disnix = 33; # module removed
|
||||
osgi = 34;
|
||||
tor = 35;
|
||||
#cups = 36; # unused
|
||||
|
@ -450,8 +450,6 @@
|
||||
./services/misc/devmon.nix
|
||||
./services/misc/dictd.nix
|
||||
./services/misc/dwm-status.nix
|
||||
./services/misc/dysnomia.nix
|
||||
./services/misc/disnix.nix
|
||||
./services/misc/docker-registry.nix
|
||||
./services/misc/domoticz.nix
|
||||
./services/misc/errbot.nix
|
||||
@ -727,6 +725,7 @@
|
||||
./services/networking/owamp.nix
|
||||
./services/networking/pdnsd.nix
|
||||
./services/networking/pixiecore.nix
|
||||
./services/networking/pleroma.nix
|
||||
./services/networking/polipo.nix
|
||||
./services/networking/powerdns.nix
|
||||
./services/networking/pdns-recursor.nix
|
||||
|
@ -1,7 +1,7 @@
|
||||
# Common configuration for virtual machines running under QEMU (using
|
||||
# virtio).
|
||||
|
||||
{ lib, ... }:
|
||||
{ ... }:
|
||||
|
||||
{
|
||||
boot.initrd.availableKernelModules = [ "virtio_net" "virtio_pci" "virtio_mmio" "virtio_blk" "virtio_scsi" "9p" "9pnet_virtio" ];
|
||||
@ -14,6 +14,4 @@
|
||||
# to the *boot time* of the host).
|
||||
hwclock -s
|
||||
'';
|
||||
|
||||
security.rngd.enable = lib.mkDefault false;
|
||||
}
|
||||
|
@ -7,6 +7,11 @@ let
|
||||
numCerts = length (builtins.attrNames cfg.certs);
|
||||
_24hSecs = 60 * 60 * 24;
|
||||
|
||||
# Used to make unique paths for each cert/account config set
|
||||
mkHash = with builtins; val: substring 0 20 (hashString "sha256" val);
|
||||
mkAccountHash = acmeServer: data: mkHash "${toString acmeServer} ${data.keyType} ${data.email}";
|
||||
accountDirRoot = "/var/lib/acme/.lego/accounts/";
|
||||
|
||||
# There are many services required to make cert renewals work.
|
||||
# They all follow a common structure:
|
||||
# - They inherit this commonServiceConfig
|
||||
@ -19,7 +24,7 @@ let
|
||||
Type = "oneshot";
|
||||
User = "acme";
|
||||
Group = mkDefault "acme";
|
||||
UMask = 0027;
|
||||
UMask = 0023;
|
||||
StateDirectoryMode = 750;
|
||||
ProtectSystem = "full";
|
||||
PrivateTmp = true;
|
||||
@ -54,23 +59,35 @@ let
|
||||
'';
|
||||
};
|
||||
|
||||
# Previously, all certs were owned by whatever user was configured in
|
||||
# config.security.acme.certs.<cert>.user. Now everything is owned by and
|
||||
# run by the acme user.
|
||||
userMigrationService = {
|
||||
description = "Fix owner and group of all ACME certificates";
|
||||
|
||||
script = with builtins; concatStringsSep "\n" (mapAttrsToList (cert: data: ''
|
||||
for fixpath in /var/lib/acme/${escapeShellArg cert} /var/lib/acme/.lego/${escapeShellArg cert}; do
|
||||
# Ensures that directories which are shared across all certs
|
||||
# exist and have the correct user and group, since group
|
||||
# is configurable on a per-cert basis.
|
||||
userMigrationService = let
|
||||
script = with builtins; ''
|
||||
chown -R acme .lego/accounts
|
||||
'' + (concatStringsSep "\n" (mapAttrsToList (cert: data: ''
|
||||
for fixpath in ${escapeShellArg cert} .lego/${escapeShellArg cert}; do
|
||||
if [ -d "$fixpath" ]; then
|
||||
chmod -R u=rwX,g=rX,o= "$fixpath"
|
||||
chown -R acme:${data.group} "$fixpath"
|
||||
fi
|
||||
done
|
||||
'') certConfigs);
|
||||
'') certConfigs));
|
||||
in {
|
||||
description = "Fix owner and group of all ACME certificates";
|
||||
|
||||
# We don't want this to run every time a renewal happens
|
||||
serviceConfig.RemainAfterExit = true;
|
||||
serviceConfig = commonServiceConfig // {
|
||||
# We don't want this to run every time a renewal happens
|
||||
RemainAfterExit = true;
|
||||
|
||||
# These StateDirectory entries negate the need for tmpfiles
|
||||
StateDirectory = [ "acme" "acme/.lego" "acme/.lego/accounts" ];
|
||||
StateDirectoryMode = 755;
|
||||
WorkingDirectory = "/var/lib/acme";
|
||||
|
||||
# Run the start script as root
|
||||
ExecStart = "+" + (pkgs.writeShellScript "acme-fixperms" script);
|
||||
};
|
||||
};
|
||||
|
||||
certToConfig = cert: data: let
|
||||
@ -101,11 +118,10 @@ let
|
||||
${toString acmeServer} ${toString data.dnsProvider}
|
||||
${toString data.ocspMustStaple} ${data.keyType}
|
||||
'';
|
||||
mkHash = with builtins; val: substring 0 20 (hashString "sha256" val);
|
||||
certDir = mkHash hashData;
|
||||
domainHash = mkHash "${concatStringsSep " " extraDomains} ${data.domain}";
|
||||
othersHash = mkHash "${toString acmeServer} ${data.keyType} ${data.email}";
|
||||
accountDir = "/var/lib/acme/.lego/accounts/" + othersHash;
|
||||
accountHash = (mkAccountHash acmeServer data);
|
||||
accountDir = accountDirRoot + accountHash;
|
||||
|
||||
protocolOpts = if useDns then (
|
||||
[ "--dns" data.dnsProvider ]
|
||||
@ -142,9 +158,8 @@ let
|
||||
);
|
||||
|
||||
in {
|
||||
inherit accountDir selfsignedDeps;
|
||||
inherit accountHash cert selfsignedDeps;
|
||||
|
||||
webroot = data.webroot;
|
||||
group = data.group;
|
||||
|
||||
renewTimer = {
|
||||
@ -184,7 +199,10 @@ let
|
||||
|
||||
StateDirectory = "acme/${cert}";
|
||||
|
||||
BindPaths = "/var/lib/acme/.minica:/tmp/ca /var/lib/acme/${cert}:/tmp/${keyName}";
|
||||
BindPaths = [
|
||||
"/var/lib/acme/.minica:/tmp/ca"
|
||||
"/var/lib/acme/${cert}:/tmp/${keyName}"
|
||||
];
|
||||
};
|
||||
|
||||
# Working directory will be /tmp
|
||||
@ -222,16 +240,22 @@ let
|
||||
serviceConfig = commonServiceConfig // {
|
||||
Group = data.group;
|
||||
|
||||
# AccountDir dir will be created by tmpfiles to ensure correct permissions
|
||||
# And to avoid deletion during systemctl clean
|
||||
# acme/.lego/${cert} is listed so that it is deleted during systemctl clean
|
||||
StateDirectory = "acme/${cert} acme/.lego/${cert} acme/.lego/${cert}/${certDir}";
|
||||
# Keep in mind that these directories will be deleted if the user runs
|
||||
# systemctl clean --what=state
|
||||
# acme/.lego/${cert} is listed for this reason.
|
||||
StateDirectory = [
|
||||
"acme/${cert}"
|
||||
"acme/.lego/${cert}"
|
||||
"acme/.lego/${cert}/${certDir}"
|
||||
"acme/.lego/accounts/${accountHash}"
|
||||
];
|
||||
|
||||
# Needs to be space separated, but can't use a multiline string because that'll include newlines
|
||||
BindPaths =
|
||||
"${accountDir}:/tmp/accounts " +
|
||||
"/var/lib/acme/${cert}:/tmp/out " +
|
||||
"/var/lib/acme/.lego/${cert}/${certDir}:/tmp/certificates ";
|
||||
BindPaths = [
|
||||
"${accountDir}:/tmp/accounts"
|
||||
"/var/lib/acme/${cert}:/tmp/out"
|
||||
"/var/lib/acme/.lego/${cert}/${certDir}:/tmp/certificates"
|
||||
];
|
||||
|
||||
# Only try loading the credentialsFile if the dns challenge is enabled
|
||||
EnvironmentFile = mkIf useDns data.credentialsFile;
|
||||
@ -248,13 +272,18 @@ let
|
||||
|
||||
# Working directory will be /tmp
|
||||
script = ''
|
||||
set -euo pipefail
|
||||
set -euxo pipefail
|
||||
|
||||
${optionalString (data.webroot != null) ''
|
||||
# Ensure the webroot exists
|
||||
mkdir -p '${data.webroot}/.well-known/acme-challenge'
|
||||
chown 'acme:${data.group}' ${data.webroot}/{.well-known,.well-known/acme-challenge}
|
||||
''}
|
||||
|
||||
echo '${domainHash}' > domainhash.txt
|
||||
|
||||
# Check if we can renew
|
||||
# Certificates and account credentials must exist
|
||||
if [ -e 'certificates/${keyName}.key' -a -e 'certificates/${keyName}.crt' -a "$(ls -1 accounts)" ]; then
|
||||
if [ -e 'certificates/${keyName}.key' -a -e 'certificates/${keyName}.crt' -a -n "$(ls -1 accounts)" ]; then
|
||||
|
||||
# When domains are updated, there's no need to do a full
|
||||
# Lego run, but it's likely renew won't work if days is too low.
|
||||
@ -664,21 +693,33 @@ in {
|
||||
|
||||
systemd.timers = mapAttrs' (cert: conf: nameValuePair "acme-${cert}" conf.renewTimer) certConfigs;
|
||||
|
||||
# .lego and .lego/accounts specified to fix any incorrect permissions
|
||||
systemd.tmpfiles.rules = [
|
||||
"d /var/lib/acme/.lego - acme acme"
|
||||
"d /var/lib/acme/.lego/accounts - acme acme"
|
||||
] ++ (unique (concatMap (conf: [
|
||||
"d ${conf.accountDir} - acme acme"
|
||||
] ++ (optional (conf.webroot != null) "d ${conf.webroot}/.well-known/acme-challenge - acme ${conf.group}")
|
||||
) (attrValues certConfigs)));
|
||||
systemd.targets = let
|
||||
# Create some targets which can be depended on to be "active" after cert renewals
|
||||
finishedTargets = mapAttrs' (cert: conf: nameValuePair "acme-finished-${cert}" {
|
||||
wantedBy = [ "default.target" ];
|
||||
requires = [ "acme-${cert}.service" ] ++ conf.selfsignedDeps;
|
||||
after = [ "acme-${cert}.service" ] ++ conf.selfsignedDeps;
|
||||
}) certConfigs;
|
||||
|
||||
# Create some targets which can be depended on to be "active" after cert renewals
|
||||
systemd.targets = mapAttrs' (cert: conf: nameValuePair "acme-finished-${cert}" {
|
||||
wantedBy = [ "default.target" ];
|
||||
requires = [ "acme-${cert}.service" ] ++ conf.selfsignedDeps;
|
||||
after = [ "acme-${cert}.service" ] ++ conf.selfsignedDeps;
|
||||
}) certConfigs;
|
||||
# Create targets to limit the number of simultaneous account creations
|
||||
# How it works:
|
||||
# - Pick a "leader" cert service, which will be in charge of creating the account,
|
||||
# and run first (requires + after)
|
||||
# - Make all other cert services sharing the same account wait for the leader to
|
||||
# finish before starting (requiredBy + before).
|
||||
# Using a target here is fine - account creation is a one time event. Even if
|
||||
# systemd clean --what=state is used to delete the account, so long as the user
|
||||
# then runs one of the cert services, there won't be any issues.
|
||||
accountTargets = mapAttrs' (hash: confs: let
|
||||
leader = "acme-${(builtins.head confs).cert}.service";
|
||||
dependantServices = map (conf: "acme-${conf.cert}.service") (builtins.tail confs);
|
||||
in nameValuePair "acme-account-${hash}" {
|
||||
requiredBy = dependantServices;
|
||||
before = dependantServices;
|
||||
requires = [ leader ];
|
||||
after = [ leader ];
|
||||
}) (groupBy (conf: conf.accountHash) (attrValues certConfigs));
|
||||
in finishedTargets // accountTargets;
|
||||
})
|
||||
];
|
||||
|
||||
|
@ -162,6 +162,9 @@ services.httpd = {
|
||||
<xref linkend="opt-security.acme.certs"/>."foo.example.com" = {
|
||||
<link linkend="opt-security.acme.certs._name_.webroot">webroot</link> = "/var/lib/acme/.challenges";
|
||||
<link linkend="opt-security.acme.certs._name_.email">email</link> = "foo@example.com";
|
||||
# Ensure that the web server you use can read the generated certs
|
||||
# Take a look at the <link linkend="opt-services.nginx.group">group</link> option for the web server you choose.
|
||||
<link linkend="opt-security.acme.certs._name_.group">group</link> = "nginx";
|
||||
# Since we have a wildcard vhost to handle port 80,
|
||||
# we can generate certs for anything!
|
||||
# Just make sure your DNS resolves them.
|
||||
@ -257,10 +260,11 @@ chmod 400 /var/lib/secrets/certs.secret
|
||||
<para>
|
||||
Should you need to regenerate a particular certificate in a hurry, such
|
||||
as when a vulnerability is found in Let's Encrypt, there is now a convenient
|
||||
mechanism for doing so. Running <literal>systemctl clean acme-example.com.service</literal>
|
||||
will remove all certificate files for the given domain, allowing you to then
|
||||
<literal>systemctl start acme-example.com.service</literal> to generate fresh
|
||||
ones.
|
||||
mechanism for doing so. Running
|
||||
<literal>systemctl clean --what=state acme-example.com.service</literal>
|
||||
will remove all certificate files and the account data for the given domain,
|
||||
allowing you to then <literal>systemctl start acme-example.com.service</literal>
|
||||
to generate fresh ones.
|
||||
</para>
|
||||
</section>
|
||||
<section xml:id="module-security-acme-fix-jws">
|
||||
|
@ -10,16 +10,8 @@ let
|
||||
(n: v: (if v ? program then v else v // {program=n;}))
|
||||
wrappers);
|
||||
|
||||
securityWrapper = pkgs.stdenv.mkDerivation {
|
||||
name = "security-wrapper";
|
||||
phases = [ "installPhase" "fixupPhase" ];
|
||||
buildInputs = [ pkgs.libcap pkgs.libcap_ng pkgs.linuxHeaders ];
|
||||
hardeningEnable = [ "pie" ];
|
||||
installPhase = ''
|
||||
mkdir -p $out/bin
|
||||
$CC -Wall -O2 -DWRAPPER_DIR=\"${parentWrapperDir}\" \
|
||||
-lcap-ng -lcap ${./wrapper.c} -o $out/bin/security-wrapper
|
||||
'';
|
||||
securityWrapper = pkgs.callPackage ./wrapper.nix {
|
||||
inherit parentWrapperDir;
|
||||
};
|
||||
|
||||
###### Activation script for the setcap wrappers
|
||||
|
@ -4,15 +4,17 @@
|
||||
#include <unistd.h>
|
||||
#include <sys/types.h>
|
||||
#include <sys/stat.h>
|
||||
#include <sys/xattr.h>
|
||||
#include <fcntl.h>
|
||||
#include <dirent.h>
|
||||
#include <assert.h>
|
||||
#include <errno.h>
|
||||
#include <linux/capability.h>
|
||||
#include <sys/capability.h>
|
||||
#include <sys/prctl.h>
|
||||
#include <limits.h>
|
||||
#include <cap-ng.h>
|
||||
#include <stdint.h>
|
||||
#include <syscall.h>
|
||||
#include <byteswap.h>
|
||||
|
||||
// Make sure assertions are not compiled out, we use them to codify
|
||||
// invariants about this program and we want it to fail fast and
|
||||
@ -23,182 +25,172 @@ extern char **environ;
|
||||
|
||||
// The WRAPPER_DIR macro is supplied at compile time so that it cannot
|
||||
// be changed at runtime
|
||||
static char * wrapperDir = WRAPPER_DIR;
|
||||
static char *wrapper_dir = WRAPPER_DIR;
|
||||
|
||||
// Wrapper debug variable name
|
||||
static char * wrapperDebug = "WRAPPER_DEBUG";
|
||||
static char *wrapper_debug = "WRAPPER_DEBUG";
|
||||
|
||||
// Update the capabilities of the running process to include the given
|
||||
// capability in the Ambient set.
|
||||
static void set_ambient_cap(cap_value_t cap)
|
||||
{
|
||||
capng_get_caps_process();
|
||||
#define CAP_SETPCAP 8
|
||||
|
||||
if (capng_update(CAPNG_ADD, CAPNG_INHERITABLE, (unsigned long) cap))
|
||||
{
|
||||
perror("cannot raise the capability into the Inheritable set\n");
|
||||
exit(1);
|
||||
#if __BYTE_ORDER == __BIG_ENDIAN
|
||||
#define LE32_TO_H(x) bswap_32(x)
|
||||
#else
|
||||
#define LE32_TO_H(x) (x)
|
||||
#endif
|
||||
|
||||
int get_last_cap(unsigned *last_cap) {
|
||||
FILE* file = fopen("/proc/sys/kernel/cap_last_cap", "r");
|
||||
if (file == NULL) {
|
||||
int saved_errno = errno;
|
||||
fprintf(stderr, "failed to open /proc/sys/kernel/cap_last_cap: %s\n", strerror(errno));
|
||||
return -saved_errno;
|
||||
}
|
||||
|
||||
capng_apply(CAPNG_SELECT_CAPS);
|
||||
|
||||
if (prctl(PR_CAP_AMBIENT, PR_CAP_AMBIENT_RAISE, (unsigned long) cap, 0, 0))
|
||||
{
|
||||
perror("cannot raise the capability into the Ambient set\n");
|
||||
exit(1);
|
||||
int res = fscanf(file, "%u", last_cap);
|
||||
if (res == EOF) {
|
||||
int saved_errno = errno;
|
||||
fprintf(stderr, "could not read number from /proc/sys/kernel/cap_last_cap: %s\n", strerror(errno));
|
||||
return -saved_errno;
|
||||
}
|
||||
fclose(file);
|
||||
return 0;
|
||||
}
|
||||
|
||||
// Given the path to this program, fetch its configured capability set
|
||||
// (as set by `setcap ... /path/to/file`) and raise those capabilities
|
||||
// into the Ambient set.
|
||||
static int make_caps_ambient(const char *selfPath)
|
||||
{
|
||||
cap_t caps = cap_get_file(selfPath);
|
||||
|
||||
if(!caps)
|
||||
{
|
||||
if(getenv(wrapperDebug))
|
||||
fprintf(stderr, "no caps set or could not retrieve the caps for this file, not doing anything...");
|
||||
static int make_caps_ambient(const char *self_path) {
|
||||
struct vfs_ns_cap_data data = {};
|
||||
int r = getxattr(self_path, "security.capability", &data, sizeof(data));
|
||||
|
||||
if (r < 0) {
|
||||
if (errno == ENODATA) {
|
||||
// no capabilities set
|
||||
return 0;
|
||||
}
|
||||
fprintf(stderr, "cannot get capabilities for %s: %s", self_path, strerror(errno));
|
||||
return 1;
|
||||
}
|
||||
|
||||
// We use `cap_to_text` and iteration over the tokenized result
|
||||
// string because, as of libcap's current release, there is no
|
||||
// facility for retrieving an array of `cap_value_t`'s that can be
|
||||
// given to `prctl` in order to lift that capability into the
|
||||
// Ambient set.
|
||||
//
|
||||
// Some discussion was had around shot-gunning all of the
|
||||
// capabilities we know about into the Ambient set but that has a
|
||||
// security smell and I deemed the risk of the current
|
||||
// implementation crashing the program to be lower than the risk
|
||||
// of a privilege escalation security hole being introduced by
|
||||
// raising all capabilities, even ones we didn't intend for the
|
||||
// program, into the Ambient set.
|
||||
//
|
||||
// `cap_t` which is returned by `cap_get_*` is an opaque type and
|
||||
// even if we could retrieve the bitmasks (which, as far as I can
|
||||
// tell we cannot) in order to get the `cap_value_t`
|
||||
// representation for each capability we would have to take the
|
||||
// total number of capabilities supported and iterate over the
|
||||
// sequence of integers up-to that maximum total, testing each one
|
||||
// against the bitmask ((bitmask >> n) & 1) to see if it's set and
|
||||
// aggregating each "capability integer n" that is set in the
|
||||
// bitmask.
|
||||
//
|
||||
// That, combined with the fact that we can't easily get the
|
||||
// bitmask anyway seemed much more brittle than fetching the
|
||||
// `cap_t`, transforming it into a textual representation,
|
||||
// tokenizing the string, and using `cap_from_name` on the token
|
||||
// to get the `cap_value_t` that we need for `prctl`. There is
|
||||
// indeed risk involved if the output string format of
|
||||
// `cap_to_text` ever changes but at this time the combination of
|
||||
// factors involving the below list have led me to the conclusion
|
||||
// that the best implementation at this time is reading then
|
||||
// parsing with *lots of documentation* about why we're doing it
|
||||
// this way.
|
||||
//
|
||||
// 1. No explicit API for fetching an array of `cap_value_t`'s or
|
||||
// for transforming a `cap_t` into such a representation
|
||||
// 2. The risk of a crash is lower than lifting all capabilities
|
||||
// into the Ambient set
|
||||
// 3. libcap is depended on heavily in the Linux ecosystem so
|
||||
// there is a high chance that the output representation of
|
||||
// `cap_to_text` will not change which reduces our risk that
|
||||
// this parsing step will cause a crash
|
||||
//
|
||||
// The preferred method, should it ever be available in the
|
||||
// future, would be to use libcap API's to transform the result
|
||||
// from a `cap_get_*` into an array of `cap_value_t`'s that can
|
||||
// then be given to prctl.
|
||||
//
|
||||
// - Parnell
|
||||
ssize_t capLen;
|
||||
char* capstr = cap_to_text(caps, &capLen);
|
||||
cap_free(caps);
|
||||
|
||||
// TODO: For now, we assume that cap_to_text always starts its
|
||||
// result string with " =" and that the first capability is listed
|
||||
// immediately after that. We should verify this.
|
||||
assert(capLen >= 2);
|
||||
capstr += 2;
|
||||
|
||||
char* saveptr = NULL;
|
||||
for(char* tok = strtok_r(capstr, ",", &saveptr); tok; tok = strtok_r(NULL, ",", &saveptr))
|
||||
{
|
||||
cap_value_t capnum;
|
||||
if (cap_from_name(tok, &capnum))
|
||||
{
|
||||
if(getenv(wrapperDebug))
|
||||
fprintf(stderr, "cap_from_name failed, skipping: %s", tok);
|
||||
}
|
||||
else if (capnum == CAP_SETPCAP)
|
||||
{
|
||||
// Check for the cap_setpcap capability, we set this on the
|
||||
// wrapper so it can elevate the capabilities to the Ambient
|
||||
// set but we do not want to propagate it down into the
|
||||
// wrapped program.
|
||||
//
|
||||
// TODO: what happens if that's the behavior you want
|
||||
// though???? I'm preferring a strict vs. loose policy here.
|
||||
if(getenv(wrapperDebug))
|
||||
fprintf(stderr, "cap_setpcap in set, skipping it\n");
|
||||
}
|
||||
else
|
||||
{
|
||||
set_ambient_cap(capnum);
|
||||
|
||||
if(getenv(wrapperDebug))
|
||||
fprintf(stderr, "raised %s into the Ambient capability set\n", tok);
|
||||
}
|
||||
size_t size;
|
||||
uint32_t version = LE32_TO_H(data.magic_etc) & VFS_CAP_REVISION_MASK;
|
||||
switch (version) {
|
||||
case VFS_CAP_REVISION_1:
|
||||
size = VFS_CAP_U32_1;
|
||||
break;
|
||||
case VFS_CAP_REVISION_2:
|
||||
case VFS_CAP_REVISION_3:
|
||||
size = VFS_CAP_U32_3;
|
||||
break;
|
||||
default:
|
||||
fprintf(stderr, "BUG! Unsupported capability version 0x%x on %s. Report to NixOS bugtracker\n", version, self_path);
|
||||
return 1;
|
||||
}
|
||||
|
||||
const struct __user_cap_header_struct header = {
|
||||
.version = _LINUX_CAPABILITY_VERSION_3,
|
||||
.pid = getpid(),
|
||||
};
|
||||
struct __user_cap_data_struct user_data[2] = {};
|
||||
|
||||
for (size_t i = 0; i < size; i++) {
|
||||
// merge inheritable & permitted into one
|
||||
user_data[i].permitted = user_data[i].inheritable =
|
||||
LE32_TO_H(data.data[i].inheritable) | LE32_TO_H(data.data[i].permitted);
|
||||
}
|
||||
|
||||
if (syscall(SYS_capset, &header, &user_data) < 0) {
|
||||
fprintf(stderr, "failed to inherit capabilities: %s", strerror(errno));
|
||||
return 1;
|
||||
}
|
||||
unsigned last_cap;
|
||||
r = get_last_cap(&last_cap);
|
||||
if (r < 0) {
|
||||
return 1;
|
||||
}
|
||||
uint64_t set = user_data[0].permitted | (uint64_t)user_data[1].permitted << 32;
|
||||
for (unsigned cap = 0; cap < last_cap; cap++) {
|
||||
if (!(set & (1ULL << cap))) {
|
||||
continue;
|
||||
}
|
||||
|
||||
// Check for the cap_setpcap capability, we set this on the
|
||||
// wrapper so it can elevate the capabilities to the Ambient
|
||||
// set but we do not want to propagate it down into the
|
||||
// wrapped program.
|
||||
//
|
||||
// TODO: what happens if that's the behavior you want
|
||||
// though???? I'm preferring a strict vs. loose policy here.
|
||||
if (cap == CAP_SETPCAP) {
|
||||
if(getenv(wrapper_debug)) {
|
||||
fprintf(stderr, "cap_setpcap in set, skipping it\n");
|
||||
}
|
||||
continue;
|
||||
}
|
||||
if (prctl(PR_CAP_AMBIENT, PR_CAP_AMBIENT_RAISE, (unsigned long) cap, 0, 0)) {
|
||||
fprintf(stderr, "cannot raise the capability %d into the ambient set: %s\n", cap, strerror(errno));
|
||||
return 1;
|
||||
}
|
||||
if (getenv(wrapper_debug)) {
|
||||
fprintf(stderr, "raised %d into the ambient capability set\n", cap);
|
||||
}
|
||||
}
|
||||
cap_free(capstr);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
int main(int argc, char * * argv)
|
||||
{
|
||||
// I *think* it's safe to assume that a path from a symbolic link
|
||||
// should safely fit within the PATH_MAX system limit. Though I'm
|
||||
// not positive it's safe...
|
||||
char selfPath[PATH_MAX];
|
||||
int selfPathSize = readlink("/proc/self/exe", selfPath, sizeof(selfPath));
|
||||
int readlink_malloc(const char *p, char **ret) {
|
||||
size_t l = FILENAME_MAX+1;
|
||||
int r;
|
||||
|
||||
assert(selfPathSize > 0);
|
||||
for (;;) {
|
||||
char *c = calloc(l, sizeof(char));
|
||||
if (!c) {
|
||||
return -ENOMEM;
|
||||
}
|
||||
|
||||
// Assert we have room for the zero byte, this ensures the path
|
||||
// isn't being truncated because it's too big for the buffer.
|
||||
//
|
||||
// A better way to handle this might be to use something like the
|
||||
// whereami library (https://github.com/gpakosz/whereami) or a
|
||||
// loop that resizes the buffer and re-reads the link if the
|
||||
// contents are being truncated.
|
||||
assert(selfPathSize < sizeof(selfPath));
|
||||
ssize_t n = readlink(p, c, l-1);
|
||||
if (n < 0) {
|
||||
r = -errno;
|
||||
free(c);
|
||||
return r;
|
||||
}
|
||||
|
||||
// Set the zero byte since readlink doesn't do that for us.
|
||||
selfPath[selfPathSize] = '\0';
|
||||
if ((size_t) n < l-1) {
|
||||
c[n] = 0;
|
||||
*ret = c;
|
||||
return 0;
|
||||
}
|
||||
|
||||
free(c);
|
||||
l *= 2;
|
||||
}
|
||||
}
|
||||
|
||||
int main(int argc, char **argv) {
|
||||
char *self_path = NULL;
|
||||
int self_path_size = readlink_malloc("/proc/self/exe", &self_path);
|
||||
if (self_path_size < 0) {
|
||||
fprintf(stderr, "cannot readlink /proc/self/exe: %s", strerror(-self_path_size));
|
||||
}
|
||||
|
||||
// Make sure that we are being executed from the right location,
|
||||
// i.e., `safeWrapperDir'. This is to prevent someone from creating
|
||||
// i.e., `safe_wrapper_dir'. This is to prevent someone from creating
|
||||
// hard link `X' from some other location, along with a false
|
||||
// `X.real' file, to allow arbitrary programs from being executed
|
||||
// with elevated capabilities.
|
||||
int len = strlen(wrapperDir);
|
||||
if (len > 0 && '/' == wrapperDir[len - 1])
|
||||
int len = strlen(wrapper_dir);
|
||||
if (len > 0 && '/' == wrapper_dir[len - 1])
|
||||
--len;
|
||||
assert(!strncmp(selfPath, wrapperDir, len));
|
||||
assert('/' == wrapperDir[0]);
|
||||
assert('/' == selfPath[len]);
|
||||
assert(!strncmp(self_path, wrapper_dir, len));
|
||||
assert('/' == wrapper_dir[0]);
|
||||
assert('/' == self_path[len]);
|
||||
|
||||
// Make *really* *really* sure that we were executed as
|
||||
// `selfPath', and not, say, as some other setuid program. That
|
||||
// `self_path', and not, say, as some other setuid program. That
|
||||
// is, our effective uid/gid should match the uid/gid of
|
||||
// `selfPath'.
|
||||
// `self_path'.
|
||||
struct stat st;
|
||||
assert(lstat(selfPath, &st) != -1);
|
||||
assert(lstat(self_path, &st) != -1);
|
||||
|
||||
assert(!(st.st_mode & S_ISUID) || (st.st_uid == geteuid()));
|
||||
assert(!(st.st_mode & S_ISGID) || (st.st_gid == getegid()));
|
||||
@ -207,33 +199,35 @@ int main(int argc, char * * argv)
|
||||
assert(!(st.st_mode & (S_IWGRP | S_IWOTH)));
|
||||
|
||||
// Read the path of the real (wrapped) program from <self>.real.
|
||||
char realFN[PATH_MAX + 10];
|
||||
int realFNSize = snprintf (realFN, sizeof(realFN), "%s.real", selfPath);
|
||||
assert (realFNSize < sizeof(realFN));
|
||||
char real_fn[PATH_MAX + 10];
|
||||
int real_fn_size = snprintf(real_fn, sizeof(real_fn), "%s.real", self_path);
|
||||
assert(real_fn_size < sizeof(real_fn));
|
||||
|
||||
int fdSelf = open(realFN, O_RDONLY);
|
||||
assert (fdSelf != -1);
|
||||
int fd_self = open(real_fn, O_RDONLY);
|
||||
assert(fd_self != -1);
|
||||
|
||||
char sourceProg[PATH_MAX];
|
||||
len = read(fdSelf, sourceProg, PATH_MAX);
|
||||
assert (len != -1);
|
||||
assert (len < sizeof(sourceProg));
|
||||
assert (len > 0);
|
||||
sourceProg[len] = 0;
|
||||
char source_prog[PATH_MAX];
|
||||
len = read(fd_self, source_prog, PATH_MAX);
|
||||
assert(len != -1);
|
||||
assert(len < sizeof(source_prog));
|
||||
assert(len > 0);
|
||||
source_prog[len] = 0;
|
||||
|
||||
close(fdSelf);
|
||||
close(fd_self);
|
||||
|
||||
// Read the capabilities set on the wrapper and raise them in to
|
||||
// the Ambient set so the program we're wrapping receives the
|
||||
// the ambient set so the program we're wrapping receives the
|
||||
// capabilities too!
|
||||
make_caps_ambient(selfPath);
|
||||
if (make_caps_ambient(self_path) != 0) {
|
||||
free(self_path);
|
||||
return 1;
|
||||
}
|
||||
free(self_path);
|
||||
|
||||
execve(sourceProg, argv, environ);
|
||||
execve(source_prog, argv, environ);
|
||||
|
||||
fprintf(stderr, "%s: cannot run `%s': %s\n",
|
||||
argv[0], sourceProg, strerror(errno));
|
||||
argv[0], source_prog, strerror(errno));
|
||||
|
||||
exit(1);
|
||||
return 1;
|
||||
}
|
||||
|
||||
|
||||
|
21
nixos/modules/security/wrappers/wrapper.nix
Normal file
21
nixos/modules/security/wrappers/wrapper.nix
Normal file
@ -0,0 +1,21 @@
|
||||
{ stdenv, linuxHeaders, parentWrapperDir, debug ? false }:
|
||||
# For testing:
|
||||
# $ nix-build -E 'with import <nixpkgs> {}; pkgs.callPackage ./wrapper.nix { parentWrapperDir = "/run/wrappers"; debug = true; }'
|
||||
stdenv.mkDerivation {
|
||||
name = "security-wrapper";
|
||||
buildInputs = [ linuxHeaders ];
|
||||
dontUnpack = true;
|
||||
hardeningEnable = [ "pie" ];
|
||||
CFLAGS = [
|
||||
''-DWRAPPER_DIR="${parentWrapperDir}"''
|
||||
] ++ (if debug then [
|
||||
"-Werror" "-Og" "-g"
|
||||
] else [
|
||||
"-Wall" "-O2"
|
||||
]);
|
||||
dontStrip = debug;
|
||||
installPhase = ''
|
||||
mkdir -p $out/bin
|
||||
$CC $CFLAGS ${./wrapper.c} -o $out/bin/security-wrapper
|
||||
'';
|
||||
}
|
@ -1,98 +0,0 @@
|
||||
# Disnix server
|
||||
{ config, lib, pkgs, ... }:
|
||||
|
||||
with lib;
|
||||
|
||||
let
|
||||
|
||||
cfg = config.services.disnix;
|
||||
|
||||
in
|
||||
|
||||
{
|
||||
|
||||
###### interface
|
||||
|
||||
options = {
|
||||
|
||||
services.disnix = {
|
||||
|
||||
enable = mkEnableOption "Disnix";
|
||||
|
||||
enableMultiUser = mkOption {
|
||||
type = types.bool;
|
||||
default = true;
|
||||
description = "Whether to support multi-user mode by enabling the Disnix D-Bus service";
|
||||
};
|
||||
|
||||
useWebServiceInterface = mkEnableOption "the DisnixWebService interface running on Apache Tomcat";
|
||||
|
||||
package = mkOption {
|
||||
type = types.path;
|
||||
description = "The Disnix package";
|
||||
default = pkgs.disnix;
|
||||
defaultText = "pkgs.disnix";
|
||||
};
|
||||
|
||||
enableProfilePath = mkEnableOption "exposing the Disnix profiles in the system's PATH";
|
||||
|
||||
profiles = mkOption {
|
||||
type = types.listOf types.string;
|
||||
default = [ "default" ];
|
||||
example = [ "default" ];
|
||||
description = "Names of the Disnix profiles to expose in the system's PATH";
|
||||
};
|
||||
};
|
||||
|
||||
};
|
||||
|
||||
###### implementation
|
||||
|
||||
config = mkIf cfg.enable {
|
||||
dysnomia.enable = true;
|
||||
|
||||
environment.systemPackages = [ pkgs.disnix ] ++ optional cfg.useWebServiceInterface pkgs.DisnixWebService;
|
||||
environment.variables.PATH = lib.optionals cfg.enableProfilePath (map (profileName: "/nix/var/nix/profiles/disnix/${profileName}/bin" ) cfg.profiles);
|
||||
|
||||
services.dbus.enable = true;
|
||||
services.dbus.packages = [ pkgs.disnix ];
|
||||
|
||||
services.tomcat.enable = cfg.useWebServiceInterface;
|
||||
services.tomcat.extraGroups = [ "disnix" ];
|
||||
services.tomcat.javaOpts = "${optionalString cfg.useWebServiceInterface "-Djava.library.path=${pkgs.libmatthew_java}/lib/jni"} ";
|
||||
services.tomcat.sharedLibs = optional cfg.useWebServiceInterface "${pkgs.DisnixWebService}/share/java/DisnixConnection.jar"
|
||||
++ optional cfg.useWebServiceInterface "${pkgs.dbus_java}/share/java/dbus.jar";
|
||||
services.tomcat.webapps = optional cfg.useWebServiceInterface pkgs.DisnixWebService;
|
||||
|
||||
users.groups.disnix.gid = config.ids.gids.disnix;
|
||||
|
||||
systemd.services = {
|
||||
disnix = mkIf cfg.enableMultiUser {
|
||||
description = "Disnix server";
|
||||
wants = [ "dysnomia.target" ];
|
||||
wantedBy = [ "multi-user.target" ];
|
||||
after = [ "dbus.service" ]
|
||||
++ optional config.services.httpd.enable "httpd.service"
|
||||
++ optional config.services.mysql.enable "mysql.service"
|
||||
++ optional config.services.postgresql.enable "postgresql.service"
|
||||
++ optional config.services.tomcat.enable "tomcat.service"
|
||||
++ optional config.services.svnserve.enable "svnserve.service"
|
||||
++ optional config.services.mongodb.enable "mongodb.service"
|
||||
++ optional config.services.influxdb.enable "influxdb.service";
|
||||
|
||||
restartIfChanged = false;
|
||||
|
||||
path = [ config.nix.package cfg.package config.dysnomia.package "/run/current-system/sw" ];
|
||||
|
||||
environment = {
|
||||
HOME = "/root";
|
||||
}
|
||||
// (if config.environment.variables ? DYSNOMIA_CONTAINERS_PATH then { inherit (config.environment.variables) DYSNOMIA_CONTAINERS_PATH; } else {})
|
||||
// (if config.environment.variables ? DYSNOMIA_MODULES_PATH then { inherit (config.environment.variables) DYSNOMIA_MODULES_PATH; } else {});
|
||||
|
||||
serviceConfig.ExecStart = "${cfg.package}/bin/disnix-service";
|
||||
};
|
||||
|
||||
};
|
||||
};
|
||||
}
|
@ -1,257 +0,0 @@
|
||||
{pkgs, lib, config, ...}:
|
||||
|
||||
with lib;
|
||||
|
||||
let
|
||||
cfg = config.dysnomia;
|
||||
|
||||
printProperties = properties:
|
||||
concatMapStrings (propertyName:
|
||||
let
|
||||
property = properties.${propertyName};
|
||||
in
|
||||
if isList property then "${propertyName}=(${lib.concatMapStrings (elem: "\"${toString elem}\" ") (properties.${propertyName})})\n"
|
||||
else "${propertyName}=\"${toString property}\"\n"
|
||||
) (builtins.attrNames properties);
|
||||
|
||||
properties = pkgs.stdenv.mkDerivation {
|
||||
name = "dysnomia-properties";
|
||||
buildCommand = ''
|
||||
cat > $out << "EOF"
|
||||
${printProperties cfg.properties}
|
||||
EOF
|
||||
'';
|
||||
};
|
||||
|
||||
containersDir = pkgs.stdenv.mkDerivation {
|
||||
name = "dysnomia-containers";
|
||||
buildCommand = ''
|
||||
mkdir -p $out
|
||||
cd $out
|
||||
|
||||
${concatMapStrings (containerName:
|
||||
let
|
||||
containerProperties = cfg.containers.${containerName};
|
||||
in
|
||||
''
|
||||
cat > ${containerName} <<EOF
|
||||
${printProperties containerProperties}
|
||||
type=${containerName}
|
||||
EOF
|
||||
''
|
||||
) (builtins.attrNames cfg.containers)}
|
||||
'';
|
||||
};
|
||||
|
||||
linkMutableComponents = {containerName}:
|
||||
''
|
||||
mkdir ${containerName}
|
||||
|
||||
${concatMapStrings (componentName:
|
||||
let
|
||||
component = cfg.components.${containerName}.${componentName};
|
||||
in
|
||||
"ln -s ${component} ${containerName}/${componentName}\n"
|
||||
) (builtins.attrNames (cfg.components.${containerName} or {}))}
|
||||
'';
|
||||
|
||||
componentsDir = pkgs.stdenv.mkDerivation {
|
||||
name = "dysnomia-components";
|
||||
buildCommand = ''
|
||||
mkdir -p $out
|
||||
cd $out
|
||||
|
||||
${concatMapStrings (containerName:
|
||||
linkMutableComponents { inherit containerName; }
|
||||
) (builtins.attrNames cfg.components)}
|
||||
'';
|
||||
};
|
||||
|
||||
dysnomiaFlags = {
|
||||
enableApacheWebApplication = config.services.httpd.enable;
|
||||
enableAxis2WebService = config.services.tomcat.axis2.enable;
|
||||
enableDockerContainer = config.virtualisation.docker.enable;
|
||||
enableEjabberdDump = config.services.ejabberd.enable;
|
||||
enableMySQLDatabase = config.services.mysql.enable;
|
||||
enablePostgreSQLDatabase = config.services.postgresql.enable;
|
||||
enableTomcatWebApplication = config.services.tomcat.enable;
|
||||
enableMongoDatabase = config.services.mongodb.enable;
|
||||
enableSubversionRepository = config.services.svnserve.enable;
|
||||
enableInfluxDatabase = config.services.influxdb.enable;
|
||||
};
|
||||
in
|
||||
{
|
||||
options = {
|
||||
dysnomia = {
|
||||
|
||||
enable = mkOption {
|
||||
type = types.bool;
|
||||
default = false;
|
||||
description = "Whether to enable Dysnomia";
|
||||
};
|
||||
|
||||
enableAuthentication = mkOption {
|
||||
type = types.bool;
|
||||
default = false;
|
||||
description = "Whether to publish privacy-sensitive authentication credentials";
|
||||
};
|
||||
|
||||
package = mkOption {
|
||||
type = types.path;
|
||||
description = "The Dysnomia package";
|
||||
};
|
||||
|
||||
properties = mkOption {
|
||||
description = "An attribute set in which each attribute represents a machine property. Optionally, these values can be shell substitutions.";
|
||||
default = {};
|
||||
};
|
||||
|
||||
containers = mkOption {
|
||||
description = "An attribute set in which each key represents a container and each value an attribute set providing its configuration properties";
|
||||
default = {};
|
||||
};
|
||||
|
||||
components = mkOption {
|
||||
description = "An atttribute set in which each key represents a container and each value an attribute set in which each key represents a component and each value a derivation constructing its initial state";
|
||||
default = {};
|
||||
};
|
||||
|
||||
extraContainerProperties = mkOption {
|
||||
description = "An attribute set providing additional container settings in addition to the default properties";
|
||||
default = {};
|
||||
};
|
||||
|
||||
extraContainerPaths = mkOption {
|
||||
description = "A list of paths containing additional container configurations that are added to the search folders";
|
||||
default = [];
|
||||
};
|
||||
|
||||
extraModulePaths = mkOption {
|
||||
description = "A list of paths containing additional modules that are added to the search folders";
|
||||
default = [];
|
||||
};
|
||||
|
||||
enableLegacyModules = mkOption {
|
||||
type = types.bool;
|
||||
default = true;
|
||||
description = "Whether to enable Dysnomia legacy process and wrapper modules";
|
||||
};
|
||||
};
|
||||
};
|
||||
|
||||
config = mkIf cfg.enable {
|
||||
|
||||
environment.etc = {
|
||||
"dysnomia/containers" = {
|
||||
source = containersDir;
|
||||
};
|
||||
"dysnomia/components" = {
|
||||
source = componentsDir;
|
||||
};
|
||||
"dysnomia/properties" = {
|
||||
source = properties;
|
||||
};
|
||||
};
|
||||
|
||||
environment.variables = {
|
||||
DYSNOMIA_STATEDIR = "/var/state/dysnomia-nixos";
|
||||
DYSNOMIA_CONTAINERS_PATH = "${lib.concatMapStrings (containerPath: "${containerPath}:") cfg.extraContainerPaths}/etc/dysnomia/containers";
|
||||
DYSNOMIA_MODULES_PATH = "${lib.concatMapStrings (modulePath: "${modulePath}:") cfg.extraModulePaths}/etc/dysnomia/modules";
|
||||
};
|
||||
|
||||
environment.systemPackages = [ cfg.package ];
|
||||
|
||||
dysnomia.package = pkgs.dysnomia.override (origArgs: dysnomiaFlags // lib.optionalAttrs (cfg.enableLegacyModules) {
|
||||
enableLegacy = builtins.trace ''
|
||||
WARNING: Dysnomia has been configured to use the legacy 'process' and 'wrapper'
|
||||
modules for compatibility reasons! If you rely on these modules, consider
|
||||
migrating to better alternatives.
|
||||
|
||||
More information: https://raw.githubusercontent.com/svanderburg/dysnomia/f65a9a84827bcc4024d6b16527098b33b02e4054/README-legacy.md
|
||||
|
||||
If you have migrated already or don't rely on these Dysnomia modules, you can
|
||||
disable legacy mode with the following NixOS configuration option:
|
||||
|
||||
dysnomia.enableLegacyModules = false;
|
||||
|
||||
In a future version of Dysnomia (and NixOS) the legacy option will go away!
|
||||
'' true;
|
||||
});
|
||||
|
||||
dysnomia.properties = {
|
||||
hostname = config.networking.hostName;
|
||||
inherit (config.nixpkgs.localSystem) system;
|
||||
|
||||
supportedTypes = [
|
||||
"echo"
|
||||
"fileset"
|
||||
"process"
|
||||
"wrapper"
|
||||
|
||||
# These are not base modules, but they are still enabled because they work with technology that are always enabled in NixOS
|
||||
"systemd-unit"
|
||||
"sysvinit-script"
|
||||
"nixos-configuration"
|
||||
]
|
||||
++ optional (dysnomiaFlags.enableApacheWebApplication) "apache-webapplication"
|
||||
++ optional (dysnomiaFlags.enableAxis2WebService) "axis2-webservice"
|
||||
++ optional (dysnomiaFlags.enableDockerContainer) "docker-container"
|
||||
++ optional (dysnomiaFlags.enableEjabberdDump) "ejabberd-dump"
|
||||
++ optional (dysnomiaFlags.enableInfluxDatabase) "influx-database"
|
||||
++ optional (dysnomiaFlags.enableMySQLDatabase) "mysql-database"
|
||||
++ optional (dysnomiaFlags.enablePostgreSQLDatabase) "postgresql-database"
|
||||
++ optional (dysnomiaFlags.enableTomcatWebApplication) "tomcat-webapplication"
|
||||
++ optional (dysnomiaFlags.enableMongoDatabase) "mongo-database"
|
||||
++ optional (dysnomiaFlags.enableSubversionRepository) "subversion-repository";
|
||||
};
|
||||
|
||||
dysnomia.containers = lib.recursiveUpdate ({
|
||||
process = {};
|
||||
wrapper = {};
|
||||
}
|
||||
// lib.optionalAttrs (config.services.httpd.enable) { apache-webapplication = {
|
||||
documentRoot = config.services.httpd.virtualHosts.localhost.documentRoot;
|
||||
}; }
|
||||
// lib.optionalAttrs (config.services.tomcat.axis2.enable) { axis2-webservice = {}; }
|
||||
// lib.optionalAttrs (config.services.ejabberd.enable) { ejabberd-dump = {
|
||||
ejabberdUser = config.services.ejabberd.user;
|
||||
}; }
|
||||
// lib.optionalAttrs (config.services.mysql.enable) { mysql-database = {
|
||||
mysqlPort = config.services.mysql.port;
|
||||
mysqlSocket = "/run/mysqld/mysqld.sock";
|
||||
} // lib.optionalAttrs cfg.enableAuthentication {
|
||||
mysqlUsername = "root";
|
||||
};
|
||||
}
|
||||
// lib.optionalAttrs (config.services.postgresql.enable) { postgresql-database = {
|
||||
} // lib.optionalAttrs (cfg.enableAuthentication) {
|
||||
postgresqlUsername = "postgres";
|
||||
};
|
||||
}
|
||||
// lib.optionalAttrs (config.services.tomcat.enable) { tomcat-webapplication = {
|
||||
tomcatPort = 8080;
|
||||
}; }
|
||||
// lib.optionalAttrs (config.services.mongodb.enable) { mongo-database = {}; }
|
||||
// lib.optionalAttrs (config.services.influxdb.enable) {
|
||||
influx-database = {
|
||||
influxdbUsername = config.services.influxdb.user;
|
||||
influxdbDataDir = "${config.services.influxdb.dataDir}/data";
|
||||
influxdbMetaDir = "${config.services.influxdb.dataDir}/meta";
|
||||
};
|
||||
}
|
||||
// lib.optionalAttrs (config.services.svnserve.enable) { subversion-repository = {
|
||||
svnBaseDir = config.services.svnserve.svnBaseDir;
|
||||
}; }) cfg.extraContainerProperties;
|
||||
|
||||
system.activationScripts.dysnomia = ''
|
||||
mkdir -p /etc/systemd-mutable/system
|
||||
if [ ! -f /etc/systemd-mutable/system/dysnomia.target ]
|
||||
then
|
||||
( echo "[Unit]"
|
||||
echo "Description=Services that are activated and deactivated by Dysnomia"
|
||||
echo "After=final.target"
|
||||
) > /etc/systemd-mutable/system/dysnomia.target
|
||||
fi
|
||||
'';
|
||||
};
|
||||
}
|
140
nixos/modules/services/networking/pleroma.nix
Normal file
140
nixos/modules/services/networking/pleroma.nix
Normal file
@ -0,0 +1,140 @@
|
||||
{ config, options, lib, pkgs, stdenv, ... }:
|
||||
let
|
||||
cfg = config.services.pleroma;
|
||||
in {
|
||||
options = {
|
||||
services.pleroma = with lib; {
|
||||
enable = mkEnableOption "pleroma";
|
||||
|
||||
package = mkOption {
|
||||
type = types.package;
|
||||
default = pkgs.pleroma-otp;
|
||||
description = "Pleroma package to use.";
|
||||
};
|
||||
|
||||
user = mkOption {
|
||||
type = types.str;
|
||||
default = "pleroma";
|
||||
description = "User account under which pleroma runs.";
|
||||
};
|
||||
|
||||
group = mkOption {
|
||||
type = types.str;
|
||||
default = "pleroma";
|
||||
description = "Group account under which pleroma runs.";
|
||||
};
|
||||
|
||||
stateDir = mkOption {
|
||||
type = types.str;
|
||||
default = "/var/lib/pleroma";
|
||||
readOnly = true;
|
||||
description = "Directory where the pleroma service will save the uploads and static files.";
|
||||
};
|
||||
|
||||
configs = mkOption {
|
||||
type = with types; listOf str;
|
||||
description = ''
|
||||
Pleroma public configuration.
|
||||
|
||||
This list gets appended from left to
|
||||
right into /etc/pleroma/config.exs. Elixir evaluates its
|
||||
configuration imperatively, meaning you can override a
|
||||
setting by appending a new str to this NixOS option list.
|
||||
|
||||
<emphasis>DO NOT STORE ANY PLEROMA SECRET
|
||||
HERE</emphasis>, use
|
||||
<link linkend="opt-services.pleroma.secretConfigFile">services.pleroma.secretConfigFile</link>
|
||||
instead.
|
||||
|
||||
This setting is going to be stored in a file part of
|
||||
the Nix store. The Nix store being world-readable, it's not
|
||||
the right place to store any secret
|
||||
|
||||
Have a look to Pleroma section in the NixOS manual for more
|
||||
informations.
|
||||
'';
|
||||
};
|
||||
|
||||
secretConfigFile = mkOption {
|
||||
type = types.str;
|
||||
default = "/var/lib/pleroma/secrets.exs";
|
||||
description = ''
|
||||
Path to the file containing your secret pleroma configuration.
|
||||
|
||||
<emphasis>DO NOT POINT THIS OPTION TO THE NIX
|
||||
STORE</emphasis>, the store being world-readable, it'll
|
||||
compromise all your secrets.
|
||||
'';
|
||||
};
|
||||
};
|
||||
};
|
||||
|
||||
config = lib.mkIf cfg.enable {
|
||||
users = {
|
||||
users."${cfg.user}" = {
|
||||
description = "Pleroma user";
|
||||
home = cfg.stateDir;
|
||||
extraGroups = [ cfg.group ];
|
||||
};
|
||||
groups."${cfg.group}" = {};
|
||||
};
|
||||
|
||||
environment.systemPackages = [ cfg.package ];
|
||||
|
||||
environment.etc."/pleroma/config.exs".text = ''
|
||||
${lib.concatMapStrings (x: "${x}") cfg.configs}
|
||||
|
||||
# The lau/tzdata library is trying to download the latest
|
||||
# timezone database in the OTP priv directory by default.
|
||||
# This directory being in the store, it's read-only.
|
||||
# Setting that up to a more appropriate location.
|
||||
config :tzdata, :data_dir, "/var/lib/pleroma/elixir_tzdata_data"
|
||||
|
||||
import_config "${cfg.secretConfigFile}"
|
||||
'';
|
||||
|
||||
systemd.services.pleroma = {
|
||||
description = "Pleroma social network";
|
||||
after = [ "network-online.target" "postgresql.service" ];
|
||||
wantedBy = [ "multi-user.target" ];
|
||||
restartTriggers = [ config.environment.etc."/pleroma/config.exs".source ];
|
||||
serviceConfig = {
|
||||
User = cfg.user;
|
||||
Group = cfg.group;
|
||||
Type = "exec";
|
||||
WorkingDirectory = "~";
|
||||
StateDirectory = "pleroma pleroma/static pleroma/uploads";
|
||||
StateDirectoryMode = "700";
|
||||
|
||||
# Checking the conf file is there then running the database
|
||||
# migration before each service start, just in case there are
|
||||
# some pending ones.
|
||||
#
|
||||
# It's sub-optimal as we'll always run this, even if pleroma
|
||||
# has not been updated. But the no-op process is pretty fast.
|
||||
# Better be safe than sorry migration-wise.
|
||||
ExecStartPre =
|
||||
let preScript = pkgs.writers.writeBashBin "pleromaStartPre"
|
||||
"${cfg.package}/bin/pleroma_ctl migrate";
|
||||
in "${preScript}/bin/pleromaStartPre";
|
||||
|
||||
ExecStart = "${cfg.package}/bin/pleroma start";
|
||||
ExecStop = "${cfg.package}/bin/pleroma stop";
|
||||
ExecReload = "${pkgs.coreutils}/bin/kill -HUP $MAINPID";
|
||||
|
||||
# Systemd sandboxing directives.
|
||||
# Taken from the upstream contrib systemd service at
|
||||
# pleroma/installation/pleroma.service
|
||||
PrivateTmp = true;
|
||||
ProtectHome = true;
|
||||
ProtectSystem = "full";
|
||||
PrivateDevices = false;
|
||||
NoNewPrivileges = true;
|
||||
CapabilityBoundingSet = "~CAP_SYS_ADMIN";
|
||||
};
|
||||
};
|
||||
|
||||
};
|
||||
meta.maintainers = with lib.maintainers; [ ninjatrappeur ];
|
||||
meta.doc = ./pleroma.xml;
|
||||
}
|
132
nixos/modules/services/networking/pleroma.xml
Normal file
132
nixos/modules/services/networking/pleroma.xml
Normal file
@ -0,0 +1,132 @@
|
||||
<chapter xmlns="http://docbook.org/ns/docbook"
|
||||
xmlns:xlink="http://www.w3.org/1999/xlink"
|
||||
xmlns:xi="http://www.w3.org/2001/XInclude"
|
||||
version="5.0"
|
||||
xml:id="module-services-pleroma">
|
||||
<title>Pleroma</title>
|
||||
<para><link xlink:href="https://pleroma.social/">Pleroma</link> is a lightweight activity pub server.</para>
|
||||
<section xml:id="module-services-pleroma-getting-started">
|
||||
<title>Quick Start</title>
|
||||
<para>To get quickly started, you can use this sample NixOS configuration and adapt it to your use case.</para>
|
||||
<para><programlisting>
|
||||
{
|
||||
security.acme = {
|
||||
email = "root@tld";
|
||||
acceptTerms = true;
|
||||
certs = {
|
||||
"social.tld.com" = {
|
||||
webroot = "/var/www/social.tld.com";
|
||||
email = "root@tld";
|
||||
group = "nginx";
|
||||
};
|
||||
};
|
||||
};
|
||||
services = {
|
||||
pleroma = {
|
||||
enable = true;
|
||||
secretConfigFile = "/var/lib/pleroma/secrets.exs";
|
||||
configs = [
|
||||
''
|
||||
import Config
|
||||
|
||||
config :pleroma, Pleroma.Web.Endpoint,
|
||||
url: [host: "social.tld.com", scheme: "https", port: 443],
|
||||
http: [ip: {127, 0, 0, 1}, port: 4000]
|
||||
|
||||
config :pleroma, :instance,
|
||||
name: "NixOS test pleroma server",
|
||||
email: "pleroma@social.tld.com",
|
||||
notify_email: "pleroma@social.tld.com",
|
||||
limit: 5000,
|
||||
registrations_open: true
|
||||
|
||||
config :pleroma, :media_proxy,
|
||||
enabled: false,
|
||||
redirect_on_failure: true
|
||||
#base_url: "https://cache.pleroma.social"
|
||||
|
||||
config :pleroma, Pleroma.Repo,
|
||||
adapter: Ecto.Adapters.Postgres,
|
||||
username: "pleroma",
|
||||
password: "${test-db-passwd}",
|
||||
database: "pleroma",
|
||||
hostname: "localhost",
|
||||
pool_size: 10,
|
||||
prepare: :named,
|
||||
parameters: [
|
||||
plan_cache_mode: "force_custom_plan"
|
||||
]
|
||||
|
||||
config :pleroma, :database, rum_enabled: false
|
||||
config :pleroma, :instance, static_dir: "/var/lib/pleroma/static"
|
||||
config :pleroma, Pleroma.Uploaders.Local, uploads: "/var/lib/pleroma/uploads"
|
||||
config :pleroma, configurable_from_database: false
|
||||
''
|
||||
];
|
||||
};
|
||||
postgresql = {
|
||||
enable = true;
|
||||
package = pkgs.postgresql_12;
|
||||
};
|
||||
nginx = {
|
||||
enable = true;
|
||||
addSSL = true;
|
||||
sslCertificate = "/var/lib/acme/social.tld.com/fullchain.pem";
|
||||
sslCertificateKey = "/var/lib/acme/social.tld.com/key.pem";
|
||||
root = "/var/www/social.tld.com";
|
||||
# ACME endpoint
|
||||
locations."/.well-known/acme-challenge" = {
|
||||
root = "/var/www/social.tld.com/";
|
||||
};
|
||||
virtualHosts."social.tld.com" = {
|
||||
addSSL = true;
|
||||
locations."/" = {
|
||||
proxyPass = "http://127.0.0.1:4000";
|
||||
extraConfig = ''
|
||||
add_header 'Access-Control-Allow-Origin' '*' always;
|
||||
add_header 'Access-Control-Allow-Methods' 'POST, PUT, DELETE, GET, PATCH, OPTIONS' always;
|
||||
add_header 'Access-Control-Allow-Headers' 'Authorization, Content-Type, Idempotency-Key' always;
|
||||
add_header 'Access-Control-Expose-Headers' 'Link, X-RateLimit-Reset, X-RateLimit-Limit, X-RateLimit-Remaining, X-Request-Id' always;
|
||||
if ($request_method = OPTIONS) {
|
||||
return 204;
|
||||
}
|
||||
add_header X-XSS-Protection "1; mode=block";
|
||||
add_header X-Permitted-Cross-Domain-Policies none;
|
||||
add_header X-Frame-Options DENY;
|
||||
add_header X-Content-Type-Options nosniff;
|
||||
add_header Referrer-Policy same-origin;
|
||||
add_header X-Download-Options noopen;
|
||||
proxy_http_version 1.1;
|
||||
proxy_set_header Upgrade $http_upgrade;
|
||||
proxy_set_header Connection "upgrade";
|
||||
proxy_set_header Host $host;
|
||||
client_max_body_size 16m;
|
||||
'';
|
||||
};
|
||||
};
|
||||
};
|
||||
};
|
||||
};
|
||||
</programlisting></para>
|
||||
<para>Note that you'll need to seed your database and upload your pleroma secrets to the path pointed by <literal>config.pleroma.secretConfigFile</literal>. You can find more informations about how to do that in the <link linkend="module-services-pleroma-generate-config">next</link> section.</para>
|
||||
</section>
|
||||
<section xml:id="module-services-pleroma-generate-config">
|
||||
<title>Generating the Pleroma Config and Seed the Database</title>
|
||||
|
||||
<para>Before using this service, you'll need to generate your
|
||||
server configuration and its associated database seed. The
|
||||
<literal>pleroma_ctl</literal> CLI utility can help you with that. You
|
||||
can start with <literal>pleroma_ctl instance gen --output config.exs
|
||||
--output-psql setup.psql</literal>, this will prompt you some
|
||||
questions and will generate both your config file and database initial
|
||||
migration. </para>
|
||||
<para>For more details about this configuration format, please have a look at the <link xlink:href="https://docs-develop.pleroma.social/backend/configuration/cheatsheet/">upstream documentation</link>.</para>
|
||||
<para>To seed your database, you can use the <literal>setup.psql</literal> file you just generated by running
|
||||
<programlisting>
|
||||
sudo -u postgres psql -f setup.psql
|
||||
</programlisting></para>
|
||||
<para>In regard of the pleroma service configuration you also just generated, you'll need to split it in two parts. The "public" part, which do not contain any secrets and thus can be safely stored in the Nix store and its "private" counterpart containing some secrets (database password, endpoint secret key, salts, etc.).</para>
|
||||
|
||||
<para>The public part will live in your NixOS machine configuration in the <link linkend="opt-services.pleroma.configs">services.pleroma.configs</link> option. However, it's up to you to upload the secret pleroma configuration to the path pointed by <link linkend="opt-services.pleroma.secretConfigFile">services.pleroma.secretConfigFile</link>. You can do that manually or rely on a third party tool such as <link xlink:href="https://github.com/DBCDK/morph">Morph</link> or <link xlink:href="https://github.com/NixOS/nixops">NixOps</link>.</para>
|
||||
</section>
|
||||
</chapter>
|
@ -77,6 +77,27 @@ in import ./make-test-python.nix ({ lib, ... }: {
|
||||
after = [ "acme-a.example.test.service" "nginx-config-reload.service" ];
|
||||
};
|
||||
|
||||
# Test that account creation is collated into one service
|
||||
specialisation.account-creation.configuration = { nodes, pkgs, lib, ... }: let
|
||||
email = "newhostmaster@example.test";
|
||||
caDomain = nodes.acme.config.test-support.acme.caDomain;
|
||||
# Exit 99 to make it easier to track if this is the reason a renew failed
|
||||
testScript = ''
|
||||
test -e accounts/${caDomain}/${email}/account.json || exit 99
|
||||
'';
|
||||
in {
|
||||
security.acme.email = lib.mkForce email;
|
||||
systemd.services."b.example.test".preStart = testScript;
|
||||
systemd.services."c.example.test".preStart = testScript;
|
||||
|
||||
services.nginx.virtualHosts."b.example.test" = (vhostBase pkgs) // {
|
||||
enableACME = true;
|
||||
};
|
||||
services.nginx.virtualHosts."c.example.test" = (vhostBase pkgs) // {
|
||||
enableACME = true;
|
||||
};
|
||||
};
|
||||
|
||||
# Cert config changes will not cause the nginx configuration to change.
|
||||
# This tests that the reload service is correctly triggered.
|
||||
# It also tests that postRun is exec'd as root
|
||||
@ -289,7 +310,7 @@ in import ./make-test-python.nix ({ lib, ... }: {
|
||||
acme.start()
|
||||
webserver.start()
|
||||
|
||||
acme.wait_for_unit("default.target")
|
||||
acme.wait_for_unit("network-online.target")
|
||||
acme.wait_for_unit("pebble.service")
|
||||
|
||||
client.succeed("curl https://${caDomain}:15000/roots/0 > /tmp/ca.crt")
|
||||
@ -314,6 +335,15 @@ in import ./make-test-python.nix ({ lib, ... }: {
|
||||
check_issuer(webserver, "a.example.test", "pebble")
|
||||
check_connection(client, "a.example.test")
|
||||
|
||||
with subtest("Runs 1 cert for account creation before others"):
|
||||
switch_to(webserver, "account-creation")
|
||||
webserver.wait_for_unit("acme-finished-a.example.test.target")
|
||||
check_connection(client, "a.example.test")
|
||||
webserver.wait_for_unit("acme-finished-b.example.test.target")
|
||||
webserver.wait_for_unit("acme-finished-c.example.test.target")
|
||||
check_connection(client, "b.example.test")
|
||||
check_connection(client, "c.example.test")
|
||||
|
||||
with subtest("Can reload web server when cert configuration changes"):
|
||||
switch_to(webserver, "cert-change")
|
||||
webserver.wait_for_unit("acme-finished-a.example.test.target")
|
||||
|
@ -303,6 +303,7 @@ in
|
||||
php = handleTest ./php {};
|
||||
pinnwand = handleTest ./pinnwand.nix {};
|
||||
plasma5 = handleTest ./plasma5.nix {};
|
||||
pleroma = handleTestOn [ "x86_64-linux" "aarch64-linux" ] ./pleroma.nix {};
|
||||
plotinus = handleTest ./plotinus.nix {};
|
||||
podman = handleTestOn ["x86_64-linux"] ./podman.nix {};
|
||||
postfix = handleTest ./postfix.nix {};
|
||||
|
265
nixos/tests/pleroma.nix
Normal file
265
nixos/tests/pleroma.nix
Normal file
@ -0,0 +1,265 @@
|
||||
/*
|
||||
Pleroma E2E VM test.
|
||||
|
||||
Abstract:
|
||||
=========
|
||||
Using pleroma, postgresql, a local CA cert, a nginx reverse proxy
|
||||
and a toot-based client, we're going to:
|
||||
|
||||
1. Provision a pleroma service from scratch (pleroma config + postgres db).
|
||||
2. Create a "jamy" admin user.
|
||||
3. Send a toot from this user.
|
||||
4. Send a upload from this user.
|
||||
5. Check the toot is part of the server public timeline
|
||||
|
||||
Notes:
|
||||
- We need a fully functional TLS setup without having any access to
|
||||
the internet. We do that by issuing a self-signed cert, add this
|
||||
self-cert to the hosts pki trust store and finally spoof the
|
||||
hostnames using /etc/hosts.
|
||||
- For this NixOS test, we *had* to store some DB-related and
|
||||
pleroma-related secrets to the store. Keep in mind the store is
|
||||
world-readable, it's the worst place possible to store *any*
|
||||
secret. **DO NOT DO THIS IN A REAL WORLD DEPLOYMENT**.
|
||||
*/
|
||||
|
||||
import ./make-test-python.nix ({ pkgs, ... }:
|
||||
let
|
||||
send-toot = pkgs.writeScriptBin "send-toot" ''
|
||||
set -eux
|
||||
# toot is using the requests library internally. This library
|
||||
# sadly embed its own certificate store instead of relying on the
|
||||
# system one. Overriding this pretty bad default behaviour.
|
||||
export REQUESTS_CA_BUNDLE=/etc/ssl/certs/ca-certificates.crt
|
||||
|
||||
export TOOT_LOGIN_CLI_PASSWORD="jamy-password"
|
||||
toot login_cli -i "pleroma.nixos.test" -e "jamy@nixos.test"
|
||||
echo "Login OK"
|
||||
|
||||
# Send a toot then verify it's part of the public timeline
|
||||
echo "y" | toot post "hello world Jamy here"
|
||||
echo "Send toot OK"
|
||||
echo "y" | toot timeline | grep -c "hello world Jamy here"
|
||||
echo "Get toot from timeline OK"
|
||||
|
||||
# Test file upload
|
||||
echo "y" | toot upload ${db-seed} | grep -c "https://pleroma.nixos.test/media"
|
||||
echo "File upload OK"
|
||||
|
||||
echo "====================================================="
|
||||
echo "= SUCCESS ="
|
||||
echo "= ="
|
||||
echo "= We were able to sent a toot + a upload and ="
|
||||
echo "= retrieve both of them in the public timeline. ="
|
||||
echo "====================================================="
|
||||
'';
|
||||
|
||||
provision-db = pkgs.writeScriptBin "provision-db" ''
|
||||
set -eux
|
||||
sudo -u postgres psql -f ${db-seed}
|
||||
'';
|
||||
|
||||
test-db-passwd = "SccZOvTGM//BMrpoQj68JJkjDkMGb4pHv2cECWiI+XhVe3uGJTLI0vFV/gDlZ5jJ";
|
||||
|
||||
/* For this NixOS test, we *had* to store this secret to the store.
|
||||
Keep in mind the store is world-readable, it's the worst place
|
||||
possible to store *any* secret. **DO NOT DO THIS IN A REAL WORLD
|
||||
DEPLOYMENT**.*/
|
||||
db-seed = pkgs.writeText "provision.psql" ''
|
||||
CREATE USER pleroma WITH ENCRYPTED PASSWORD '${test-db-passwd}';
|
||||
CREATE DATABASE pleroma OWNER pleroma;
|
||||
\c pleroma;
|
||||
--Extensions made by ecto.migrate that need superuser access
|
||||
CREATE EXTENSION IF NOT EXISTS citext;
|
||||
CREATE EXTENSION IF NOT EXISTS pg_trgm;
|
||||
CREATE EXTENSION IF NOT EXISTS "uuid-ossp";
|
||||
'';
|
||||
|
||||
pleroma-conf = ''
|
||||
import Config
|
||||
|
||||
config :pleroma, Pleroma.Web.Endpoint,
|
||||
url: [host: "pleroma.nixos.test", scheme: "https", port: 443],
|
||||
http: [ip: {127, 0, 0, 1}, port: 4000]
|
||||
|
||||
config :pleroma, :instance,
|
||||
name: "NixOS test pleroma server",
|
||||
email: "pleroma@nixos.test",
|
||||
notify_email: "pleroma@nixos.test",
|
||||
limit: 5000,
|
||||
registrations_open: true
|
||||
|
||||
config :pleroma, :media_proxy,
|
||||
enabled: false,
|
||||
redirect_on_failure: true
|
||||
#base_url: "https://cache.pleroma.social"
|
||||
|
||||
config :pleroma, Pleroma.Repo,
|
||||
adapter: Ecto.Adapters.Postgres,
|
||||
username: "pleroma",
|
||||
password: "${test-db-passwd}",
|
||||
database: "pleroma",
|
||||
hostname: "localhost",
|
||||
pool_size: 10,
|
||||
prepare: :named,
|
||||
parameters: [
|
||||
plan_cache_mode: "force_custom_plan"
|
||||
]
|
||||
|
||||
config :pleroma, :database, rum_enabled: false
|
||||
config :pleroma, :instance, static_dir: "/var/lib/pleroma/static"
|
||||
config :pleroma, Pleroma.Uploaders.Local, uploads: "/var/lib/pleroma/uploads"
|
||||
config :pleroma, configurable_from_database: false
|
||||
'';
|
||||
|
||||
/* For this NixOS test, we *had* to store this secret to the store.
|
||||
Keep in mind the store is world-readable, it's the worst place
|
||||
possible to store *any* secret. **DO NOT DO THIS IN A REAL WORLD
|
||||
DEPLOYMENT**.
|
||||
In a real-word deployment, you'd handle this either by:
|
||||
- manually upload your pleroma secrets to /var/lib/pleroma/secrets.exs
|
||||
- use a deployment tool such as morph or NixOps to deploy your secrets.
|
||||
*/
|
||||
pleroma-conf-secret = pkgs.writeText "secrets.exs" ''
|
||||
import Config
|
||||
|
||||
config :joken, default_signer: "PS69/wMW7X6FIQPABt9lwvlZvgrJIncfiAMrK9J5mjVus/7/NJJi1DsDA1OghBE5"
|
||||
|
||||
config :pleroma, Pleroma.Web.Endpoint,
|
||||
secret_key_base: "NvfmU7lYaQrmmxt4NACm0AaAfN9t6WxsrX0NCB4awkGHvr1S7jyshlEmrjaPFhhq",
|
||||
signing_salt: "3L41+BuJ"
|
||||
|
||||
config :web_push_encryption, :vapid_details,
|
||||
subject: "mailto:pleroma@nixos.test",
|
||||
public_key: "BKjfNX9-UqAcncaNqERQtF7n9pKrB0-MO-juv6U5E5XQr_Tg5D-f8AlRjduAguDpyAngeDzG8MdrTejMSL4VF30",
|
||||
private_key: "k7o9onKMQrgMjMb6l4fsxSaXO0BTNAer5MVSje3q60k"
|
||||
'';
|
||||
|
||||
/* For this NixOS test, we *had* to store this secret to the store.
|
||||
Keep in mind the store is world-readable, it's the worst place
|
||||
possible to store *any* secret. **DO NOT DO THIS IN A REAL WORLD
|
||||
DEPLOYMENT**.
|
||||
In a real-word deployment, you'd handle this either by:
|
||||
- manually upload your pleroma secrets to /var/lib/pleroma/secrets.exs
|
||||
- use a deployment tool such as morph or NixOps to deploy your secrets.
|
||||
*/
|
||||
provision-secrets = pkgs.writeScriptBin "provision-secrets" ''
|
||||
set -eux
|
||||
cp "${pleroma-conf-secret}" "/var/lib/pleroma/secrets.exs"
|
||||
chown pleroma:pleroma /var/lib/pleroma/secrets.exs
|
||||
'';
|
||||
|
||||
/* For this NixOS test, we *had* to store this secret to the store.
|
||||
Keep in mind the store is world-readable, it's the worst place
|
||||
possible to store *any* secret. **DO NOT DO THIS IN A REAL WORLD
|
||||
DEPLOYMENT**.
|
||||
*/
|
||||
provision-user = pkgs.writeScriptBin "provision-user" ''
|
||||
set -eux
|
||||
|
||||
# Waiting for pleroma to be up.
|
||||
timeout 5m bash -c 'while [[ "$(curl -s -o /dev/null -w '%{http_code}' https://pleroma.nixos.test/api/v1/instance)" != "200" ]]; do sleep 2; done'
|
||||
pleroma_ctl user new jamy jamy@nixos.test --password 'jamy-password' --moderator --admin -y
|
||||
'';
|
||||
|
||||
tls-cert = pkgs.runCommandNoCC "selfSignedCerts" { buildInputs = [ pkgs.openssl ]; } ''
|
||||
openssl req -x509 -newkey rsa:4096 -keyout key.pem -out cert.pem -nodes -subj '/CN=pleroma.nixos.test'
|
||||
mkdir -p $out
|
||||
cp key.pem cert.pem $out
|
||||
'';
|
||||
|
||||
/* Toot is preventing users from feeding login_cli a password non
|
||||
interactively. While it makes sense most of the times, it's
|
||||
preventing us to login in this non-interactive test. This patch
|
||||
introduce a TOOT_LOGIN_CLI_PASSWORD env variable allowing us to
|
||||
provide a password to toot login_cli
|
||||
|
||||
If https://github.com/ihabunek/toot/pull/180 gets merged at some
|
||||
point, feel free to remove this patch. */
|
||||
custom-toot = pkgs.toot.overrideAttrs(old:{
|
||||
patches = [ (pkgs.fetchpatch {
|
||||
url = "https://github.com/NinjaTrappeur/toot/commit/b4a4c30f41c0cb7e336714c2c4af9bc9bfa0c9f2.patch";
|
||||
sha256 = "sha256-0xxNwjR/fStLjjUUhwzCCfrghRVts+fc+fvVJqVcaFg=";
|
||||
}) ];
|
||||
});
|
||||
|
||||
hosts = nodes: ''
|
||||
${nodes.pleroma.config.networking.primaryIPAddress} pleroma.nixos.test
|
||||
${nodes.client.config.networking.primaryIPAddress} client.nixos.test
|
||||
'';
|
||||
in {
|
||||
name = "pleroma";
|
||||
nodes = {
|
||||
client = { nodes, pkgs, config, ... }: {
|
||||
security.pki.certificateFiles = [ "${tls-cert}/cert.pem" ];
|
||||
networking.extraHosts = hosts nodes;
|
||||
environment.systemPackages = with pkgs; [
|
||||
custom-toot
|
||||
send-toot
|
||||
];
|
||||
};
|
||||
pleroma = { nodes, pkgs, config, ... }: {
|
||||
security.pki.certificateFiles = [ "${tls-cert}/cert.pem" ];
|
||||
networking.extraHosts = hosts nodes;
|
||||
networking.firewall.enable = false;
|
||||
environment.systemPackages = with pkgs; [
|
||||
provision-db
|
||||
provision-secrets
|
||||
provision-user
|
||||
];
|
||||
services = {
|
||||
pleroma = {
|
||||
enable = true;
|
||||
configs = [
|
||||
pleroma-conf
|
||||
];
|
||||
};
|
||||
postgresql = {
|
||||
enable = true;
|
||||
package = pkgs.postgresql_12;
|
||||
};
|
||||
nginx = {
|
||||
enable = true;
|
||||
virtualHosts."pleroma.nixos.test" = {
|
||||
addSSL = true;
|
||||
sslCertificate = "${tls-cert}/cert.pem";
|
||||
sslCertificateKey = "${tls-cert}/key.pem";
|
||||
locations."/" = {
|
||||
proxyPass = "http://127.0.0.1:4000";
|
||||
extraConfig = ''
|
||||
add_header 'Access-Control-Allow-Origin' '*' always;
|
||||
add_header 'Access-Control-Allow-Methods' 'POST, PUT, DELETE, GET, PATCH, OPTIONS' always;
|
||||
add_header 'Access-Control-Allow-Headers' 'Authorization, Content-Type, Idempotency-Key' always;
|
||||
add_header 'Access-Control-Expose-Headers' 'Link, X-RateLimit-Reset, X-RateLimit-Limit, X-RateLimit-Remaining, X-Request-Id' always;
|
||||
if ($request_method = OPTIONS) {
|
||||
return 204;
|
||||
}
|
||||
add_header X-XSS-Protection "1; mode=block";
|
||||
add_header X-Permitted-Cross-Domain-Policies none;
|
||||
add_header X-Frame-Options DENY;
|
||||
add_header X-Content-Type-Options nosniff;
|
||||
add_header Referrer-Policy same-origin;
|
||||
add_header X-Download-Options noopen;
|
||||
proxy_http_version 1.1;
|
||||
proxy_set_header Upgrade $http_upgrade;
|
||||
proxy_set_header Connection "upgrade";
|
||||
proxy_set_header Host $host;
|
||||
client_max_body_size 16m;
|
||||
'';
|
||||
};
|
||||
};
|
||||
};
|
||||
};
|
||||
};
|
||||
};
|
||||
|
||||
testScript = { nodes, ... }: ''
|
||||
pleroma.wait_for_unit("postgresql.service")
|
||||
pleroma.succeed("provision-db")
|
||||
pleroma.succeed("provision-secrets")
|
||||
pleroma.systemctl("restart pleroma.service")
|
||||
pleroma.wait_for_unit("pleroma.service")
|
||||
pleroma.succeed("provision-user")
|
||||
client.succeed("send-toot")
|
||||
'';
|
||||
})
|
@ -19,13 +19,13 @@ assert withOpenCL -> ocl-icd != null;
|
||||
|
||||
mkDerivation rec {
|
||||
pname = "mandelbulber";
|
||||
version = "2.23";
|
||||
version = "2.24";
|
||||
|
||||
src = fetchFromGitHub {
|
||||
owner = "buddhi1980";
|
||||
repo = "mandelbulber2";
|
||||
rev = version;
|
||||
sha256 = "08izphj7jyk3wsq3qbzaf2fplys80vr39wliqc1i4c5cr90nrq1l";
|
||||
sha256 = "sha256-JgpYGzD2FsqcCWnOKBiVCxUKqLfT4S++uUBZekhGWmA=";
|
||||
};
|
||||
|
||||
nativeBuildInputs = [
|
||||
|
@ -2,7 +2,7 @@
|
||||
|
||||
let
|
||||
pname = "Sylk";
|
||||
version = "2.9.4";
|
||||
version = "3.0.0";
|
||||
in
|
||||
|
||||
appimageTools.wrapType2 rec {
|
||||
@ -10,7 +10,7 @@ appimageTools.wrapType2 rec {
|
||||
|
||||
src = fetchurl {
|
||||
url = "http://download.ag-projects.com/Sylk/Sylk-${version}-x86_64.AppImage";
|
||||
hash = "sha256-LnJ8Pd+AHIrHrYpIx+rxnFKZ1uh2viDHC5TaU1BL62s=";
|
||||
hash = "sha256-A+SFkGDg+I1lPJ56XPaRfBUktyjSttcsZSqgXvw9sDs=";
|
||||
};
|
||||
|
||||
profile = ''
|
||||
|
@ -1,9 +1,6 @@
|
||||
{ stdenv, fetchurl, openssl }:
|
||||
{ lib, stdenv, fetchurl, openssl }:
|
||||
|
||||
with stdenv;
|
||||
with lib;
|
||||
|
||||
mkDerivation rec {
|
||||
stdenv.mkDerivation rec {
|
||||
pname = "wraith";
|
||||
version = "1.4.7";
|
||||
src = fetchurl {
|
||||
@ -25,7 +22,7 @@ mkDerivation rec {
|
||||
ln -s wraith $out/bin/hub
|
||||
'';
|
||||
|
||||
meta = {
|
||||
meta = with lib; {
|
||||
description = "An IRC channel management bot written purely in C/C++";
|
||||
longDescription = ''
|
||||
Wraith is an IRC channel management bot written purely in C/C++. It has
|
||||
|
@ -45,7 +45,7 @@ let
|
||||
};
|
||||
releaseRev = v: "V${v}";
|
||||
fetched = import ../../../../build-support/coq/meta-fetch/default.nix
|
||||
{ inherit stdenv fetchzip; }
|
||||
{ inherit lib stdenv fetchzip; }
|
||||
{ inherit release releaseRev; location = { owner = "coq"; repo = "coq";}; }
|
||||
args.version;
|
||||
version = fetched.version;
|
||||
|
@ -53,7 +53,7 @@ stdenv.mkDerivation {
|
||||
meta = {
|
||||
description = "Tools for software verification and analysis";
|
||||
homepage = "https://saw.galois.com";
|
||||
license = lib.licenses.unfreeRedistributable;
|
||||
license = lib.licenses.bsd3;
|
||||
platforms = lib.platforms.linux;
|
||||
maintainers = [ lib.maintainers.thoughtpolice ];
|
||||
};
|
||||
|
@ -1,4 +1,4 @@
|
||||
{stdenv, fetchurl, makeWrapper, flex, bison,
|
||||
{lib, stdenv, fetchurl, makeWrapper, flex, bison,
|
||||
asciidoc, docbook_xml_dtd_45, docbook_xsl,
|
||||
libxml2, libxslt,
|
||||
python3, rcs, cvs, git,
|
||||
|
@ -1,4 +1,4 @@
|
||||
{ stdenv, fetchurl, makeWrapper, python27Packages, git
|
||||
{ lib, stdenv, fetchurl, makeWrapper, python27Packages, git
|
||||
, docbook_xml_dtd_412, docbook_xsl, asciidoc, xmlto, pypy
|
||||
, breezy ? null, cvs ? null, darcs ? null, fossil ? null
|
||||
, mercurial ? null, monotone ? null, rcs ? null
|
||||
|
@ -35,7 +35,7 @@ let
|
||||
"extraInstallFlags" "setCOQBIN" "mlPlugin"
|
||||
"dropAttrs" "dropDerivationAttrs" "keepAttrs" ] ++ dropAttrs) keepAttrs;
|
||||
fetch = import ../coq/meta-fetch/default.nix
|
||||
{ inherit stdenv fetchzip; } ({
|
||||
{ inherit lib stdenv fetchzip; } ({
|
||||
inherit release releaseRev;
|
||||
location = { inherit domain owner repo; };
|
||||
} // optionalAttrs (args?fetcher) {inherit fetcher;});
|
||||
|
@ -1,5 +1,6 @@
|
||||
{ stdenv, fetchzip }@args:
|
||||
let lib = import ../extra-lib.nix {inherit (args.stdenv) lib;}; in
|
||||
{ lib, stdenv, fetchzip }@args:
|
||||
let lib' = lib; in
|
||||
let lib = import ../extra-lib.nix {lib = lib';}; in
|
||||
with builtins; with lib;
|
||||
let
|
||||
default-fetcher = {domain ? "github.com", owner ? "", repo, rev, name ? "source", sha256 ? null, ...}@args:
|
||||
|
@ -1,14 +1,14 @@
|
||||
{ lib, fetchzip }:
|
||||
|
||||
let
|
||||
version = "2.221";
|
||||
version = "2.225";
|
||||
in
|
||||
fetchzip {
|
||||
name = "JetBrainsMono-${version}";
|
||||
|
||||
url = "https://github.com/JetBrains/JetBrainsMono/releases/download/v${version}/JetBrainsMono-${version}.zip";
|
||||
|
||||
sha256 = "1in3znnj0i0yfwj93ncxi3s1cp9lhgwnv2r14br47rr7vik4zjr6";
|
||||
sha256 = "1k8xmjaingz50626hd73hqbp196kg3zndiy0aqb88z5cw9nd0fva";
|
||||
|
||||
postFetch = ''
|
||||
mkdir -p $out/share/fonts
|
||||
|
@ -1,10 +1,11 @@
|
||||
{ stdenv, fetchurl, curl, tzdata, autoPatchelfHook, fixDarwinDylibNames, glibc
|
||||
{ lib, stdenv, fetchurl, curl, tzdata, autoPatchelfHook, fixDarwinDylibNames, glibc
|
||||
, version, hashes }:
|
||||
with stdenv;
|
||||
|
||||
let
|
||||
inherit (stdenv) hostPlatform;
|
||||
OS = if hostPlatform.isDarwin then "osx" else hostPlatform.parsed.kernel.name;
|
||||
MODEL = toString hostPlatform.parsed.cpu.bits;
|
||||
in mkDerivation {
|
||||
in stdenv.mkDerivation {
|
||||
pname = "dmd-bootstrap";
|
||||
inherit version;
|
||||
|
||||
|
@ -1,10 +1,11 @@
|
||||
{ stdenv, fetchurl, curl, tzdata, autoPatchelfHook, fixDarwinDylibNames, libxml2
|
||||
{ lib, stdenv, fetchurl, curl, tzdata, autoPatchelfHook, fixDarwinDylibNames, libxml2
|
||||
, version, hashes }:
|
||||
with stdenv;
|
||||
|
||||
let
|
||||
OS = if hostPlatform.isDarwin then "osx" else hostPlatform.parsed.kernel.name;
|
||||
inherit (stdenv) hostPlatform;
|
||||
OS = if stdenv.hostPlatform.isDarwin then "osx" else hostPlatform.parsed.kernel.name;
|
||||
ARCH = toString hostPlatform.parsed.cpu.name;
|
||||
in mkDerivation {
|
||||
in stdenv.mkDerivation {
|
||||
pname = "ldc-bootstrap";
|
||||
inherit version;
|
||||
|
||||
|
@ -1,4 +1,4 @@
|
||||
{ stdenv, fetchFromGitHub, cmake
|
||||
{ lib, stdenv, fetchFromGitHub, cmake
|
||||
, boost, python3, eigen
|
||||
, icestorm, trellis
|
||||
, llvmPackages
|
||||
@ -12,7 +12,7 @@
|
||||
let
|
||||
boostPython = boost.override { python = python3; enablePython = true; };
|
||||
in
|
||||
with stdenv; mkDerivation rec {
|
||||
stdenv.mkDerivation rec {
|
||||
pname = "nextpnr";
|
||||
version = "2021.01.02";
|
||||
|
||||
|
@ -6,7 +6,7 @@ rustPlatform.buildRustPackage rec {
|
||||
|
||||
# commit chosen by using the latest build from http://bin.zetz.it/
|
||||
src = fetchFromGitHub {
|
||||
owner = "aep";
|
||||
owner = "zetzit";
|
||||
repo = "zz";
|
||||
rev = "0b5c52674e9adf795fbfb051d4dceef3126e669f";
|
||||
sha256 = "0bb77ll1g5i6a04ybpgx6lqsb74xs4v4nyqm9j4j6x24407h8l89";
|
||||
@ -16,13 +16,23 @@ rustPlatform.buildRustPackage rec {
|
||||
|
||||
cargoSha256 = "1lf4k3n89w2797c1yrj1dp97y8a8d5hnixr1nwa2qcq1sxmm5rcg";
|
||||
|
||||
postPatch = ''
|
||||
# remove search path entry which would reference /build
|
||||
sed -i '/env!("CARGO_MANIFEST_DIR")/d' src/lib.rs
|
||||
'';
|
||||
|
||||
postInstall = ''
|
||||
wrapProgram $out/bin/zz --prefix PATH ":" "${lib.getBin z3}/bin"
|
||||
mkdir -p "$out/share/zz"
|
||||
cp -r modules "$out/share/zz/"
|
||||
|
||||
wrapProgram $out/bin/zz \
|
||||
--prefix PATH ":" "${lib.getBin z3}/bin" \
|
||||
--suffix ZZ_MODULE_PATHS ":" "$out/share/zz/modules"
|
||||
'';
|
||||
|
||||
meta = with lib; {
|
||||
description = "🍺🐙 ZetZ a zymbolic verifier and tranzpiler to bare metal C";
|
||||
homepage = "https://github.com/aep/zz";
|
||||
homepage = "https://github.com/zetzit/zz";
|
||||
license = licenses.mit;
|
||||
maintainers = [ maintainers.marsam ];
|
||||
};
|
||||
|
@ -327,6 +327,37 @@ in package-set { inherit pkgs lib callPackage; } self // {
|
||||
# packages. You should set this to true if you have benchmarks defined
|
||||
# in your local packages that you want to be able to run with cabal benchmark
|
||||
doBenchmark ? false
|
||||
# An optional function that can modify the generic builder arguments
|
||||
# for the fake package that shellFor uses to construct its environment.
|
||||
#
|
||||
# Example:
|
||||
# let
|
||||
# # elided...
|
||||
# haskellPkgs = pkgs.haskell.packages.ghc884.override (hpArgs: {
|
||||
# overrides = pkgs.lib.composeExtensions (hpArgs.overrides or (_: _: { })) (
|
||||
# _hfinal: hprev: {
|
||||
# mkDerivation = args: hprev.mkDerivation ({
|
||||
# doCheck = false;
|
||||
# doBenchmark = false;
|
||||
# doHoogle = true;
|
||||
# doHaddock = true;
|
||||
# enableLibraryProfiling = false;
|
||||
# enableExecutableProfiling = false;
|
||||
# } // args);
|
||||
# }
|
||||
# );
|
||||
# });
|
||||
# in
|
||||
# hpkgs.shellFor {
|
||||
# packages = p: [ p.foo ];
|
||||
# genericBuilderArgsModifier = args: args // { doCheck = true; doBenchmark = true };
|
||||
# }
|
||||
#
|
||||
# This will disable tests and benchmarks for everything in "haskellPkgs"
|
||||
# (which will invalidate the binary cache), and then re-enable them
|
||||
# for the "shellFor" environment (ensuring that any test/benchmark
|
||||
# dependencies for "foo" will be available within the nix-shell).
|
||||
, genericBuilderArgsModifier ? (args: args)
|
||||
, ...
|
||||
} @ args:
|
||||
let
|
||||
@ -443,7 +474,7 @@ in package-set { inherit pkgs lib callPackage; } self // {
|
||||
# This is a derivation created with `haskellPackages.mkDerivation`.
|
||||
#
|
||||
# pkgWithCombinedDeps :: HaskellDerivation
|
||||
pkgWithCombinedDeps = self.mkDerivation genericBuilderArgs;
|
||||
pkgWithCombinedDeps = self.mkDerivation (genericBuilderArgsModifier genericBuilderArgs);
|
||||
|
||||
# The derivation returned from `envFunc` for `pkgWithCombinedDeps`.
|
||||
#
|
||||
@ -457,7 +488,7 @@ in package-set { inherit pkgs lib callPackage; } self // {
|
||||
# pkgWithCombinedDepsDevDrv :: Derivation
|
||||
pkgWithCombinedDepsDevDrv = pkgWithCombinedDeps.envFunc { inherit withHoogle; };
|
||||
|
||||
mkDerivationArgs = builtins.removeAttrs args [ "packages" "withHoogle" "doBenchmark" ];
|
||||
mkDerivationArgs = builtins.removeAttrs args [ "genericBuilderArgsModifier" "packages" "withHoogle" "doBenchmark" ];
|
||||
|
||||
in pkgWithCombinedDepsDevDrv.overrideAttrs (old: mkDerivationArgs // {
|
||||
nativeBuildInputs = old.nativeBuildInputs ++ mkDerivationArgs.nativeBuildInputs or [];
|
||||
|
@ -1,6 +1,6 @@
|
||||
{stdenv, fetchurl, libusb-compat-0_1}:
|
||||
{lib, stdenv, fetchurl, libusb-compat-0_1}:
|
||||
|
||||
with stdenv; mkDerivation rec {
|
||||
stdenv.mkDerivation rec {
|
||||
name = "libftdi-0.20";
|
||||
|
||||
src = fetchurl {
|
||||
@ -14,7 +14,7 @@ with stdenv; mkDerivation rec {
|
||||
|
||||
# Hack to avoid TMPDIR in RPATHs.
|
||||
preFixup = ''rm -rf "$(pwd)" '';
|
||||
configureFlags = lib.optional (!isDarwin) "--with-async-mode";
|
||||
configureFlags = lib.optional (!stdenv.isDarwin) "--with-async-mode";
|
||||
|
||||
# allow async mode. from ubuntu. see:
|
||||
# https://bazaar.launchpad.net/~ubuntu-branches/ubuntu/trusty/libftdi/trusty/view/head:/debian/patches/04_async_mode.diff
|
||||
|
@ -8,12 +8,12 @@
|
||||
|
||||
stdenv.mkDerivation rec {
|
||||
pname = "mapnik";
|
||||
version = "3.0.23";
|
||||
version = "3.1.0";
|
||||
|
||||
src = fetchzip {
|
||||
# this one contains all git submodules and is cheaper than fetchgit
|
||||
url = "https://github.com/mapnik/mapnik/releases/download/v${version}/mapnik-v${version}.tar.bz2";
|
||||
sha256 = "1754m8y7fyk0dyf7cglhavsk66g5kdqhnmgicib1jkcgjbl69f15";
|
||||
sha256 = "sha256-qqPqN4vs3ZsqKgnx21yQhX8OzHca/0O+3mvQ/vnC5EY=";
|
||||
};
|
||||
|
||||
# a distinct dev output makes python-mapnik fail
|
||||
|
@ -14,7 +14,8 @@ let
|
||||
};
|
||||
|
||||
nativeBuildInputs = [ cmake ];
|
||||
buildInputs = [ fmt ];
|
||||
# spdlog <1.3 uses a bundled version of fmt
|
||||
propagatedBuildInputs = lib.optional (lib.versionAtLeast version "1.3") fmt;
|
||||
|
||||
cmakeFlags = [
|
||||
"-DSPDLOG_BUILD_SHARED=${if stdenv.hostPlatform.isStatic then "OFF" else "ON"}"
|
||||
@ -25,7 +26,9 @@ let
|
||||
"-DSPDLOG_FMT_EXTERNAL=ON"
|
||||
];
|
||||
|
||||
outputs = [ "out" "doc" ];
|
||||
outputs = [ "out" "doc" ]
|
||||
# spdlog <1.4 is header only, no need to split libraries and headers
|
||||
++ lib.optional (lib.versionAtLeast version "1.4") "dev";
|
||||
|
||||
postInstall = ''
|
||||
mkdir -p $out/share/doc/spdlog
|
||||
|
@ -96,6 +96,7 @@
|
||||
, "graphql-cli"
|
||||
, "grunt-cli"
|
||||
, "makam"
|
||||
, "meshcommander"
|
||||
, "gqlint"
|
||||
, "gtop"
|
||||
, "gulp"
|
||||
|
8075
pkgs/development/node-packages/node-packages.nix
generated
8075
pkgs/development/node-packages/node-packages.nix
generated
File diff suppressed because it is too large
Load Diff
@ -4,7 +4,7 @@
|
||||
}:
|
||||
with lib;
|
||||
let fetched = import ../../../build-support/coq/meta-fetch/default.nix
|
||||
{inherit stdenv fetchzip; } ({
|
||||
{inherit lib stdenv fetchzip; } ({
|
||||
release."1.12.0".sha256 = "1agisdnaq9wrw3r73xz14yrq3wx742i6j8i5icjagqk0ypmly2is";
|
||||
release."1.11.4".sha256 = "1m0jk9swcs3jcrw5yyw5343v8mgax238cjb03s8gc4wipw1fn9f5";
|
||||
releaseRev = v: "v${v}";
|
||||
|
@ -2,13 +2,13 @@
|
||||
|
||||
buildGoPackage rec {
|
||||
pname = "tfsec";
|
||||
version = "0.36.10";
|
||||
version = "0.37.1";
|
||||
|
||||
src = fetchFromGitHub {
|
||||
owner = "tfsec";
|
||||
repo = pname;
|
||||
rev = "v${version}";
|
||||
sha256 = "11kv13d4cw515r79azfha1ksmvsha1rvg0jak9nvz9ggivyn0s7a";
|
||||
sha256 = "sha256-ZYJqnyIFwyPODFqXAZp1ep0Ofl/JH2F07gqPx4WZ7mo=";
|
||||
};
|
||||
|
||||
goPackagePath = "github.com/tfsec/tfsec";
|
||||
|
@ -2,11 +2,11 @@
|
||||
|
||||
stdenv.mkDerivation rec {
|
||||
pname = "clojure-lsp";
|
||||
version = "2021.01.20-01.39.32";
|
||||
version = "2021.01.26-22.35.27";
|
||||
|
||||
src = fetchurl {
|
||||
url = "https://github.com/clojure-lsp/clojure-lsp/releases/download/${version}/${pname}.jar";
|
||||
sha256 = "sha256-DqvAIM5YHtcUNZHoH+fcZym6EaPX5a/vgphTFfTO6bU=";
|
||||
sha256 = "sha256-kYxOrallox/LnAdZ4wTWZDlzt5GR0/s6nlG6CO0/pRw=";
|
||||
};
|
||||
|
||||
dontUnpack = true;
|
||||
|
@ -1,10 +1,8 @@
|
||||
{ stdenv, mkDerivation, fetchFromGitHub, makeDesktopItem, makeWrapper
|
||||
{ lib, stdenv, mkDerivation, fetchFromGitHub, makeDesktopItem, makeWrapper
|
||||
, python, pkg-config, SDL2, SDL2_ttf, alsaLib, which, qtbase, libXinerama
|
||||
, libpcap, CoreAudioKit, ForceFeedback
|
||||
, installShellFiles }:
|
||||
|
||||
with stdenv;
|
||||
|
||||
let
|
||||
majorVersion = "0";
|
||||
minorVersion = "226";
|
||||
|
@ -189,6 +189,23 @@ let
|
||||
};
|
||||
};
|
||||
|
||||
elmtooling.elm-ls-vscode = buildVscodeMarketplaceExtension {
|
||||
mktplcRef = {
|
||||
name = "elm-ls-vscode";
|
||||
publisher = "Elmtooling";
|
||||
version = "2.0.1";
|
||||
sha256 = "06x5ld2r1hzns2s052mvhmfiaawjzcn0jf5lkfprhmrkxnmfdd43";
|
||||
};
|
||||
meta = with lib; {
|
||||
changelog = "https://marketplace.visualstudio.com/items/Elmtooling.elm-ls-vscode/changelog";
|
||||
description = "Elm language server";
|
||||
downloadPage = "https://marketplace.visualstudio.com/items?itemName=Elmtooling.elm-ls-vscode";
|
||||
homepage = "https://github.com/elm-tooling/elm-language-client-vscode";
|
||||
license = licenses.mit;
|
||||
maintainers = with maintainers; [ mcwitt ];
|
||||
};
|
||||
};
|
||||
|
||||
esbenp.prettier-vscode = buildVscodeMarketplaceExtension {
|
||||
meta = with lib; {
|
||||
changelog = "https://marketplace.visualstudio.com/items/esbenp.prettier-vscode/changelog";
|
||||
|
@ -10,15 +10,14 @@
|
||||
|
||||
buildGoModule rec {
|
||||
pname = "oci-seccomp-bpf-hook";
|
||||
version = "1.2.0";
|
||||
version = "1.2.1";
|
||||
src = fetchFromGitHub {
|
||||
owner = "containers";
|
||||
repo = "oci-seccomp-bpf-hook";
|
||||
rev = "v${version}";
|
||||
sha256 = "143x4daixzhhhpli1l14r7dr7dn3q42w8dddr16jzhhwighsirqw";
|
||||
sha256 = "0zbrpv6j4gd4l36zl2dljazdm85qlqwchf0xvmnaywcj8c8b49xw";
|
||||
};
|
||||
vendorSha256 = null;
|
||||
doCheck = false;
|
||||
|
||||
outputs = [ "out" "man" ];
|
||||
nativeBuildInputs = [
|
||||
@ -31,6 +30,10 @@ buildGoModule rec {
|
||||
libseccomp
|
||||
];
|
||||
|
||||
checkPhase = ''
|
||||
go test -v ./...
|
||||
'';
|
||||
|
||||
buildPhase = ''
|
||||
make
|
||||
'';
|
||||
|
@ -26,11 +26,11 @@ in stdenv.mkDerivation rec {
|
||||
|
||||
pname = "postfix";
|
||||
|
||||
version = "3.5.8";
|
||||
version = "3.5.9";
|
||||
|
||||
src = fetchurl {
|
||||
url = "ftp://ftp.cs.uu.nl/mirror/postfix/postfix-release/official/${pname}-${version}.tar.gz";
|
||||
sha256 = "0vs50z5p5xcrdbbkb0dnbx1sk5fx8d2z97sw2p2iip1yrwl2cn12";
|
||||
sha256 = "0avn00drmk9c9mjynfvcmir72ss9s3mckdhjm3mmnhas2sixbkji";
|
||||
};
|
||||
|
||||
nativeBuildInputs = [ makeWrapper m4 ];
|
||||
|
@ -3,12 +3,12 @@
|
||||
}:
|
||||
|
||||
stdenv.mkDerivation rec {
|
||||
version = "6.0.6";
|
||||
version = "6.0.10";
|
||||
pname = "redis";
|
||||
|
||||
src = fetchurl {
|
||||
url = "http://download.redis.io/releases/${pname}-${version}.tar.gz";
|
||||
sha256 = "151x6qicmrmlxkmiwi2vdq8p50d52b9gglp8csag6pmgcfqlkb8j";
|
||||
sha256 = "1gc529nfh8frk4pynyjlnmzvwa0j9r5cmqwyd7537sywz6abifvr";
|
||||
};
|
||||
|
||||
# Cross-compiling fixes
|
||||
|
70
pkgs/servers/pleroma-otp/default.nix
Normal file
70
pkgs/servers/pleroma-otp/default.nix
Normal file
@ -0,0 +1,70 @@
|
||||
{ stdenv
|
||||
, autoPatchelfHook
|
||||
, fetchurl
|
||||
, file
|
||||
, makeWrapper
|
||||
, ncurses
|
||||
, nixosTests
|
||||
, openssl
|
||||
, unzip
|
||||
, zlib
|
||||
}:
|
||||
stdenv.mkDerivation {
|
||||
pname = "pleroma-otp";
|
||||
version = "2.2.2";
|
||||
|
||||
# To find the latest binary release stable link, have a look at
|
||||
# the CI pipeline for the latest commit of the stable branch
|
||||
# https://git.pleroma.social/pleroma/pleroma/-/tree/stable
|
||||
src = {
|
||||
aarch64-linux = fetchurl {
|
||||
url = "https://git.pleroma.social/pleroma/pleroma/-/jobs/175288/artifacts/download";
|
||||
sha256 = "107kp5zqwq1lixk1cwkx4v7zpm0h248xzlm152aj36ghb43j2snw";
|
||||
};
|
||||
x86_64-linux = fetchurl {
|
||||
url = "https://git.pleroma.social/pleroma/pleroma/-/jobs/175284/artifacts/download";
|
||||
sha256 = "1c6l04gga9iigm249ywwcrjg6wzy8iiid652mws3j9dnl71w2sim";
|
||||
};
|
||||
}."${stdenv.hostPlatform.system}";
|
||||
|
||||
nativeBuildInputs = [ unzip ];
|
||||
|
||||
buildInputs = [
|
||||
autoPatchelfHook
|
||||
file
|
||||
makeWrapper
|
||||
ncurses
|
||||
openssl
|
||||
zlib
|
||||
];
|
||||
|
||||
# mkDerivation fails to detect the zip nature of $src due to the
|
||||
# missing .zip extension.
|
||||
# Let's unpack the archive explicitely.
|
||||
unpackCmd = "unzip $curSrc";
|
||||
|
||||
installPhase = ''
|
||||
mkdir $out
|
||||
cp -r * $out'';
|
||||
|
||||
# Pleroma is using the project's root path (here the store path)
|
||||
# as its TMPDIR.
|
||||
# Patching it to move the tmp dir to the actual tmpdir
|
||||
postFixup = ''
|
||||
wrapProgram $out/bin/pleroma \
|
||||
--set-default RELEASE_TMP "/tmp"
|
||||
wrapProgram $out/bin/pleroma_ctl \
|
||||
--set-default RELEASE_TMP "/tmp"'';
|
||||
|
||||
passthru.tests = {
|
||||
pleroma = nixosTests.pleroma;
|
||||
};
|
||||
|
||||
meta = {
|
||||
description = "ActivityPub microblogging server";
|
||||
homepage = https://git.pleroma.social/pleroma/pleroma;
|
||||
license = stdenv.lib.licenses.agpl3;
|
||||
maintainers = with stdenv.lib.maintainers; [ ninjatrappeur ];
|
||||
platforms = [ "x86_64-linux" "aarch64-linux" ];
|
||||
};
|
||||
}
|
@ -24,12 +24,12 @@ let
|
||||
ctlpath = lib.makeBinPath [ bash gnused gnugrep coreutils util-linux procps ];
|
||||
|
||||
in stdenv.mkDerivation rec {
|
||||
version = "20.03";
|
||||
version = "20.12";
|
||||
pname = "ejabberd";
|
||||
|
||||
src = fetchurl {
|
||||
url = "https://www.process-one.net/downloads/downloads-action.php?file=/${version}/${pname}-${version}.tgz";
|
||||
sha256 = "0i013l9cygmgainfid298n6llhs3mblfklry3jw2a6irvhffym0s";
|
||||
sha256 = "sha256-nZxdYXRyv4UejPLHNT/p6CrvW22Koo7rZSi96KRjqFQ=";
|
||||
};
|
||||
|
||||
nativeBuildInputs = [ fakegit ];
|
||||
@ -76,7 +76,7 @@ in stdenv.mkDerivation rec {
|
||||
|
||||
outputHashMode = "recursive";
|
||||
outputHashAlgo = "sha256";
|
||||
outputHash = "0xwgi9hy6y0m8mwznl6px98kdmkcxg98k62zgqbaqd4paks5zwqa";
|
||||
outputHash = "sha256-0/hBgA+9rsDOBcvbROSpc5Xnw4JkYpuLCl2V+lJnieY=";
|
||||
};
|
||||
|
||||
configureFlags =
|
||||
@ -115,7 +115,7 @@ in stdenv.mkDerivation rec {
|
||||
license = licenses.gpl2;
|
||||
homepage = "https://www.ejabberd.im";
|
||||
platforms = platforms.linux;
|
||||
maintainers = with maintainers; [ sander abbradar ajs124 ];
|
||||
maintainers = with maintainers; [ sander abbradar ];
|
||||
broken = withElixir;
|
||||
};
|
||||
}
|
||||
|
@ -2,11 +2,11 @@
|
||||
|
||||
stdenv.mkDerivation rec {
|
||||
pname = "abcMIDI";
|
||||
version = "2021.01.21";
|
||||
version = "2021.01.25";
|
||||
|
||||
src = fetchzip {
|
||||
url = "https://ifdo.ca/~seymour/runabc/${pname}-${version}.zip";
|
||||
sha256 = "184d59pc60dax60j3nzcsr5kflaygbjpbrwg6r4bky0q0sg17z5i";
|
||||
sha256 = "1c2jx03ssm9yyv6rgr5wfv88ivfgdgq3889yaghjyvllm3nv9380";
|
||||
};
|
||||
|
||||
# There is also a file called "makefile" which seems to be preferred by the standard build phase
|
||||
|
@ -1,4 +1,4 @@
|
||||
{ stdenv, runCommand, fetchurl
|
||||
{ lib, stdenv, runCommand, fetchurl
|
||||
, fetchpatch
|
||||
, ensureNewerSourcesHook
|
||||
, cmake, pkg-config
|
||||
@ -36,7 +36,6 @@
|
||||
# We must have one crypto library
|
||||
assert cryptopp != null || (nss != null && nspr != null);
|
||||
|
||||
with stdenv; with lib;
|
||||
let
|
||||
shouldUsePkg = pkg: if pkg != null && pkg.meta.available then pkg else null;
|
||||
|
||||
@ -76,7 +75,7 @@ let
|
||||
none = [ ];
|
||||
};
|
||||
|
||||
getMeta = description: {
|
||||
getMeta = description: with lib; {
|
||||
homepage = "https://ceph.com/";
|
||||
inherit description;
|
||||
license = with licenses; [ lgpl21 gpl2 bsd3 mit publicDomain ];
|
||||
@ -148,11 +147,11 @@ in rec {
|
||||
boost ceph-python-env libxml2 optYasm optLibatomic_ops optLibs3
|
||||
malloc zlib openldap lttng-ust babeltrace gperf gtest cunit
|
||||
snappy rocksdb lz4 oathToolkit leveldb libnl libcap_ng rdkafka
|
||||
] ++ optionals stdenv.isLinux [
|
||||
] ++ lib.optionals stdenv.isLinux [
|
||||
linuxHeaders util-linux libuuid udev keyutils optLibaio optLibxfs optZfs
|
||||
# ceph 14
|
||||
rdma-core rabbitmq-c
|
||||
] ++ optionals hasRadosgw [
|
||||
] ++ lib.optionals hasRadosgw [
|
||||
optFcgi optExpat optCurl optFuse optLibedit
|
||||
];
|
||||
|
||||
|
@ -1,9 +1,7 @@
|
||||
{ stdenv, bzip2, zlib, autoconf, automake, cmake, gnumake, help2man , texinfo, libtool , cppzmq , libarchive, avro-cpp, boost, jansson, zeromq, openssl, pam, libiodbc, kerberos, gcc, libcxx, which, catch2 }:
|
||||
{ lib, stdenv, bzip2, zlib, autoconf, automake, cmake, gnumake, help2man , texinfo, libtool , cppzmq , libarchive, avro-cpp, boost, jansson, zeromq, openssl, pam, libiodbc, kerberos, gcc, libcxx, which, catch2 }:
|
||||
|
||||
# Common attributes of irods packages
|
||||
|
||||
with stdenv;
|
||||
|
||||
{
|
||||
nativeBuildInputs = [ autoconf automake cmake gnumake help2man texinfo which gcc ];
|
||||
buildInputs = [ bzip2 zlib libtool cppzmq libarchive avro-cpp jansson zeromq openssl pam libiodbc kerberos boost libcxx catch2 ];
|
||||
@ -35,7 +33,7 @@ with stdenv;
|
||||
"
|
||||
'';
|
||||
|
||||
meta = {
|
||||
meta = with lib; {
|
||||
description = "Integrated Rule-Oriented Data System (iRODS)";
|
||||
longDescription = ''
|
||||
The Integrated Rule-Oriented Data System (iRODS) is open source data management
|
||||
|
@ -1,13 +1,11 @@
|
||||
{ stdenv, fetchFromGitHub, bzip2, zlib, autoconf, automake, cmake, gnumake, help2man , texinfo, libtool , cppzmq , libarchive, avro-cpp_llvm, boost, jansson, zeromq, openssl , pam, libiodbc, kerberos, gcc, libcxx, which, catch2 }:
|
||||
|
||||
with stdenv;
|
||||
{ lib, stdenv, fetchFromGitHub, bzip2, zlib, autoconf, automake, cmake, gnumake, help2man , texinfo, libtool , cppzmq , libarchive, avro-cpp_llvm, boost, jansson, zeromq, openssl , pam, libiodbc, kerberos, gcc, libcxx, which, catch2 }:
|
||||
|
||||
let
|
||||
avro-cpp=avro-cpp_llvm;
|
||||
in
|
||||
let
|
||||
common = import ./common.nix {
|
||||
inherit stdenv bzip2 zlib autoconf automake cmake gnumake
|
||||
inherit lib stdenv bzip2 zlib autoconf automake cmake gnumake
|
||||
help2man texinfo libtool cppzmq libarchive jansson
|
||||
zeromq openssl pam libiodbc kerberos gcc libcxx
|
||||
boost avro-cpp which catch2;
|
||||
@ -83,7 +81,7 @@ in rec {
|
||||
'';
|
||||
|
||||
cmakeFlags = common.cmakeFlags ++ [
|
||||
"-DCMAKE_INSTALL_PREFIX=${out}"
|
||||
"-DCMAKE_INSTALL_PREFIX=${stdenv.out}"
|
||||
"-DIRODS_DIR=${irods}/lib/irods/cmake"
|
||||
"-DCMAKE_EXE_LINKER_FLAGS=-Wl,-rpath,${irods}/lib"
|
||||
"-DCMAKE_MODULE_LINKER_FLAGS=-Wl,-rpath,${irods}/lib"
|
||||
|
@ -1,28 +0,0 @@
|
||||
{lib, stdenv, fetchurl, apacheAnt, jdk, axis2, dbus_java }:
|
||||
|
||||
stdenv.mkDerivation {
|
||||
name = "DisnixWebService-0.10";
|
||||
src = fetchurl {
|
||||
url = "https://github.com/svanderburg/DisnixWebService/releases/download/DisnixWebService-0.10/DisnixWebService-0.10.tar.gz";
|
||||
sha256 = "0m451msd127ay09yb8rbflg68szm8s4hh65j99f7s3mz375vc114";
|
||||
};
|
||||
buildInputs = [ apacheAnt jdk ];
|
||||
PREFIX = "\${env.out}";
|
||||
AXIS2_LIB = "${axis2}/lib";
|
||||
AXIS2_WEBAPP = "${axis2}/webapps/axis2";
|
||||
DBUS_JAVA_LIB = "${dbus_java}/share/java";
|
||||
prePatch = ''
|
||||
sed -i -e "s|#JAVA_HOME=|JAVA_HOME=${jdk}|" \
|
||||
-e "s|#AXIS2_LIB=|AXIS2_LIB=${axis2}/lib|" \
|
||||
scripts/disnix-soap-client
|
||||
'';
|
||||
buildPhase = "ant";
|
||||
installPhase = "ant install";
|
||||
|
||||
meta = {
|
||||
description = "A SOAP interface and client for Disnix";
|
||||
license = lib.licenses.mit;
|
||||
maintainers = [ lib.maintainers.sander ];
|
||||
platforms = lib.platforms.linux;
|
||||
};
|
||||
}
|
@ -1,20 +0,0 @@
|
||||
{ lib, stdenv, fetchurl, pkg-config, glib, libxml2, libxslt, getopt, gettext, nixUnstable, dysnomia, libintl, libiconv, help2man, doclifter, docbook5, dblatex, doxygen, libnixxml, autoreconfHook }:
|
||||
|
||||
stdenv.mkDerivation {
|
||||
name = "disnix-0.10";
|
||||
|
||||
src = fetchurl {
|
||||
url = "https://github.com/svanderburg/disnix/releases/download/disnix-0.10/disnix-0.10.tar.gz";
|
||||
sha256 = "0mciqbc2h60nc0i6pd36w0m2yr96v97ybrzrqzh5f67ac1f0gqwg";
|
||||
};
|
||||
|
||||
nativeBuildInputs = [ pkg-config ];
|
||||
buildInputs = [ glib libxml2 libxslt getopt nixUnstable libintl libiconv dysnomia ];
|
||||
|
||||
meta = {
|
||||
description = "A Nix-based distributed service deployment tool";
|
||||
license = lib.licenses.lgpl21Plus;
|
||||
maintainers = with lib.maintainers; [ sander tomberek ];
|
||||
platforms = lib.platforms.unix;
|
||||
};
|
||||
}
|
@ -1,20 +0,0 @@
|
||||
{ lib, stdenv, fetchurl, dysnomia, disnix, socat, pkg-config, getopt }:
|
||||
|
||||
stdenv.mkDerivation {
|
||||
name = "disnixos-0.9";
|
||||
|
||||
src = fetchurl {
|
||||
url = "https://github.com/svanderburg/disnixos/releases/download/disnixos-0.9/disnixos-0.9.tar.gz";
|
||||
sha256 = "0vllm5a8d9dvz5cjiq1mmkc4r4vnljabq42ng0ml85sjn0w7xvm7";
|
||||
};
|
||||
|
||||
nativeBuildInputs = [ pkg-config ];
|
||||
buildInputs = [ socat dysnomia disnix getopt ];
|
||||
|
||||
meta = {
|
||||
description = "Provides complementary NixOS infrastructure deployment to Disnix";
|
||||
license = lib.licenses.lgpl21Plus;
|
||||
maintainers = [ lib.maintainers.sander ];
|
||||
platforms = lib.platforms.linux;
|
||||
};
|
||||
}
|
@ -1,27 +0,0 @@
|
||||
{ lib, stdenv, fetchFromGitHub, autoconf, automake, libtool , pkg-config, glib, libxml2, libxslt, getopt, libiconv, gettext, nix, disnix, libnixxml }:
|
||||
|
||||
stdenv.mkDerivation rec {
|
||||
version="2020-07-04";
|
||||
name = "dydisnix-${version}";
|
||||
|
||||
src = fetchFromGitHub {
|
||||
owner = "svanderburg";
|
||||
repo = "dydisnix";
|
||||
rev = "e99091f1c2329d562097e35faedee80622d387f0";
|
||||
sha256 = "sha256-XKab2hNGtWDkIEMxE1vMvqQBTP9BvHTabBVfzpH57h0=";
|
||||
};
|
||||
|
||||
nativeBuildInputs = [ pkg-config autoconf automake libtool ];
|
||||
buildInputs = [ glib libxml2 libxslt getopt nix disnix libiconv gettext libnixxml ];
|
||||
preConfigure = ''
|
||||
./bootstrap
|
||||
'';
|
||||
|
||||
meta = {
|
||||
description = "A toolset enabling self-adaptive redeployment on top of Disnix";
|
||||
longDescription = "Dynamic Disnix is a (very experimental!) prototype extension framework for Disnix supporting dynamic (re)deployment of service-oriented systems.";
|
||||
license = lib.licenses.lgpl21Plus;
|
||||
maintainers = [ lib.maintainers.tomberek ];
|
||||
platforms = lib.platforms.unix;
|
||||
};
|
||||
}
|
@ -1,71 +0,0 @@
|
||||
{ lib, stdenv, fetchurl, netcat
|
||||
, systemd ? null, ejabberd ? null, mysql ? null, postgresql ? null, subversion ? null, mongodb ? null, mongodb-tools ? null, influxdb ? null, supervisor ? null, docker ? null
|
||||
, enableApacheWebApplication ? false
|
||||
, enableAxis2WebService ? false
|
||||
, enableEjabberdDump ? false
|
||||
, enableMySQLDatabase ? false
|
||||
, enablePostgreSQLDatabase ? false
|
||||
, enableSubversionRepository ? false
|
||||
, enableTomcatWebApplication ? false
|
||||
, enableMongoDatabase ? false
|
||||
, enableInfluxDatabase ? false
|
||||
, enableSupervisordProgram ? false
|
||||
, enableDockerContainer ? true
|
||||
, enableLegacy ? false
|
||||
, catalinaBaseDir ? "/var/tomcat"
|
||||
, jobTemplate ? "systemd"
|
||||
, getopt
|
||||
}:
|
||||
|
||||
assert enableMySQLDatabase -> mysql != null;
|
||||
assert enablePostgreSQLDatabase -> postgresql != null;
|
||||
assert enableSubversionRepository -> subversion != null;
|
||||
assert enableEjabberdDump -> ejabberd != null;
|
||||
assert enableMongoDatabase -> (mongodb != null && mongodb-tools != null);
|
||||
assert enableInfluxDatabase -> influxdb != null;
|
||||
assert enableSupervisordProgram -> supervisor != null;
|
||||
assert enableDockerContainer -> docker != null;
|
||||
|
||||
stdenv.mkDerivation {
|
||||
name = "dysnomia-0.10";
|
||||
src = fetchurl {
|
||||
url = "https://github.com/svanderburg/dysnomia/releases/download/dysnomia-0.10/dysnomia-0.10.tar.gz";
|
||||
sha256 = "19zg4nhn0f9v4i7c9hhan1i4xv3ljfpl2d0s84ph8byiscvhyrna";
|
||||
};
|
||||
|
||||
preConfigure = if enableEjabberdDump then "export PATH=$PATH:${ejabberd}/sbin" else "";
|
||||
|
||||
configureFlags = [
|
||||
(if enableApacheWebApplication then "--with-apache" else "--without-apache")
|
||||
(if enableAxis2WebService then "--with-axis2" else "--without-axis2")
|
||||
(if enableEjabberdDump then "--with-ejabberd" else "--without-ejabberd")
|
||||
(if enableMySQLDatabase then "--with-mysql" else "--without-mysql")
|
||||
(if enablePostgreSQLDatabase then "--with-postgresql" else "--without-postgresql")
|
||||
(if enableSubversionRepository then "--with-subversion" else "--without-subversion")
|
||||
(if enableTomcatWebApplication then "--with-tomcat=${catalinaBaseDir}" else "--without-tomcat")
|
||||
(if enableMongoDatabase then "--with-mongodb" else "--without-mongodb")
|
||||
(if enableInfluxDatabase then "--with-influxdb" else "--without-influxdb")
|
||||
(if enableSupervisordProgram then "--with-supervisord" else "--without-supervisord")
|
||||
(if enableDockerContainer then "--with-docker" else "--without-docker")
|
||||
"--with-job-template=${jobTemplate}"
|
||||
] ++ lib.optional enableLegacy "--enable-legacy";
|
||||
|
||||
buildInputs = [ getopt netcat ]
|
||||
++ lib.optional stdenv.isLinux systemd
|
||||
++ lib.optional enableEjabberdDump ejabberd
|
||||
++ lib.optional enableMySQLDatabase mysql.out
|
||||
++ lib.optional enablePostgreSQLDatabase postgresql
|
||||
++ lib.optional enableSubversionRepository subversion
|
||||
++ lib.optional enableMongoDatabase mongodb
|
||||
++ lib.optional enableMongoDatabase mongodb-tools
|
||||
++ lib.optional enableInfluxDatabase influxdb
|
||||
++ lib.optional enableSupervisordProgram supervisor
|
||||
++ lib.optional enableDockerContainer docker;
|
||||
|
||||
meta = {
|
||||
description = "Automated deployment of mutable components and services for Disnix";
|
||||
license = lib.licenses.mit;
|
||||
maintainers = [ lib.maintainers.sander ];
|
||||
platforms = lib.platforms.unix;
|
||||
};
|
||||
}
|
@ -2,17 +2,17 @@
|
||||
|
||||
buildGoModule rec {
|
||||
pname = "gotop";
|
||||
version = "4.0.1";
|
||||
version = "4.1.0";
|
||||
|
||||
src = fetchFromGitHub {
|
||||
owner = "xxxserxxx";
|
||||
repo = pname;
|
||||
rev = "v${version}";
|
||||
sha256 = "10qfzmq1wdgpvv319khzicalix1x4fqava0wry3bzz84k5c9dabs";
|
||||
sha256 = "09cs97fjjxcjxzsl2kh8j607cs5zy2hnrh1pb21pggzhg7dzsz0w";
|
||||
};
|
||||
|
||||
runVend = true;
|
||||
vendorSha256 = "09vdhdgj74ifdhl6rmxddkvk7ls26jn8gswzcxf9389zkjzi7822";
|
||||
vendorSha256 = "1mbjl7b49naaqkr2j658j17z9ryf5g3x6q34gvmrm7n9y082ggnz";
|
||||
|
||||
preCheck = ''
|
||||
export HOME=$(mktemp -d)
|
||||
@ -21,7 +21,8 @@ buildGoModule rec {
|
||||
meta = with lib; {
|
||||
description = "A terminal based graphical activity monitor inspired by gtop and vtop";
|
||||
homepage = "https://github.com/xxxserxxx/gotop";
|
||||
license = licenses.agpl3;
|
||||
changelog = "https://github.com/xxxserxxx/gotop/blob/v${version}/CHANGELOG.md";
|
||||
license = licenses.mit;
|
||||
maintainers = [ maintainers.magnetophon ];
|
||||
platforms = platforms.unix;
|
||||
};
|
||||
|
@ -2,7 +2,7 @@
|
||||
, texlive
|
||||
, zlib, libiconv, libpng, libX11
|
||||
, freetype, gd, libXaw, icu, ghostscript, libXpm, libXmu, libXext
|
||||
, perl, perlPackages, python2Packages, pkg-config
|
||||
, perl, perlPackages, python3Packages, pkg-config
|
||||
, poppler, libpaper, graphite2, zziplib, harfbuzz, potrace, gmp, mpfr
|
||||
, brotli, cairo, pixman, xorg, clisp, biber, woff2, xxHash
|
||||
, makeWrapper, shortenPerlShebang
|
||||
@ -321,13 +321,13 @@ latexindent = perlPackages.buildPerlPackage rec {
|
||||
};
|
||||
|
||||
|
||||
pygmentex = python2Packages.buildPythonApplication rec {
|
||||
pygmentex = python3Packages.buildPythonApplication rec {
|
||||
pname = "pygmentex";
|
||||
inherit (src) version;
|
||||
|
||||
src = lib.head (builtins.filter (p: p.tlType == "run") texlive.pygmentex.pkgs);
|
||||
|
||||
propagatedBuildInputs = with python2Packages; [ pygments chardet ];
|
||||
propagatedBuildInputs = with python3Packages; [ pygments chardet ];
|
||||
|
||||
dontBuild = true;
|
||||
|
||||
|
@ -29,7 +29,7 @@ let
|
||||
[ "de-macro" "pythontex" "dviasm" "texliveonfly" ];
|
||||
pkgNeedsRuby = pkg: pkg.tlType == "run" && pkg.pname == "match-parens";
|
||||
extraInputs =
|
||||
lib.optional (lib.any pkgNeedsPython splitBin.wrong) python
|
||||
lib.optional (lib.any pkgNeedsPython splitBin.wrong) python3
|
||||
++ lib.optional (lib.any pkgNeedsRuby splitBin.wrong) ruby;
|
||||
};
|
||||
|
||||
|
@ -4,7 +4,7 @@
|
||||
*/
|
||||
{ stdenv, lib, fetchurl, runCommand, writeText, buildEnv
|
||||
, callPackage, ghostscriptX, harfbuzz, poppler_min
|
||||
, makeWrapper, python, ruby, perl
|
||||
, makeWrapper, python3, ruby, perl
|
||||
, useFixedHashes ? true
|
||||
, recurseIntoAttrs
|
||||
}:
|
||||
@ -25,7 +25,7 @@ let
|
||||
# function for creating a working environment from a set of TL packages
|
||||
combine = import ./combine.nix {
|
||||
inherit bin combinePkgs buildEnv lib makeWrapper writeText
|
||||
stdenv python ruby perl;
|
||||
stdenv python3 ruby perl;
|
||||
ghostscript = ghostscriptX; # could be without X, probably, but we use X above
|
||||
};
|
||||
|
||||
|
@ -123,6 +123,9 @@ mapAliases ({
|
||||
dbus_glib = dbus-glib; # added 2018-02-25
|
||||
dbus_libs = dbus; # added 2018-04-25
|
||||
diffuse = throw "diffuse has been removed from nixpkgs, as it's unmaintained"; # added 2019-12-10
|
||||
disnix = throw "disnix has been removed."; # added 2021-01-27
|
||||
disnixos = throw "disnixos has been removed."; # added 2021-01-27
|
||||
DisnixWebService = throw "DisnixWebService has been removed."; # added 2021-01-27
|
||||
dbus_tools = dbus.out; # added 2018-04-25
|
||||
deadbeef-mpris2-plugin = deadbeefPlugins.mpris2; # added 2018-02-23
|
||||
deadpixi-sam = deadpixi-sam-unstable;
|
||||
@ -139,6 +142,8 @@ mapAliases ({
|
||||
docker_compose = docker-compose; # 2018-11-10
|
||||
draftsight = throw "draftsight has been removed, no longer available as freeware"; # added 2020-08-14
|
||||
dvb_apps = throw "dvb_apps has been removed."; # added 2020-11-03
|
||||
dydisnix = throw "dydisnix has been removed."; # added 2021-01-27
|
||||
dysnomia = throw "dysnomia has been removed."; # added 2021-01-27
|
||||
dwarf_fortress = dwarf-fortress; # added 2016-01-23
|
||||
elasticmq = throw "elasticmq has been removed in favour of elasticmq-server-bin"; # added 2021-01-17
|
||||
emacsPackagesGen = emacsPackagesFor; # added 2018-08-18
|
||||
|
@ -7056,6 +7056,8 @@ in
|
||||
|
||||
tautulli = python3Packages.callPackage ../servers/tautulli { };
|
||||
|
||||
pleroma-otp = callPackage ../servers/pleroma-otp { };
|
||||
|
||||
ploticus = callPackage ../tools/graphics/ploticus {
|
||||
libpng = libpng12;
|
||||
};
|
||||
@ -28884,18 +28886,6 @@ in
|
||||
|
||||
solfege = python3Packages.callPackage ../misc/solfege { };
|
||||
|
||||
disnix = callPackage ../tools/package-management/disnix { };
|
||||
|
||||
dysnomia = callPackage ../tools/package-management/disnix/dysnomia (config.disnix or {
|
||||
inherit (pythonPackages) supervisor;
|
||||
});
|
||||
|
||||
dydisnix = callPackage ../tools/package-management/disnix/dydisnix { };
|
||||
|
||||
disnixos = callPackage ../tools/package-management/disnix/disnixos { };
|
||||
|
||||
DisnixWebService = callPackage ../tools/package-management/disnix/DisnixWebService { };
|
||||
|
||||
lkproof = callPackage ../tools/typesetting/tex/lkproof { };
|
||||
|
||||
lice = callPackage ../tools/misc/lice {};
|
||||
|
Loading…
Reference in New Issue
Block a user