Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions nixos/modules/module-list.nix
Original file line number Diff line number Diff line change
Expand Up @@ -837,6 +837,7 @@
./services/ttys/gpm.nix
./services/ttys/kmscon.nix
./services/wayland/cage.nix
./services/video/mirakurun.nix
./services/web-apps/atlassian/confluence.nix
./services/web-apps/atlassian/crowd.nix
./services/web-apps/atlassian/jira.nix
Expand Down
165 changes: 165 additions & 0 deletions nixos/modules/services/video/mirakurun.nix
Original file line number Diff line number Diff line change
@@ -0,0 +1,165 @@
{ config, lib, pkgs, ... }:

with lib;

let
cfg = config.services.mirakurun;
mirakurun = pkgs.mirakurun;
username = config.users.users.mirakurun.name;
groupname = config.users.users.mirakurun.group;
settingsFmt = pkgs.formats.yaml {};
in
{
options = {
services.mirakurun = {
enable = mkEnableOption mirakurun.meta.description;

port = mkOption {
type = with types; nullOr port;
default = 40772;
description = ''
Port to listen on. If null, it won't listen on any port.
'';
};

openFirewall = mkOption {
type = types.bool;
default = false;
description = ''
Open ports in the firewall for Mirakurun.
'';
};

serverSettings = mkOption {
type = settingsFmt.type;
default = {};
example = literalExample ''
{
highWaterMark = 25165824;
overflowTimeLimit = 30000;
};
'';
description = ''
Options for server.yml.

Documentation:
<link xlink:href="https://github.com/Chinachu/Mirakurun/blob/master/doc/Configuration.md"/>
'';
};

tunerSettings = mkOption {
type = with types; nullOr settingsFmt.type;
default = null;
example = literalExample ''
[
{
name = "tuner-name";
types = [ "GR" "BS" "CS" "SKY" ];
dvbDevicePath = "/dev/dvb/adapterX/dvrX";
}
];
'';
description = ''
Options which are added to tuners.yml. If none is specified, it will
automatically be generated at runtime.

Documentation:
<link xlink:href="https://github.com/Chinachu/Mirakurun/blob/master/doc/Configuration.md"/>
'';
};

channelSettings = mkOption {
type = with types; nullOr settingsFmt.type;
default = null;
example = literalExample ''
[
{
name = "channel";
types = "GR";
channel = "0";
}
];
'';
description = ''
Options which are added to channels.yml. If none is specified, it
will automatically be generated at runtime.

Documentation:
<link xlink:href="https://github.com/Chinachu/Mirakurun/blob/master/doc/Configuration.md"/>
'';
};
};
};

config = mkIf cfg.enable {
environment.systemPackages = [ mirakurun ];
environment.etc = {
"mirakurun/server.yml".source = settingsFmt.generate "server.yml" cfg.serverSettings;
"mirakurun/tuners.yml" = mkIf (cfg.tunerSettings != null) {
source = settingsFmt.generate "tuners.yml" cfg.tunerSettings;
mode = "0644";
user = username;
group = groupname;
};
"mirakurun/channels.yml" = mkIf (cfg.channelSettings != null) {
source = settingsFmt.generate "channels.yml" cfg.channelSettings;
mode = "0644";
user = username;
group = groupname;
};
};

networking.firewall = mkIf cfg.openFirewall {
allowedTCPPorts = mkIf (cfg.port != null) [ cfg.port ];
};

users.users.mirakurun = {
description = "Mirakurun user";
group = "video";
isSystemUser = true;
};

services.mirakurun.serverSettings = {
logLevel = mkDefault 2;
path = mkDefault "/var/run/mirakurun/mirakurun.sock";
port = mkIf (cfg.port != null) (mkDefault cfg.port);
};

systemd.tmpfiles.rules = [
"d '/etc/mirakurun' - ${username} ${groupname} - -"
];

systemd.services.mirakurun = {
description = mirakurun.meta.description;
wantedBy = [ "multi-user.target" ];
after = [ "network.target" ];
serviceConfig = {
ExecStart = "${mirakurun}/bin/mirakurun";
User = username;
Group = groupname;
RuntimeDirectory="mirakurun";
StateDirectory="mirakurun";
Nice = -10;
IOSchedulingClass = "realtime";
IOSchedulingPriority = 7;
};

environment = {
SERVER_CONFIG_PATH = "/etc/mirakurun/server.yml";
TUNERS_CONFIG_PATH = "/etc/mirakurun/tuners.yml";
CHANNELS_CONFIG_PATH = "/etc/mirakurun/channels.yml";
SERVICES_DB_PATH = "/var/lib/mirakurun/services.json";
PROGRAMS_DB_PATH = "/var/lib/mirakurun/programs.json";
NODE_ENV = "production";
};

restartTriggers = let
getconf = target: config.environment.etc."mirakurun/${target}.yml".source;
targets = [
"server"
] ++ optional (cfg.tunerSettings != null) "tuners"
++ optional (cfg.channelSettings != null) "channels";
in (map getconf targets);
};
};
}
30 changes: 30 additions & 0 deletions pkgs/development/node-packages/default.nix
Original file line number Diff line number Diff line change
Expand Up @@ -60,6 +60,36 @@ let
nativeBuildInputs = drv.nativeBuildInputs or [] ++ [ pkgs.psc-package self.pulp ];
});

mirakurun = super.mirakurun.override rec {
nativeBuildInputs = with pkgs; [ makeWrapper ];
postInstall = let
runtimeDeps = [ nodejs ] ++ (with pkgs; [ bash which v4l_utils ]);
in
''
substituteInPlace $out/lib/node_modules/mirakurun/processes.json \
--replace "/usr/local" ""

# XXX: Files copied from the Nix store are non-writable, so they need
# to be given explicit write permissions
substituteInPlace $out/lib/node_modules/mirakurun/lib/Mirakurun/config.js \
--replace 'fs.copyFileSync("config/server.yml", path);' \
'fs.copyFileSync("config/server.yml", path); fs.chmodSync(path, 0o644);' \
--replace 'fs.copyFileSync("config/tuners.yml", path);' \
'fs.copyFileSync("config/tuners.yml", path); fs.chmodSync(path, 0o644);' \
--replace 'fs.copyFileSync("config/channels.yml", path);' \
'fs.copyFileSync("config/channels.yml", path); fs.chmodSync(path, 0o644);'

# XXX: The original mirakurun command uses PM2 to manage the Mirakurun
# server. However, we invoke the server directly and let systemd
# manage it to avoid complication. This is okay since no features
# unique to PM2 is currently being used.
makeWrapper ${nodejs}/bin/npm $out/bin/mirakurun \
--add-flags "start" \
--run "cd $out/lib/node_modules/mirakurun" \
--prefix PATH : ${pkgs.lib.makeBinPath runtimeDeps}
'';
};

node-inspector = super.node-inspector.override {
buildInputs = [ self.node-pre-gyp ];
meta.broken = since "10";
Expand Down
1 change: 1 addition & 0 deletions pkgs/development/node-packages/node-packages.json
Original file line number Diff line number Diff line change
Expand Up @@ -119,6 +119,7 @@
, "mathjax"
, "meat"
, "meguca"
, "mirakurun"
, "mocha"
, "multi-file-swagger"
, "neovim"
Expand Down
Loading