at 17.09-beta 6.0 kB view raw
1{ config, lib, pkgs, ... }: 2 3with lib; 4 5let 6 cfg = config.services.etcd; 7 8in { 9 10 options.services.etcd = { 11 enable = mkOption { 12 description = "Whether to enable etcd."; 13 default = false; 14 type = types.bool; 15 }; 16 17 name = mkOption { 18 description = "Etcd unique node name."; 19 default = config.networking.hostName; 20 type = types.str; 21 }; 22 23 advertiseClientUrls = mkOption { 24 description = "Etcd list of this member's client URLs to advertise to the rest of the cluster."; 25 default = cfg.listenClientUrls; 26 type = types.listOf types.str; 27 }; 28 29 listenClientUrls = mkOption { 30 description = "Etcd list of URLs to listen on for client traffic."; 31 default = ["http://127.0.0.1:2379"]; 32 type = types.listOf types.str; 33 }; 34 35 listenPeerUrls = mkOption { 36 description = "Etcd list of URLs to listen on for peer traffic."; 37 default = ["http://127.0.0.1:2380"]; 38 type = types.listOf types.str; 39 }; 40 41 initialAdvertisePeerUrls = mkOption { 42 description = "Etcd list of this member's peer URLs to advertise to rest of the cluster."; 43 default = cfg.listenPeerUrls; 44 type = types.listOf types.str; 45 }; 46 47 initialCluster = mkOption { 48 description = "Etcd initial cluster configuration for bootstrapping."; 49 default = ["${cfg.name}=http://127.0.0.1:2380"]; 50 type = types.listOf types.str; 51 }; 52 53 initialClusterState = mkOption { 54 description = "Etcd initial cluster configuration for bootstrapping."; 55 default = "new"; 56 type = types.enum ["new" "existing"]; 57 }; 58 59 initialClusterToken = mkOption { 60 description = "Etcd initial cluster token for etcd cluster during bootstrap."; 61 default = "etcd-cluster"; 62 type = types.str; 63 }; 64 65 discovery = mkOption { 66 description = "Etcd discovery url"; 67 default = ""; 68 type = types.str; 69 }; 70 71 clientCertAuth = mkOption { 72 description = "Whether to use certs for client authentication"; 73 default = false; 74 type = types.bool; 75 }; 76 77 trustedCaFile = mkOption { 78 description = "Certificate authority file to use for clients"; 79 default = null; 80 type = types.nullOr types.path; 81 }; 82 83 certFile = mkOption { 84 description = "Cert file to use for clients"; 85 default = null; 86 type = types.nullOr types.path; 87 }; 88 89 keyFile = mkOption { 90 description = "Key file to use for clients"; 91 default = null; 92 type = types.nullOr types.path; 93 }; 94 95 peerCertFile = mkOption { 96 description = "Cert file to use for peer to peer communication"; 97 default = cfg.certFile; 98 type = types.nullOr types.path; 99 }; 100 101 peerKeyFile = mkOption { 102 description = "Key file to use for peer to peer communication"; 103 default = cfg.keyFile; 104 type = types.nullOr types.path; 105 }; 106 107 peerTrustedCaFile = mkOption { 108 description = "Certificate authority file to use for peer to peer communication"; 109 default = cfg.trustedCaFile; 110 type = types.nullOr types.path; 111 }; 112 113 peerClientCertAuth = mkOption { 114 description = "Whether to check all incoming peer requests from the cluster for valid client certificates signed by the supplied CA"; 115 default = false; 116 type = types.bool; 117 }; 118 119 extraConf = mkOption { 120 description = '' 121 Etcd extra configuration. See 122 <link xlink:href='https://github.com/coreos/etcd/blob/master/Documentation/op-guide/configuration.md#configuration-flags' /> 123 ''; 124 type = types.attrsOf types.str; 125 default = {}; 126 example = literalExample '' 127 { 128 "CORS" = "*"; 129 "NAME" = "default-name"; 130 "MAX_RESULT_BUFFER" = "1024"; 131 "MAX_CLUSTER_SIZE" = "9"; 132 "MAX_RETRY_ATTEMPTS" = "3"; 133 } 134 ''; 135 }; 136 137 dataDir = mkOption { 138 type = types.path; 139 default = "/var/lib/etcd"; 140 description = "Etcd data directory."; 141 }; 142 }; 143 144 config = mkIf cfg.enable { 145 systemd.services.etcd = { 146 description = "etcd key-value store"; 147 wantedBy = [ "multi-user.target" ]; 148 after = [ "network.target" ]; 149 150 environment = (filterAttrs (n: v: v != null) { 151 ETCD_NAME = cfg.name; 152 ETCD_DISCOVERY = cfg.discovery; 153 ETCD_DATA_DIR = cfg.dataDir; 154 ETCD_ADVERTISE_CLIENT_URLS = concatStringsSep "," cfg.advertiseClientUrls; 155 ETCD_LISTEN_CLIENT_URLS = concatStringsSep "," cfg.listenClientUrls; 156 ETCD_LISTEN_PEER_URLS = concatStringsSep "," cfg.listenPeerUrls; 157 ETCD_INITIAL_ADVERTISE_PEER_URLS = concatStringsSep "," cfg.initialAdvertisePeerUrls; 158 ETCD_PEER_TRUSTED_CA_FILE = cfg.peerTrustedCaFile; 159 ETCD_PEER_CERT_FILE = cfg.peerCertFile; 160 ETCD_PEER_KEY_FILE = cfg.peerKeyFile; 161 ETCD_CLIENT_CERT_AUTH = toString cfg.peerClientCertAuth; 162 ETCD_TRUSTED_CA_FILE = cfg.trustedCaFile; 163 ETCD_CERT_FILE = cfg.certFile; 164 ETCD_KEY_FILE = cfg.keyFile; 165 }) // (optionalAttrs (cfg.discovery == ""){ 166 ETCD_INITIAL_CLUSTER = concatStringsSep "," cfg.initialCluster; 167 ETCD_INITIAL_CLUSTER_STATE = cfg.initialClusterState; 168 ETCD_INITIAL_CLUSTER_TOKEN = cfg.initialClusterToken; 169 }) // (mapAttrs' (n: v: nameValuePair "ETCD_${n}" v) cfg.extraConf); 170 171 unitConfig = { 172 Documentation = "https://github.com/coreos/etcd"; 173 }; 174 175 serviceConfig = { 176 Type = "notify"; 177 ExecStart = "${pkgs.etcd.bin}/bin/etcd"; 178 User = "etcd"; 179 PermissionsStartOnly = true; 180 LimitNOFILE = 40000; 181 }; 182 183 preStart = '' 184 mkdir -m 0700 -p ${cfg.dataDir} 185 if [ "$(id -u)" = 0 ]; then chown etcd ${cfg.dataDir}; fi 186 ''; 187 }; 188 189 environment.systemPackages = [ pkgs.etcdctl ]; 190 191 users.extraUsers = singleton { 192 name = "etcd"; 193 uid = config.ids.uids.etcd; 194 description = "Etcd daemon user"; 195 home = cfg.dataDir; 196 }; 197 }; 198}