1{ config, lib, pkgs, ... }:
2
3with lib;
4let
5 cfg = config.services.corosync;
6in
7{
8 # interface
9 options.services.corosync = {
10 enable = mkEnableOption "corosync";
11
12 package = mkPackageOption pkgs "corosync" { };
13
14 clusterName = mkOption {
15 type = types.str;
16 default = "nixcluster";
17 description = "Name of the corosync cluster.";
18 };
19
20 extraOptions = mkOption {
21 type = with types; listOf str;
22 default = [];
23 description = "Additional options with which to start corosync.";
24 };
25
26 nodelist = mkOption {
27 description = "Corosync nodelist: all cluster members.";
28 default = [];
29 type = with types; listOf (submodule {
30 options = {
31 nodeid = mkOption {
32 type = int;
33 description = "Node ID number";
34 };
35 name = mkOption {
36 type = str;
37 description = "Node name";
38 };
39 ring_addrs = mkOption {
40 type = listOf str;
41 description = "List of addresses, one for each ring.";
42 };
43 };
44 });
45 };
46 };
47
48 # implementation
49 config = mkIf cfg.enable {
50 environment.systemPackages = [ cfg.package ];
51
52 environment.etc."corosync/corosync.conf".text = ''
53 totem {
54 version: 2
55 secauth: on
56 cluster_name: ${cfg.clusterName}
57 transport: knet
58 }
59
60 nodelist {
61 ${concatMapStrings ({ nodeid, name, ring_addrs }: ''
62 node {
63 nodeid: ${toString nodeid}
64 name: ${name}
65 ${concatStrings (imap0 (i: addr: ''
66 ring${toString i}_addr: ${addr}
67 '') ring_addrs)}
68 }
69 '') cfg.nodelist}
70 }
71
72 quorum {
73 # only corosync_votequorum is supported
74 provider: corosync_votequorum
75 wait_for_all: 0
76 ${optionalString (builtins.length cfg.nodelist < 3) ''
77 two_node: 1
78 ''}
79 }
80
81 logging {
82 to_syslog: yes
83 }
84 '';
85
86 environment.etc."corosync/uidgid.d/root".text = ''
87 # allow pacemaker connection by root
88 uidgid {
89 uid: 0
90 gid: 0
91 }
92 '';
93
94 systemd.packages = [ cfg.package ];
95 systemd.services.corosync = {
96 wantedBy = [ "multi-user.target" ];
97 serviceConfig = {
98 StateDirectory = "corosync";
99 StateDirectoryMode = "0700";
100 };
101 };
102
103 environment.etc."sysconfig/corosync".text = lib.optionalString (cfg.extraOptions != []) ''
104 COROSYNC_OPTIONS="${lib.escapeShellArgs cfg.extraOptions}"
105 '';
106 };
107}