commit
aba90d9366
@ -0,0 +1,345 @@ |
|||||||
|
{ config, lib, options, pkgs, ... }: |
||||||
|
let |
||||||
|
cfg = config.services.kanidm; |
||||||
|
settingsFormat = pkgs.formats.toml { }; |
||||||
|
# Remove null values, so we can document optional values that don't end up in the generated TOML file. |
||||||
|
filterConfig = lib.converge (lib.filterAttrsRecursive (_: v: v != null)); |
||||||
|
serverConfigFile = settingsFormat.generate "server.toml" (filterConfig cfg.serverSettings); |
||||||
|
clientConfigFile = settingsFormat.generate "kanidm-config.toml" (filterConfig cfg.clientSettings); |
||||||
|
unixConfigFile = settingsFormat.generate "kanidm-unixd.toml" (filterConfig cfg.unixSettings); |
||||||
|
|
||||||
|
defaultServiceConfig = { |
||||||
|
BindReadOnlyPaths = [ |
||||||
|
"/nix/store" |
||||||
|
"-/etc/resolv.conf" |
||||||
|
"-/etc/nsswitch.conf" |
||||||
|
"-/etc/hosts" |
||||||
|
"-/etc/localtime" |
||||||
|
]; |
||||||
|
CapabilityBoundingSet = ""; |
||||||
|
# ProtectClock= adds DeviceAllow=char-rtc r |
||||||
|
DeviceAllow = ""; |
||||||
|
# Implies ProtectSystem=strict, which re-mounts all paths |
||||||
|
# DynamicUser = true; |
||||||
|
LockPersonality = true; |
||||||
|
MemoryDenyWriteExecute = true; |
||||||
|
NoNewPrivileges = true; |
||||||
|
PrivateDevices = true; |
||||||
|
PrivateMounts = true; |
||||||
|
PrivateNetwork = true; |
||||||
|
PrivateTmp = true; |
||||||
|
PrivateUsers = true; |
||||||
|
ProcSubset = "pid"; |
||||||
|
ProtectClock = true; |
||||||
|
ProtectHome = true; |
||||||
|
ProtectHostname = true; |
||||||
|
# Would re-mount paths ignored by temporary root |
||||||
|
#ProtectSystem = "strict"; |
||||||
|
ProtectControlGroups = true; |
||||||
|
ProtectKernelLogs = true; |
||||||
|
ProtectKernelModules = true; |
||||||
|
ProtectKernelTunables = true; |
||||||
|
ProtectProc = "invisible"; |
||||||
|
RestrictAddressFamilies = [ ]; |
||||||
|
RestrictNamespaces = true; |
||||||
|
RestrictRealtime = true; |
||||||
|
RestrictSUIDSGID = true; |
||||||
|
SystemCallArchitectures = "native"; |
||||||
|
SystemCallFilter = [ "@system-service" "~@privileged @resources @setuid @keyring" ]; |
||||||
|
# Does not work well with the temporary root |
||||||
|
#UMask = "0066"; |
||||||
|
}; |
||||||
|
|
||||||
|
in |
||||||
|
{ |
||||||
|
options.services.kanidm = { |
||||||
|
enableClient = lib.mkEnableOption "the Kanidm client"; |
||||||
|
enableServer = lib.mkEnableOption "the Kanidm server"; |
||||||
|
enablePam = lib.mkEnableOption "the Kanidm PAM and NSS integration."; |
||||||
|
|
||||||
|
serverSettings = lib.mkOption { |
||||||
|
type = lib.types.submodule { |
||||||
|
freeformType = settingsFormat.type; |
||||||
|
|
||||||
|
options = { |
||||||
|
bindaddress = lib.mkOption { |
||||||
|
description = "Address/port combination the webserver binds to."; |
||||||
|
example = "[::1]:8443"; |
||||||
|
type = lib.types.str; |
||||||
|
}; |
||||||
|
# Should be optional but toml does not accept null |
||||||
|
ldapbindaddress = lib.mkOption { |
||||||
|
description = '' |
||||||
|
Address and port the LDAP server is bound to. Setting this to <literal>null</literal> disables the LDAP interface. |
||||||
|
''; |
||||||
|
example = "[::1]:636"; |
||||||
|
default = null; |
||||||
|
type = lib.types.nullOr lib.types.str; |
||||||
|
}; |
||||||
|
origin = lib.mkOption { |
||||||
|
description = "The origin of your Kanidm instance. Must have https as protocol."; |
||||||
|
example = "https://idm.example.org"; |
||||||
|
type = lib.types.strMatching "^https://.*"; |
||||||
|
}; |
||||||
|
domain = lib.mkOption { |
||||||
|
description = '' |
||||||
|
The <literal>domain</literal> that Kanidm manages. Must be below or equal to the domain |
||||||
|
specified in <literal>serverSettings.origin</literal>. |
||||||
|
This can be left at <literal>null</literal>, only if your instance has the role <literal>ReadOnlyReplica</literal>. |
||||||
|
While it is possible to change the domain later on, it requires extra steps! |
||||||
|
Please consider the warnings and execute the steps described |
||||||
|
<link xlink:href="https://kanidm.github.io/kanidm/stable/administrivia.html#rename-the-domain">in the documentation</link>. |
||||||
|
''; |
||||||
|
example = "example.org"; |
||||||
|
default = null; |
||||||
|
type = lib.types.nullOr lib.types.str; |
||||||
|
}; |
||||||
|
db_path = lib.mkOption { |
||||||
|
description = "Path to Kanidm database."; |
||||||
|
default = "/var/lib/kanidm/kanidm.db"; |
||||||
|
readOnly = true; |
||||||
|
type = lib.types.path; |
||||||
|
}; |
||||||
|
log_level = lib.mkOption { |
||||||
|
description = "Log level of the server."; |
||||||
|
default = "default"; |
||||||
|
type = lib.types.enum [ "default" "verbose" "perfbasic" "perffull" ]; |
||||||
|
}; |
||||||
|
role = lib.mkOption { |
||||||
|
description = "The role of this server. This affects the replication relationship and thereby available features."; |
||||||
|
default = "WriteReplica"; |
||||||
|
type = lib.types.enum [ "WriteReplica" "WriteReplicaNoUI" "ReadOnlyReplica" ]; |
||||||
|
}; |
||||||
|
}; |
||||||
|
}; |
||||||
|
default = { }; |
||||||
|
description = '' |
||||||
|
Settings for Kanidm, see |
||||||
|
<link xlink:href="https://github.com/kanidm/kanidm/blob/master/kanidm_book/src/server_configuration.md">the documentation</link> |
||||||
|
and <link xlink:href="https://github.com/kanidm/kanidm/blob/master/examples/server.toml">example configuration</link> |
||||||
|
for possible values. |
||||||
|
''; |
||||||
|
}; |
||||||
|
|
||||||
|
clientSettings = lib.mkOption { |
||||||
|
type = lib.types.submodule { |
||||||
|
freeformType = settingsFormat.type; |
||||||
|
|
||||||
|
options.uri = lib.mkOption { |
||||||
|
description = "Address of the Kanidm server."; |
||||||
|
example = "http://127.0.0.1:8080"; |
||||||
|
type = lib.types.str; |
||||||
|
}; |
||||||
|
}; |
||||||
|
description = '' |
||||||
|
Configure Kanidm clients, needed for the PAM daemon. See |
||||||
|
<link xlink:href="https://github.com/kanidm/kanidm/blob/master/kanidm_book/src/client_tools.md#kanidm-configuration">the documentation</link> |
||||||
|
and <link xlink:href="https://github.com/kanidm/kanidm/blob/master/examples/config">example configuration</link> |
||||||
|
for possible values. |
||||||
|
''; |
||||||
|
}; |
||||||
|
|
||||||
|
unixSettings = lib.mkOption { |
||||||
|
type = lib.types.submodule { |
||||||
|
freeformType = settingsFormat.type; |
||||||
|
|
||||||
|
options.pam_allowed_login_groups = lib.mkOption { |
||||||
|
description = "Kanidm groups that are allowed to login using PAM."; |
||||||
|
example = "my_pam_group"; |
||||||
|
type = lib.types.listOf lib.types.str; |
||||||
|
}; |
||||||
|
}; |
||||||
|
description = '' |
||||||
|
Configure Kanidm unix daemon. |
||||||
|
See <link xlink:href="https://github.com/kanidm/kanidm/blob/master/kanidm_book/src/pam_and_nsswitch.md#the-unix-daemon">the documentation</link> |
||||||
|
and <link xlink:href="https://github.com/kanidm/kanidm/blob/master/examples/unixd">example configuration</link> |
||||||
|
for possible values. |
||||||
|
''; |
||||||
|
}; |
||||||
|
}; |
||||||
|
|
||||||
|
config = lib.mkIf (cfg.enableClient || cfg.enableServer || cfg.enablePam) { |
||||||
|
assertions = |
||||||
|
[ |
||||||
|
{ |
||||||
|
assertion = !cfg.enableServer || ((cfg.serverSettings.tls_chain or null) == null) || (!lib.isStorePath cfg.serverSettings.tls_chain); |
||||||
|
message = '' |
||||||
|
<option>services.kanidm.serverSettings.tls_chain</option> points to |
||||||
|
a file in the Nix store. You should use a quoted absolute path to |
||||||
|
prevent this. |
||||||
|
''; |
||||||
|
} |
||||||
|
{ |
||||||
|
assertion = !cfg.enableServer || ((cfg.serverSettings.tls_key or null) == null) || (!lib.isStorePath cfg.serverSettings.tls_key); |
||||||
|
message = '' |
||||||
|
<option>services.kanidm.serverSettings.tls_key</option> points to |
||||||
|
a file in the Nix store. You should use a quoted absolute path to |
||||||
|
prevent this. |
||||||
|
''; |
||||||
|
} |
||||||
|
{ |
||||||
|
assertion = !cfg.enableClient || options.services.kanidm.clientSettings.isDefined; |
||||||
|
message = '' |
||||||
|
<option>services.kanidm.clientSettings</option> needs to be configured |
||||||
|
if the client is enabled. |
||||||
|
''; |
||||||
|
} |
||||||
|
{ |
||||||
|
assertion = !cfg.enablePam || options.services.kanidm.clientSettings.isDefined; |
||||||
|
message = '' |
||||||
|
<option>services.kanidm.clientSettings</option> needs to be configured |
||||||
|
for the PAM daemon to connect to the Kanidm server. |
||||||
|
''; |
||||||
|
} |
||||||
|
{ |
||||||
|
assertion = !cfg.enableServer || (cfg.serverSettings.domain == null |
||||||
|
-> cfg.serverSettings.role == "WriteReplica" || cfg.serverSettings.role == "WriteReplicaNoUI"); |
||||||
|
message = '' |
||||||
|
<option>services.kanidm.serverSettings.domain</option> can only be set if this instance |
||||||
|
is not a ReadOnlyReplica. Otherwise the db would inherit it from |
||||||
|
the instance it follows. |
||||||
|
''; |
||||||
|
} |
||||||
|
]; |
||||||
|
|
||||||
|
environment.systemPackages = lib.mkIf cfg.enableClient [ pkgs.kanidm ]; |
||||||
|
|
||||||
|
systemd.services.kanidm = lib.mkIf cfg.enableServer { |
||||||
|
description = "kanidm identity management daemon"; |
||||||
|
wantedBy = [ "multi-user.target" ]; |
||||||
|
after = [ "network.target" ]; |
||||||
|
serviceConfig = defaultServiceConfig // { |
||||||
|
StateDirectory = "kanidm"; |
||||||
|
StateDirectoryMode = "0700"; |
||||||
|
ExecStart = "${pkgs.kanidm}/bin/kanidmd server -c ${serverConfigFile}"; |
||||||
|
User = "kanidm"; |
||||||
|
Group = "kanidm"; |
||||||
|
|
||||||
|
AmbientCapabilities = [ "CAP_NET_BIND_SERVICE" ]; |
||||||
|
CapabilityBoundingSet = [ "CAP_NET_BIND_SERVICE" ]; |
||||||
|
# This would otherwise override the CAP_NET_BIND_SERVICE capability. |
||||||
|
PrivateUsers = false; |
||||||
|
# Port needs to be exposed to the host network |
||||||
|
PrivateNetwork = false; |
||||||
|
RestrictAddressFamilies = [ "AF_INET" "AF_INET6" ]; |
||||||
|
TemporaryFileSystem = "/:ro"; |
||||||
|
}; |
||||||
|
environment.RUST_LOG = "info"; |
||||||
|
}; |
||||||
|
|
||||||
|
systemd.services.kanidm-unixd = lib.mkIf cfg.enablePam { |
||||||
|
description = "Kanidm PAM daemon"; |
||||||
|
wantedBy = [ "multi-user.target" ]; |
||||||
|
after = [ "network.target" ]; |
||||||
|
restartTriggers = [ unixConfigFile clientConfigFile ]; |
||||||
|
serviceConfig = defaultServiceConfig // { |
||||||
|
CacheDirectory = "kanidm-unixd"; |
||||||
|
CacheDirectoryMode = "0700"; |
||||||
|
RuntimeDirectory = "kanidm-unixd"; |
||||||
|
ExecStart = "${pkgs.kanidm}/bin/kanidm_unixd"; |
||||||
|
User = "kanidm-unixd"; |
||||||
|
Group = "kanidm-unixd"; |
||||||
|
|
||||||
|
BindReadOnlyPaths = [ |
||||||
|
"/nix/store" |
||||||
|
"-/etc/resolv.conf" |
||||||
|
"-/etc/nsswitch.conf" |
||||||
|
"-/etc/hosts" |
||||||
|
"-/etc/localtime" |
||||||
|
"-/etc/kanidm" |
||||||
|
"-/etc/static/kanidm" |
||||||
|
]; |
||||||
|
BindPaths = [ |
||||||
|
# To create the socket |
||||||
|
"/run/kanidm-unixd:/var/run/kanidm-unixd" |
||||||
|
]; |
||||||
|
# Needs to connect to kanidmd |
||||||
|
PrivateNetwork = false; |
||||||
|
RestrictAddressFamilies = [ "AF_INET" "AF_INET6" "AF_UNIX" ]; |
||||||
|
TemporaryFileSystem = "/:ro"; |
||||||
|
}; |
||||||
|
environment.RUST_LOG = "info"; |
||||||
|
}; |
||||||
|
|
||||||
|
systemd.services.kanidm-unixd-tasks = lib.mkIf cfg.enablePam { |
||||||
|
description = "Kanidm PAM home management daemon"; |
||||||
|
wantedBy = [ "multi-user.target" ]; |
||||||
|
after = [ "network.target" "kanidm-unixd.service" ]; |
||||||
|
partOf = [ "kanidm-unixd.service" ]; |
||||||
|
restartTriggers = [ unixConfigFile clientConfigFile ]; |
||||||
|
serviceConfig = { |
||||||
|
ExecStart = "${pkgs.kanidm}/bin/kanidm_unixd_tasks"; |
||||||
|
|
||||||
|
BindReadOnlyPaths = [ |
||||||
|
"/nix/store" |
||||||
|
"-/etc/resolv.conf" |
||||||
|
"-/etc/nsswitch.conf" |
||||||
|
"-/etc/hosts" |
||||||
|
"-/etc/localtime" |
||||||
|
"-/etc/kanidm" |
||||||
|
"-/etc/static/kanidm" |
||||||
|
]; |
||||||
|
BindPaths = [ |
||||||
|
# To manage home directories |
||||||
|
"/home" |
||||||
|
# To connect to kanidm-unixd |
||||||
|
"/run/kanidm-unixd:/var/run/kanidm-unixd" |
||||||
|
]; |
||||||
|
# CAP_DAC_OVERRIDE is needed to ignore ownership of unixd socket |
||||||
|
CapabilityBoundingSet = [ "CAP_CHOWN" "CAP_FOWNER" "CAP_DAC_OVERRIDE" "CAP_DAC_READ_SEARCH" ]; |
||||||
|
IPAddressDeny = "any"; |
||||||
|
# Need access to users |
||||||
|
PrivateUsers = false; |
||||||
|
# Need access to home directories |
||||||
|
ProtectHome = false; |
||||||
|
RestrictAddressFamilies = [ "AF_UNIX" ]; |
||||||
|
TemporaryFileSystem = "/:ro"; |
||||||
|
}; |
||||||
|
environment.RUST_LOG = "info"; |
||||||
|
}; |
||||||
|
|
||||||
|
# These paths are hardcoded |
||||||
|
environment.etc = lib.mkMerge [ |
||||||
|
(lib.mkIf options.services.kanidm.clientSettings.isDefined { |
||||||
|
"kanidm/config".source = clientConfigFile; |
||||||
|
}) |
||||||
|
(lib.mkIf cfg.enablePam { |
||||||
|
"kanidm/unixd".source = unixConfigFile; |
||||||
|
}) |
||||||
|
]; |
||||||
|
|
||||||
|
system.nssModules = lib.mkIf cfg.enablePam [ pkgs.kanidm ]; |
||||||
|
|
||||||
|
system.nssDatabases.group = lib.optional cfg.enablePam "kanidm"; |
||||||
|
system.nssDatabases.passwd = lib.optional cfg.enablePam "kanidm"; |
||||||
|
|
||||||
|
users.groups = lib.mkMerge [ |
||||||
|
(lib.mkIf cfg.enableServer { |
||||||
|
kanidm = { }; |
||||||
|
}) |
||||||
|
(lib.mkIf cfg.enablePam { |
||||||
|
kanidm-unixd = { }; |
||||||
|
}) |
||||||
|
]; |
||||||
|
users.users = lib.mkMerge [ |
||||||
|
(lib.mkIf cfg.enableServer { |
||||||
|
kanidm = { |
||||||
|
description = "Kanidm server"; |
||||||
|
isSystemUser = true; |
||||||
|
group = "kanidm"; |
||||||
|
packages = with pkgs; [ kanidm ]; |
||||||
|
}; |
||||||
|
}) |
||||||
|
(lib.mkIf cfg.enablePam { |
||||||
|
kanidm-unixd = { |
||||||
|
description = "Kanidm PAM daemon"; |
||||||
|
isSystemUser = true; |
||||||
|
group = "kanidm-unixd"; |
||||||
|
}; |
||||||
|
}) |
||||||
|
]; |
||||||
|
}; |
||||||
|
|
||||||
|
meta.maintainers = with lib.maintainers; [ erictapen Flakebi ]; |
||||||
|
meta.buildDocsInSandbox = false; |
||||||
|
} |
@ -1,9 +0,0 @@ |
|||||||
{ pkgs, lib, makeInstalledTest, ... }: |
|
||||||
|
|
||||||
makeInstalledTest { |
|
||||||
tested = pkgs.power-profiles-daemon; |
|
||||||
|
|
||||||
testConfig = { |
|
||||||
services.power-profiles-daemon.enable = true; |
|
||||||
}; |
|
||||||
} |
|
@ -0,0 +1,75 @@ |
|||||||
|
import ./make-test-python.nix ({ pkgs, ... }: |
||||||
|
let |
||||||
|
certs = import ./common/acme/server/snakeoil-certs.nix; |
||||||
|
serverDomain = certs.domain; |
||||||
|
in |
||||||
|
{ |
||||||
|
name = "kanidm"; |
||||||
|
meta.maintainers = with pkgs.lib.maintainers; [ erictapen Flakebi ]; |
||||||
|
|
||||||
|
nodes.server = { config, pkgs, lib, ... }: { |
||||||
|
services.kanidm = { |
||||||
|
enableServer = true; |
||||||
|
serverSettings = { |
||||||
|
origin = "https://${serverDomain}"; |
||||||
|
domain = serverDomain; |
||||||
|
bindaddress = "[::1]:8443"; |
||||||
|
ldapbindaddress = "[::1]:636"; |
||||||
|
}; |
||||||
|
}; |
||||||
|
|
||||||
|
services.nginx = { |
||||||
|
enable = true; |
||||||
|
recommendedProxySettings = true; |
||||||
|
virtualHosts."${serverDomain}" = { |
||||||
|
forceSSL = true; |
||||||
|
sslCertificate = certs."${serverDomain}".cert; |
||||||
|
sslCertificateKey = certs."${serverDomain}".key; |
||||||
|
locations."/".proxyPass = "http://[::1]:8443"; |
||||||
|
}; |
||||||
|
}; |
||||||
|
|
||||||
|
security.pki.certificateFiles = [ certs.ca.cert ]; |
||||||
|
|
||||||
|
networking.hosts."::1" = [ serverDomain ]; |
||||||
|
networking.firewall.allowedTCPPorts = [ 80 443 ]; |
||||||
|
|
||||||
|
users.users.kanidm.shell = pkgs.bashInteractive; |
||||||
|
|
||||||
|
environment.systemPackages = with pkgs; [ kanidm openldap ripgrep ]; |
||||||
|
}; |
||||||
|
|
||||||
|
nodes.client = { pkgs, nodes, ... }: { |
||||||
|
services.kanidm = { |
||||||
|
enableClient = true; |
||||||
|
clientSettings = { |
||||||
|
uri = "https://${serverDomain}"; |
||||||
|
}; |
||||||
|
}; |
||||||
|
|
||||||
|
networking.hosts."${nodes.server.config.networking.primaryIPAddress}" = [ serverDomain ]; |
||||||
|
|
||||||
|
security.pki.certificateFiles = [ certs.ca.cert ]; |
||||||
|
}; |
||||||
|
|
||||||
|
testScript = { nodes, ... }: |
||||||
|
let |
||||||
|
ldapBaseDN = builtins.concatStringsSep "," (map (s: "dc=" + s) (pkgs.lib.splitString "." serverDomain)); |
||||||
|
|
||||||
|
# We need access to the config file in the test script. |
||||||
|
filteredConfig = pkgs.lib.converge |
||||||
|
(pkgs.lib.filterAttrsRecursive (_: v: v != null)) |
||||||
|
nodes.server.config.services.kanidm.serverSettings; |
||||||
|
serverConfigFile = (pkgs.formats.toml { }).generate "server.toml" filteredConfig; |
||||||
|
|
||||||
|
in |
||||||
|
'' |
||||||
|
start_all() |
||||||
|
server.wait_for_unit("kanidm.service") |
||||||
|
server.wait_until_succeeds("curl -sf https://${serverDomain} | grep Kanidm") |
||||||
|
server.wait_until_succeeds("ldapsearch -H ldap://[::1]:636 -b '${ldapBaseDN}' -x '(name=test)'") |
||||||
|
client.wait_until_succeeds("kanidm login -D anonymous && kanidm self whoami | grep anonymous@${serverDomain}") |
||||||
|
(rv, result) = server.execute("kanidmd recover_account -d quiet -c ${serverConfigFile} -n admin 2>&1 | rg -o '[A-Za-z0-9]{48}'") |
||||||
|
assert rv == 0 |
||||||
|
''; |
||||||
|
}) |
@ -0,0 +1,69 @@ |
|||||||
|
diff --git a/meson.build b/meson.build
|
||||||
|
index 2ed9027..1f6bbf2 100644
|
||||||
|
--- a/meson.build
|
||||||
|
+++ b/meson.build
|
||||||
|
@@ -38,6 +38,7 @@ g_ir_compiler = find_program('g-ir-compiler', required: false)
|
||||||
|
|
||||||
|
conf.set('PACKAGE_NAME', meson.project_name())
|
||||||
|
conf.set_quoted('VERSION', meson.project_version())
|
||||||
|
+conf.set_quoted('LIBDIR', get_option('prefix') / get_option('libdir'))
|
||||||
|
|
||||||
|
# glibc versions somewhere between 2.28 and 2.34
|
||||||
|
if cc.has_function('__fxstatat', prefix: '#include <sys/stat.h>')
|
||||||
|
@@ -148,7 +149,7 @@ hacked_gir = custom_target('UMockdev-1.0 hacked gir',
|
||||||
|
|
||||||
|
if g_ir_compiler.found()
|
||||||
|
umockdev_typelib = custom_target('UMockdev-1.0 typelib',
|
||||||
|
- command: [g_ir_compiler, '--output', '@OUTPUT@', '-l', 'libumockdev.so.0', '@INPUT@'],
|
||||||
|
+ command: [g_ir_compiler, '--output', '@OUTPUT@', '-l', get_option('prefix') / get_option('libdir') / 'libumockdev.so.0', '@INPUT@'],
|
||||||
|
input: hacked_gir,
|
||||||
|
output: 'UMockdev-1.0.typelib',
|
||||||
|
install: true,
|
||||||
|
diff --git a/src/config.vapi b/src/config.vapi
|
||||||
|
index 5269dd0..a2ec46d 100644
|
||||||
|
--- a/src/config.vapi
|
||||||
|
+++ b/src/config.vapi
|
||||||
|
@@ -2,5 +2,6 @@
|
||||||
|
namespace Config {
|
||||||
|
public const string PACKAGE_NAME;
|
||||||
|
public const string VERSION;
|
||||||
|
+ public const string LIBDIR;
|
||||||
|
}
|
||||||
|
|
||||||
|
diff --git a/src/umockdev-record.vala b/src/umockdev-record.vala
|
||||||
|
index 8434d32..68c7f8e 100644
|
||||||
|
--- a/src/umockdev-record.vala
|
||||||
|
+++ b/src/umockdev-record.vala
|
||||||
|
@@ -435,7 +435,7 @@ main (string[] args)
|
||||||
|
preload = "";
|
||||||
|
else
|
||||||
|
preload = preload + ":";
|
||||||
|
- Environment.set_variable("LD_PRELOAD", preload + "libumockdev-preload.so.0", true);
|
||||||
|
+ Environment.set_variable("LD_PRELOAD", preload + Config.LIBDIR + "/libumockdev-preload.so.0", true);
|
||||||
|
|
||||||
|
try {
|
||||||
|
root_dir = DirUtils.make_tmp("umockdev.XXXXXX");
|
||||||
|
diff --git a/src/umockdev-run.vala b/src/umockdev-run.vala
|
||||||
|
index 9a1ba10..6df2522 100644
|
||||||
|
--- a/src/umockdev-run.vala
|
||||||
|
+++ b/src/umockdev-run.vala
|
||||||
|
@@ -95,7 +95,7 @@ main (string[] args)
|
||||||
|
preload = "";
|
||||||
|
else
|
||||||
|
preload = preload + ":";
|
||||||
|
- Environment.set_variable ("LD_PRELOAD", preload + "libumockdev-preload.so.0", true);
|
||||||
|
+ Environment.set_variable ("LD_PRELOAD", preload + Config.LIBDIR + "/libumockdev-preload.so.0", true);
|
||||||
|
|
||||||
|
var testbed = new UMockdev.Testbed ();
|
||||||
|
|
||||||
|
diff --git a/src/umockdev-wrapper b/src/umockdev-wrapper
|
||||||
|
index 6ce4dcd..706c49a 100755
|
||||||
|
--- a/src/umockdev-wrapper
|
||||||
|
+++ b/src/umockdev-wrapper
|
||||||
|
@@ -1,5 +1,5 @@
|
||||||
|
#!/bin/sh
|
||||||
|
# Wrapper program to preload the libumockdev library, so that test programs can
|
||||||
|
# set $UMOCKDEV_DIR for redirecting sysfs and other queries to a test bed.
|
||||||
|
-exec env LD_PRELOAD=libumockdev-preload.so.0:$LD_PRELOAD "$@"
|
||||||
|
+exec env LD_PRELOAD=@LIBDIR@/libumockdev-preload.so.0:$LD_PRELOAD "$@"
|
||||||
|
|
@ -0,0 +1,65 @@ |
|||||||
|
{ lib |
||||||
|
, buildPythonPackage |
||||||
|
, fetchFromGitHub |
||||||
|
, fetchpatch |
||||||
|
, poetry-core |
||||||
|
, importlib-metadata |
||||||
|
, pytest-asyncio |
||||||
|
, pytestCheckHook |
||||||
|
, pythonOlder |
||||||
|
, toml |
||||||
|
}: |
||||||
|
|
||||||
|
buildPythonPackage rec { |
||||||
|
pname = "aiolimiter"; |
||||||
|
version = "1.0.0"; |
||||||
|
format = "pyproject"; |
||||||
|
|
||||||
|
disabled = pythonOlder "3.7"; |
||||||
|
|
||||||
|
src = fetchFromGitHub { |
||||||
|
owner = "mjpieters"; |
||||||
|
repo = pname; |
||||||
|
rev = "v${version}"; |
||||||
|
sha256 = "sha256-4wByVZoOLhrXFx9oK19GBmRcjGoJolQ3Gwx9vQV/n8s="; |
||||||
|
}; |
||||||
|
|
||||||
|
nativeBuildInputs = [ |
||||||
|
poetry-core |
||||||
|
]; |
||||||
|
|
||||||
|
propagatedBuildInputs = lib.optionals (pythonOlder "3.8") [ |
||||||
|
importlib-metadata |
||||||
|
]; |
||||||
|
|
||||||
|
checkInputs = [ |
||||||
|
pytest-asyncio |
||||||
|
pytestCheckHook |
||||||
|
toml |
||||||
|
]; |
||||||
|
|
||||||
|
patches = [ |
||||||
|
# Switch to poetry-core, https://github.com/mjpieters/aiolimiter/pull/77 |
||||||
|
(fetchpatch { |
||||||
|
name = "switch-to-peotry-core.patch"; |
||||||
|
url = "https://github.com/mjpieters/aiolimiter/commit/84a85eff42621b0daff8fcf6bb485db313faae0b.patch"; |
||||||
|
sha256 = "sha256-xUfJwLvMF2Xt/V1bKBFn/fjn1uyw7bGNo9RpWxtyr50="; |
||||||
|
}) |
||||||
|
]; |
||||||
|
|
||||||
|
postPatch = '' |
||||||
|
substituteInPlace tox.ini \ |
||||||
|
--replace " --cov=aiolimiter --cov-config=tox.ini --cov-report term-missing" "" |
||||||
|
''; |
||||||
|
|
||||||
|
pythonImportsCheck = [ |
||||||
|
"aiolimiter" |
||||||
|
]; |
||||||
|
|
||||||
|
meta = with lib; { |
||||||
|
description = "Implementation of a rate limiter for asyncio"; |
||||||
|
homepage = "https://github.com/mjpieters/aiolimiter"; |
||||||
|
license = with licenses; [ mit ]; |
||||||
|
maintainers = with maintainers; [ fab ]; |
||||||
|
}; |
||||||
|
} |
@ -0,0 +1,37 @@ |
|||||||
|
{ lib |
||||||
|
, aiohttp |
||||||
|
, buildPythonPackage |
||||||
|
, fetchPypi |
||||||
|
, pythonOlder |
||||||
|
}: |
||||||
|
|
||||||
|
buildPythonPackage rec { |
||||||
|
pname = "meater-python"; |
||||||
|
version = "0.0.8"; |
||||||
|
format = "setuptools"; |
||||||
|
|
||||||
|
disabled = pythonOlder "3.7"; |
||||||
|
|
||||||
|
src = fetchPypi { |
||||||
|
inherit pname version; |
||||||
|
hash = "sha256-86XJmKOc2MCyU9v0UAZsPCUL/kAXywOlQOIHaykNF1o="; |
||||||
|
}; |
||||||
|
|
||||||
|
propagatedBuildInputs = [ |
||||||
|
aiohttp |
||||||
|
]; |
||||||
|
|
||||||
|
# Module has no tests |
||||||
|
doCheck = false; |
||||||
|
|
||||||
|
pythonImportsCheck = [ |
||||||
|
"meater" |
||||||
|
]; |
||||||
|
|
||||||
|
meta = with lib; { |
||||||
|
description = "Library for the Apption Labs Meater cooking probe"; |
||||||
|
homepage = "https://github.com/Sotolotl/meater-python"; |
||||||
|
license = licenses.asl20; |
||||||
|
maintainers = with maintainers; [ fab ]; |
||||||
|
}; |
||||||
|
} |
@ -0,0 +1,58 @@ |
|||||||
|
{ lib |
||||||
|
, buildPythonPackage |
||||||
|
, fetchFromGitHub |
||||||
|
, parameterized |
||||||
|
, pycryptodome |
||||||
|
, pytestCheckHook |
||||||
|
, pythonOlder |
||||||
|
, pyyaml |
||||||
|
, requests |
||||||
|
, responses |
||||||
|
, setuptools |
||||||
|
}: |
||||||
|
|
||||||
|
buildPythonPackage rec { |
||||||
|
pname = "pyrainbird"; |
||||||
|
version = "0.4.3"; |
||||||
|
format = "setuptools"; |
||||||
|
|
||||||
|
disabled = pythonOlder "3.7"; |
||||||
|
|
||||||
|
src = fetchFromGitHub { |
||||||
|
owner = "jbarrancos"; |
||||||
|
repo = pname; |
||||||
|
rev = version; |
||||||
|
hash = "sha256-uRHknWvoPKPu3B5MbSEUlWqBKwAbNMwsgXuf6PZxhkU="; |
||||||
|
}; |
||||||
|
|
||||||
|
propagatedBuildInputs = [ |
||||||
|
pycryptodome |
||||||
|
pyyaml |
||||||
|
requests |
||||||
|
setuptools |
||||||
|
]; |
||||||
|
|
||||||
|
checkInputs = [ |
||||||
|
pytestCheckHook |
||||||
|
parameterized |
||||||
|
responses |
||||||
|
]; |
||||||
|
|
||||||
|
postPatch = '' |
||||||
|
substituteInPlace requirements.txt \ |
||||||
|
--replace "datetime" "" |
||||||
|
substituteInPlace pytest.ini \ |
||||||
|
--replace "--cov=pyrainbird --cov-report=term-missing --pep8 --flakes --mccabe" "" |
||||||
|
''; |
||||||
|
|
||||||
|
pythonImportsCheck = [ |
||||||
|
"pyrainbird" |
||||||
|
]; |
||||||
|
|
||||||
|
meta = with lib; { |
||||||
|
description = "Module to interact with Rainbird controllers"; |
||||||
|
homepage = "https://github.com/jbarrancos/pyrainbird/"; |
||||||
|
license = with licenses; [ mit ]; |
||||||
|
maintainers = with maintainers; [ fab ]; |
||||||
|
}; |
||||||
|
} |
@ -0,0 +1,61 @@ |
|||||||
|
{ lib |
||||||
|
, beautifulsoup4 |
||||||
|
, buildPythonPackage |
||||||
|
, fetchFromGitHub |
||||||
|
, html5lib |
||||||
|
, pytestCheckHook |
||||||
|
, pythonOlder |
||||||
|
, requests |
||||||
|
, requests-mock |
||||||
|
, urllib3 |
||||||
|
}: |
||||||
|
|
||||||
|
buildPythonPackage rec { |
||||||
|
pname = "raincloudy"; |
||||||
|
version = "1.1.1"; |
||||||
|
format = "setuptools"; |
||||||
|
|
||||||
|
disabled = pythonOlder "3.7"; |
||||||
|
|
||||||
|
src = fetchFromGitHub { |
||||||
|
owner = "vanstinator"; |
||||||
|
repo = pname; |
||||||
|
rev = version; |
||||||
|
hash = "sha256-c6tux0DZY56a4BpuiMXtaqm8+JKNDiyMxrFUju3cp2Y="; |
||||||
|
}; |
||||||
|
|
||||||
|
propagatedBuildInputs = [ |
||||||
|
requests |
||||||
|
beautifulsoup4 |
||||||
|
urllib3 |
||||||
|
html5lib |
||||||
|
]; |
||||||
|
|
||||||
|
checkInputs = [ |
||||||
|
pytestCheckHook |
||||||
|
requests-mock |
||||||
|
]; |
||||||
|
|
||||||
|
postPatch = '' |
||||||
|
# https://github.com/vanstinator/raincloudy/pull/60 |
||||||
|
substituteInPlace setup.py \ |
||||||
|
--replace "bs4" "beautifulsoup4" \ |
||||||
|
--replace "html5lib==1.0.1" "html5lib" |
||||||
|
''; |
||||||
|
|
||||||
|
pythonImportsCheck = [ |
||||||
|
"raincloudy" |
||||||
|
]; |
||||||
|
|
||||||
|
disabledTests = [ |
||||||
|
# Test requires network access |
||||||
|
"test_attributes" |
||||||
|
]; |
||||||
|
|
||||||
|
meta = with lib; { |
||||||
|
description = "Module to interact with Melnor RainCloud Smart Garden Watering Irrigation Timer"; |
||||||
|
homepage = "https://github.com/vanstinator/raincloudy"; |
||||||
|
license = with licenses; [ asl20 ]; |
||||||
|
maintainers = with maintainers; [ fab ]; |
||||||
|
}; |
||||||
|
} |
@ -1,37 +0,0 @@ |
|||||||
diff --git a/meson_options.txt b/meson_options.txt
|
|
||||||
index 7e89619..76497db 100644
|
|
||||||
--- a/meson_options.txt
|
|
||||||
+++ b/meson_options.txt
|
|
||||||
@@ -1,3 +1,4 @@
|
|
||||||
+option('installed_test_prefix', type: 'string', description: 'Prefix for installed tests')
|
|
||||||
option('systemdsystemunitdir',
|
|
||||||
description: 'systemd unit directory',
|
|
||||||
type: 'string',
|
|
||||||
diff --git a/tests/meson.build b/tests/meson.build
|
|
||||||
index b306a7f..7670e1b 100644
|
|
||||||
--- a/tests/meson.build
|
|
||||||
+++ b/tests/meson.build
|
|
||||||
@@ -2,8 +2,8 @@ envs = environment()
|
|
||||||
envs.set ('top_builddir', meson.build_root())
|
|
||||||
envs.set ('top_srcdir', meson.source_root())
|
|
||||||
|
|
||||||
-installed_test_bindir = libexecdir / 'installed-tests' / meson.project_name()
|
|
||||||
-installed_test_datadir = datadir / 'installed-tests' / meson.project_name()
|
|
||||||
+installed_test_bindir = get_option('installed_test_prefix') / 'libexec' / 'installed-tests' / meson.project_name()
|
|
||||||
+installed_test_datadir = get_option('installed_test_prefix') / 'share' / 'installed-tests' / meson.project_name()
|
|
||||||
|
|
||||||
python3 = find_program('python3')
|
|
||||||
unittest_inspector = find_program('unittest_inspector.py')
|
|
||||||
diff --git a/tests/integration-test.py b/tests/integration-test.py
|
|
||||||
index 22dc42c..0f92b76 100755
|
|
||||||
--- a/tests/integration-test.py
|
|
||||||
+++ b/tests/integration-test.py
|
|
||||||
@@ -67,7 +67,7 @@ class Tests(dbusmock.DBusTestCase):
|
|
||||||
print('Testing binaries from JHBuild (%s)' % cls.daemon_path)
|
|
||||||
else:
|
|
||||||
cls.daemon_path = None
|
|
||||||
- with open('/usr/lib/systemd/system/power-profiles-daemon.service') as f:
|
|
||||||
+ with open('/run/current-system/sw/lib/systemd/system/power-profiles-daemon.service') as f:
|
|
||||||
for line in f:
|
|
||||||
if line.startswith('ExecStart='):
|
|
||||||
cls.daemon_path = line.split('=', 1)[1].strip()
|
|
@ -0,0 +1,89 @@ |
|||||||
|
{ stdenv |
||||||
|
, lib |
||||||
|
, formats |
||||||
|
, nixosTests |
||||||
|
, rustPlatform |
||||||
|
, fetchFromGitHub |
||||||
|
, installShellFiles |
||||||
|
, pkg-config |
||||||
|
, udev |
||||||
|
, openssl |
||||||
|
, sqlite |
||||||
|
, pam |
||||||
|
}: |
||||||
|
|
||||||
|
let |
||||||
|
arch = if stdenv.isx86_64 then "x86_64" else "generic"; |
||||||
|
in |
||||||
|
rustPlatform.buildRustPackage rec { |
||||||
|
pname = "kanidm"; |
||||||
|
version = "1.1.0-alpha.8"; |
||||||
|
|
||||||
|
src = fetchFromGitHub { |
||||||
|
owner = pname; |
||||||
|
repo = pname; |
||||||
|
rev = "v${version}"; |
||||||
|
sha256 = "sha256-zMtbE6Y9wXFPBqhmiTMJ3m6bLVZl+c6lRY39DWDlJNo="; |
||||||
|
}; |
||||||
|
|
||||||
|
cargoSha256 = "sha256:1l7xqp457zfd9gfjp6f4lzgadfp6112jbip4irazw4084qwj0z6x"; |
||||||
|
|
||||||
|
KANIDM_BUILD_PROFILE = "release_nixos_${arch}"; |
||||||
|
|
||||||
|
postPatch = |
||||||
|
let |
||||||
|
format = (formats.toml { }).generate "${KANIDM_BUILD_PROFILE}.toml"; |
||||||
|
profile = { |
||||||
|
web_ui_pkg_path = "@web_ui_pkg_path@"; |
||||||
|
cpu_flags = if stdenv.isx86_64 then "x86_64_v1" else "none"; |
||||||
|
}; |
||||||
|
in |
||||||
|
'' |
||||||
|
cp ${format profile} profiles/${KANIDM_BUILD_PROFILE}.toml |
||||||
|
substituteInPlace profiles/${KANIDM_BUILD_PROFILE}.toml \ |
||||||
|
--replace '@web_ui_pkg_path@' "$out/ui" |
||||||
|
''; |
||||||
|
|
||||||
|
nativeBuildInputs = [ |
||||||
|
pkg-config |
||||||
|
installShellFiles |
||||||
|
]; |
||||||
|
|
||||||
|
buildInputs = [ |
||||||
|
udev |
||||||
|
openssl |
||||||
|
sqlite |
||||||
|
pam |
||||||
|
]; |
||||||
|
|
||||||
|
# Failing tests, probably due to network issues |
||||||
|
checkFlags = [ |
||||||
|
"--skip default_entries" |
||||||
|
"--skip oauth2_openid_basic_flow" |
||||||
|
"--skip test_server" |
||||||
|
"--skip test_cache" |
||||||
|
]; |
||||||
|
|
||||||
|
preFixup = '' |
||||||
|
installShellCompletion --bash $releaseDir/build/completions/*.bash |
||||||
|
installShellCompletion --zsh $releaseDir/build/completions/_* |
||||||
|
|
||||||
|
# PAM and NSS need fix library names |
||||||
|
mv $out/lib/libnss_kanidm.so $out/lib/libnss_kanidm.so.2 |
||||||
|
mv $out/lib/libpam_kanidm.so $out/lib/pam_kanidm.so |
||||||
|
|
||||||
|
# We don't compile the wasm-part form source, as there isn't a rustc for |
||||||
|
# wasm32-unknown-unknown in nixpkgs yet. |
||||||
|
cp -r kanidmd_web_ui/pkg $out/ui |
||||||
|
''; |
||||||
|
|
||||||
|
passthru.tests = { inherit (nixosTests) kanidm; }; |
||||||
|
|
||||||
|
meta = with lib; { |
||||||
|
description = "A simple, secure and fast identity management platform"; |
||||||
|
homepage = "https://github.com/kanidm/kanidm"; |
||||||
|
license = licenses.mpl20; |
||||||
|
platforms = platforms.linux; |
||||||
|
maintainers = with maintainers; [ erictapen Flakebi ]; |
||||||
|
}; |
||||||
|
} |
Loading…
Reference in new issue