anchor.diff:      MONGO_URL = cfg.seyren.mongoUrl;
       GRAPHITE_URL = cfg.seyren.graphiteUrl;
     } // cfg.seyren.extraConfig;
  +
  +  pagerConfig = pkgs.writeText "alarms.yaml" cfg.pager.alerts;
   
     configDir = pkgs.buildEnv {
       name = "graphite-config";
  
positive.code:         '';
        };
      };
    };
  
    ###### implementation
  
    config = mkIf (
      cfg.carbon.enableAggregator ||
      cfg.carbon.enableCache ||
      cfg.carbon.enableRelay ||
      cfg.web.enable ||
      cfg.api.enable ||
      cfg.seyren.enable
    ) {
      systemd.services.carbonCache = {
        enable = cfg.carbon.enableCache;
        description = "Graphite Data Storage Backend";
        wantedBy = [ "multi-user.target" ];
        after = [ "network-interfaces.target" ];
        environment = carbonEnv;
        serviceConfig = {
          ExecStart = "${pkgs.twisted}/bin/twistd ${carbonOpts "carbon-cache"}";
          User = "graphite";
          Group = "graphite";
          PermissionsStartOnly = true;
        };
        preStart = ''
          mkdir -p ${cfg.dataDir}/whisper
          chmod 0700 ${cfg.dataDir}/whisper
          chown -R graphite:graphite ${cfg.dataDir}
        '';
      };
  
      systemd.services.carbonAggregator = {
        enable = cfg.carbon.enableAggregator;
        description = "Carbon Data Aggregator";
        wantedBy = [ "multi-user.target" ];
        after = [ "network-interfaces.target" ];
        environment = carbonEnv;
        serviceConfig = {
          ExecStart = "${pkgs.twisted}/bin/twistd ${carbonOpts "carbon-aggregator"}";
          User = "graphite";
          Group = "graphite";
        };
      };
  
      systemd.services.carbonRelay = {
        enable = cfg.carbon.enableRelay;
        description = "Carbon Data Relay";
        wantedBy = [ "multi-user.target" ];
        after = [ "network-interfaces.target" ];
        environment = carbonEnv;
        serviceConfig = {
          ExecStart = "${pkgs.twisted}/bin/twistd ${carbonOpts "carbon-relay"}";
          User = "graphite";
          Group = "graphite";
        };
      };
  
      systemd.services.graphiteWeb = {
        enable = cfg.web.enable;
        description = "Graphite Web Interface";
        wantedBy = [ "multi-user.target" ];
        after = [ "network-interfaces.target" ];
        path = [ pkgs.perl ];
        environment = {
          PYTHONPATH = "${pkgs.python27Packages.graphite_web}/lib/python2.7/site-packages";
          DJANGO_SETTINGS_MODULE = "graphite.settings";
          GRAPHITE_CONF_DIR = configDir;
          GRAPHITE_STORAGE_DIR = dataDir;
        };
        serviceConfig = {
          ExecStart = ''
            ${pkgs.python27Packages.waitress}/bin/waitress-serve \
            --host=${cfg.web.host} --port=${toString cfg.web.port} \
            --call django.core.handlers.wsgi:WSGIHandler'';
          User = "graphite";
          Group = "graphite";
          PermissionsStartOnly = true;
        };
        preStart = ''
          if ! test -e ${dataDir}/db-created; then
            mkdir -p ${dataDir}/{whisper/,log/webapp/}
            chmod 0700 ${dataDir}/{whisper/,log/webapp/}
  
            # populate database
            ${pkgs.python27Packages.graphite_web}/bin/manage-graphite.py syncdb --noinput
  
            # create index
            ${pkgs.python27Packages.graphite_web}/bin/build-index.sh
  
            touch ${dataDir}/db-created
  
            chown -R graphite:graphite ${cfg.dataDir}
          fi
        '';
      };
  
      systemd.services.graphiteApi = {
        enable = cfg.api.enable;
        description = "Graphite Api Interface";
        wantedBy = [ "multi-user.target" ];
        after = [ "network-interfaces.target" ];
        environment = {
          PYTHONPATH =
            "${cfg.api.package}/lib/python2.7/site-packages:" +
            concatMapStringsSep ":" (f: f + "/lib/python2.7/site-packages") cfg.api.finders;
          GRAPHITE_API_CONFIG = graphiteApiConfig;
          LD_LIBRARY_PATH = "${pkgs.cairo}/lib";
        };
        serviceConfig = {
          ExecStart = ''
            ${pkgs.python27Packages.waitress}/bin/waitress-serve \
            --host=${cfg.api.host} --port=${toString cfg.api.port} \
            graphite_api.app:app 
          '';
          User = "graphite";
          Group = "graphite";
          PermissionsStartOnly = true;
        };
        preStart = ''
          if ! test -e ${dataDir}/db-created; then
            mkdir -p ${dataDir}/cache/
            chmod 0700 ${dataDir}/cache/
  
            touch ${dataDir}/db-created
  
            chown -R graphite:graphite ${cfg.dataDir}
          fi
        '';
      };
  
      systemd.services.seyren = {
        enable = cfg.seyren.enable;
        description = "Graphite Alerting Dashboard";
        wantedBy = [ "multi-user.target" ];
        after = [ "network-interfaces.target" "mongodb.service" ];
        environment = seyrenConfig;
        serviceConfig = {
          ExecStart = "${pkgs.seyren}/bin/seyren -httpPort ${toString cfg.seyren.port}";
          WorkingDirectory = dataDir;
          User = "graphite";
          Group = "graphite"; 
        };
        preStart = ''
          if ! test -e ${dataDir}/db-created; then
            mkdir -p ${dataDir}
            chown -R graphite:graphite ${dataDir}
          fi
        '';
      };
  
      services.mongodb.enable = mkDefault cfg.seyren.enable;
  
      environment.systemPackages = [
        pkgs.pythonPackages.carbon
        pkgs.python27Packages.graphite_web
        pkgs.python27Packages.waitress
      ];
  
      users.extraUsers = singleton {
        name = "graphite";
        uid = config.ids.uids.graphite;
        description = "Graphite daemon user";
        home = dataDir;
      };
      users.extraGroups.graphite.gid = config.ids.gids.graphite;
    };
  }
  
negative.code: 
      api = {
        enable = mkOption {
          description = ''
            Whether to enable graphite api. Graphite api is lightweight alternative
            to graphite web, with api and without dashboard. It's advised to use
            grafana as alternative dashboard and influxdb as alternative to
            graphite carbon.
  
            For more information visit
            <link xlink:href="http://graphite.readthedocs.org/en/1.0/index.html"/>
          '';
          default = false;
          type = types.uniq types.bool;
        };
  
        finders = mkOption {
          description = "List of finder plugins to load.";
          default = [];
          example = [ pkgs.python27Packages.graphite_influxdb ];
          type = types.listOf types.package;
  