Skip to content
Permalink
Browse files

nixos: kodi module

Includes basic support for specifying sources and advanced configuration.
  • Loading branch information
peterhoeg committed Sep 23, 2019
1 parent 021d733 commit ff4a0d310af777ebf27dac74d227a7df63887a97
Showing with 212 additions and 11 deletions.
  1. +212 −11 nixos/modules/services/x11/desktop-managers/kodi.nix
@@ -4,27 +4,228 @@ with lib;

let
cfg = config.services.xserver.desktopManager.kodi;
in

{
bin = "${getBin pkgs.kodi}/bin/kodi --lircdev /run/lirc/lircd --standalone";

manageSources = (cfg.sourcesConfig != "");

advCfg = pkgs.writeText "advancedsettings.xml" ''
<?xml version='1.0' encoding='utf-8'?>
<advancedsettings version='1.0'>
${optionalString (cfg.database.type == "mysql") ''
<videodatabase>
<type>mysql</type>
<host>${cfg.database.host}</host>
<port>${toString cfg.database.port}</port>
<user>${cfg.database.user}</user>
<pass>${cfg.database.password}</pass>
</videodatabase>
<musicdatabase>
<type>mysql</type>
<host>${cfg.database.host}</host>
<port>${toString cfg.database.port}</port>
<user>${cfg.database.user}</user>
<pass>${cfg.database.password}</pass>
</musicdatabase>''}
${cfg.advancedConfig}
</advancedsettings>
'';

srcCfg = pkgs.writeText "sources.xml" ''
<?xml version='1.0' encoding='utf-8'?>
<sources>
${cfg.sourcesConfig}
</sources>
'';

cfgDir = pkgs.stdenv.mkDerivation {
name = "kodi-config";
buildCommand = ''
install -Dm444 ${advCfg} $out/etc/kodi/advancedsettings.xml
install -Dm444 ${srcCfg} $out/etc/kodi/sources.xml
'';
};

setupScript = pkgs.writeScript "link_kodi_config.sh" ''
#!${pkgs.runtimeShell}
set -eEuo pipefail
processUserFile() {
local userdata=${cfg.homeDir}/.kodi/userdata
mkdir -p $userdata
ln -sf ${cfgDir}/etc/kodi/$1 $userdata/$1
}
processUserFile advancedsettings.xml
${lib.optionalString manageSources ''
processUserFile sources.xml
''}
exit 0
'';

# sddm is broken for auto-login using id < 1000
# https://github.com/sddm/sddm/issues/762
# uid = config.ids.uids.kodi;
uid = 3000;

in {
options = {
services.xserver.desktopManager.kodi = {
enable = mkOption {
default = false;
type = types.bool;
example = true;
description = "Enable the kodi multimedia center.";
};

runMode = mkOption {
default = "session";
type = types.enum [ "session" "auto-login" "standalone" ];
description = ''
How to launch kodi.
'';
};

tty = mkOption {
default = "tty7";
type = types.str;
description = "Which TTY to launch kodi on.";
};

homeDir = mkOption {
default = "/var/lib/kodi";
type = types.str;
description = "Home directory.";
};

zeroconf = mkOption {
default = false;
type = types.bool;
description = "Enable support for Zeroconf/Avahi";
};

database = mkOption {
default = {};
description = "Configure the database.";
type = (types.submodule {
options = {
type = mkOption {
default = "sqlite";
type = types.enum [ "sqlite" "mysql" ];
description = "Which type of database to connect to.";
};

host = mkOption {
default = "localhost";
type = types.str;
description = "Database host.";
};

port = mkOption {
default = 3306;
type = types.int;
description = "Database port.";
};

user = mkOption {
default = "kodi";
type = types.str;
description = "Database user.";
};

password = mkOption {
default = "kodi";
type = types.str;
description = "Database password.";
};
};
});
};

sourcesConfig = mkOption {
type = types.lines;
default = "";
description = ''sources.xml configuration'';
};

advancedConfig = mkOption {
type = types.lines;
default = "";
description = ''Extra advancedsettings.xml configuration'';
};
};
};

config = mkIf cfg.enable {
services.xserver.desktopManager.session = [{
name = "kodi";
start = ''
${pkgs.kodi}/bin/kodi --lircdev /var/run/lirc/lircd --standalone &
waitPID=$!
'';
}];

environment.systemPackages = [ pkgs.kodi ];
environment.systemPackages = with pkgs; [ kodi ];

environment.etc.kodi.source = cfgDir;

services = {
avahi.enable = cfg.zeroconf;

xserver = {
desktopManager.session = [{
name = "kodi";
start = ''
${setupScript}
${bin} &
waitPID=$!
'';
}];

displayManager.sddm = {
enable = (cfg.runMode == "auto-login");
autoLogin = {
enable = true;
user = "kodi";
relogin = true;
};
};
};
};

systemd.services = {
kodi = mkIf (cfg.runMode == "standalone") {
description = "Kodi Media Server on ${cfg.tty}";
conflicts = [ "getty@${cfg.tty}.service"];
after = [ "mysqld.service" ];
wantedBy = [ "graphical.target" ];
path = [ "${getBin pkgs.xorg.xorgserver}" ];
serviceConfig = {
User = "kodi";
Group = "kodi";
PAMName = "login";
ExecStartPre = setupScript;
ExecStart = ''
${pkgs.xorg.xinit}/bin/xinit ${bin} -- :${toString (if builtins.isInt config.services.xserver.display then config.services.xserver.display else 0)} -nolisten tcp ${builtins.replaceStrings [ "tty" ] [ "vt" ] cfg.tty}
'';
Restart = "on-failure";
ProtectSystem = "full";
# doesn't work with true as it is expecting a socket in /tmp
PrivateTmp = false;
};
};
};

users = {
extraGroups.kodi.gid = uid;

extraUsers.kodi = {
uid = uid;
group = "kodi";
home = cfg.homeDir;
description = "Kodi User";
createHome = true;
shell = "${pkgs.stdenv.shell}";
isNormalUser = false;
# tty seems needed for "standalone" although not quite working yet
extraGroups = [ "tty" ];
};
};
};
}

0 comments on commit ff4a0d3

Please sign in to comment.
You can’t perform that action at this time.