223 lines
		
	
	
		
			6.5 KiB
		
	
	
	
		
			Nix
		
	
	
	
	
	
		
		
			
		
	
	
			223 lines
		
	
	
		
			6.5 KiB
		
	
	
	
		
			Nix
		
	
	
	
	
	
|   | { config, lib, pkgs, ... }: | ||
|  | 
 | ||
|  | # TODO: support non-postgresql | ||
|  | 
 | ||
|  | with lib; | ||
|  | 
 | ||
|  | let | ||
|  |   cfg = config.services.redmine; | ||
|  | 
 | ||
|  |   ruby = pkgs.ruby; | ||
|  |   rubyLibs = pkgs.rubyLibs; | ||
|  | 
 | ||
|  |   databaseYml = ''
 | ||
|  |     production: | ||
|  |       adapter: postgresql | ||
|  |       database: ${cfg.databaseName} | ||
|  |       host: ${cfg.databaseHost} | ||
|  |       password: ${cfg.databasePassword} | ||
|  |       username: ${cfg.databaseUsername} | ||
|  |       encoding: utf8 | ||
|  |   '';
 | ||
|  | 
 | ||
|  |   configurationYml = ''
 | ||
|  |     default: | ||
|  |       # Absolute path to the directory where attachments are stored. | ||
|  |       # The default is the 'files' directory in your Redmine instance. | ||
|  |       # Your Redmine instance needs to have write permission on this | ||
|  |       # directory. | ||
|  |       # Examples: | ||
|  |       # attachments_storage_path: /var/redmine/files | ||
|  |       # attachments_storage_path: D:/redmine/files | ||
|  |       attachments_storage_path: ${cfg.stateDir}/files | ||
|  | 
 | ||
|  |       # Absolute path to the SCM commands errors (stderr) log file. | ||
|  |       # The default is to log in the 'log' directory of your Redmine instance. | ||
|  |       # Example: | ||
|  |       # scm_stderr_log_file: /var/log/redmine_scm_stderr.log | ||
|  |       scm_stderr_log_file: ${cfg.stateDir}/redmine_scm_stderr.log | ||
|  | 
 | ||
|  |       ${cfg.extraConfig} | ||
|  |   '';
 | ||
|  | 
 | ||
|  |   unpackTheme = unpack "theme"; | ||
|  |   unpackPlugin = unpack "plugin"; | ||
|  |   unpack = id: (name: source: | ||
|  |     pkgs.stdenv.mkDerivation { | ||
|  |       name = "redmine-${id}-${name}"; | ||
|  |       buildInputs = [ pkgs.unzip ]; | ||
|  |       buildCommand = ''
 | ||
|  |         mkdir -p $out | ||
|  |         cd $out | ||
|  |         unpackFile ${source} | ||
|  |       '';
 | ||
|  |     }); | ||
|  | 
 | ||
|  | in { | ||
|  | 
 | ||
|  |   options = { | ||
|  |     services.redmine = { | ||
|  |       enable = mkOption { | ||
|  |         type = types.bool; | ||
|  |         default = false; | ||
|  |         description = ''
 | ||
|  |           Enable the redmine service. | ||
|  |         '';
 | ||
|  |       }; | ||
|  | 
 | ||
|  |       stateDir = mkOption { | ||
|  |         type = types.str; | ||
|  |         default = "/var/redmine"; | ||
|  |         description = "The state directory, logs and plugins are stored here"; | ||
|  |       }; | ||
|  | 
 | ||
|  |       extraConfig = mkOption { | ||
|  |         type = types.str; | ||
|  |         default = ""; | ||
|  |         description = "Extra configuration in configuration.yml"; | ||
|  |       }; | ||
|  | 
 | ||
|  |       themes = mkOption { | ||
|  |         type = types.attrsOf types.path; | ||
|  |         default = {}; | ||
|  |         description = "Set of themes"; | ||
|  |       }; | ||
|  | 
 | ||
|  |       plugins = mkOption { | ||
|  |         type = types.attrsOf types.path; | ||
|  |         default = {}; | ||
|  |         description = "Set of plugins"; | ||
|  |       }; | ||
|  | 
 | ||
|  |       #databaseType = mkOption { | ||
|  |       #  type = types.str; | ||
|  |       #  default = "postgresql"; | ||
|  |       #  description = "Type of database"; | ||
|  |       #}; | ||
|  | 
 | ||
|  |       databaseHost = mkOption { | ||
|  |         type = types.str; | ||
|  |         default = "127.0.0.1"; | ||
|  |         description = "Database hostname"; | ||
|  |       }; | ||
|  | 
 | ||
|  |       databasePassword = mkOption { | ||
|  |         type = types.str; | ||
|  |         default = ""; | ||
|  |         description = "Database user password"; | ||
|  |       }; | ||
|  | 
 | ||
|  |       databaseName = mkOption { | ||
|  |         type = types.str; | ||
|  |         default = "redmine"; | ||
|  |         description = "Database name"; | ||
|  |       }; | ||
|  | 
 | ||
|  |       databaseUsername = mkOption { | ||
|  |         type = types.str; | ||
|  |         default = "redmine"; | ||
|  |         description = "Database user"; | ||
|  |       }; | ||
|  |     }; | ||
|  |   }; | ||
|  | 
 | ||
|  |   config = mkIf cfg.enable { | ||
|  | 
 | ||
|  |     assertions = [ | ||
|  |       { assertion = cfg.databasePassword != ""; | ||
|  |         message = "databasePassword must be set"; | ||
|  |       } | ||
|  |     ]; | ||
|  | 
 | ||
|  |     users.extraUsers = [ | ||
|  |       { name = "redmine"; | ||
|  |         group = "redmine"; | ||
|  |         uid = config.ids.uids.redmine; | ||
|  |       } ]; | ||
|  | 
 | ||
|  |     users.extraGroups = [ | ||
|  |       { name = "redmine"; | ||
|  |         gid = config.ids.gids.redmine; | ||
|  |       } ]; | ||
|  | 
 | ||
|  |     systemd.services.redmine = { | ||
|  |       after = [ "network.target" "postgresql.service" ]; | ||
|  |       wantedBy = [ "multi-user.target" ]; | ||
|  |       environment.RAILS_ENV = "production"; | ||
|  |       environment.RAILS_ETC = "${cfg.stateDir}/config"; | ||
|  |       environment.RAILS_LOG = "${cfg.stateDir}/log"; | ||
|  |       environment.RAILS_VAR = "${cfg.stateDir}/var"; | ||
|  |       environment.RAILS_CACHE = "${cfg.stateDir}/cache"; | ||
|  |       environment.RAILS_PLUGINS = "${cfg.stateDir}/plugins"; | ||
|  |       environment.RAILS_PUBLIC = "${cfg.stateDir}/public"; | ||
|  |       environment.RAILS_TMP = "${cfg.stateDir}/tmp"; | ||
|  |       environment.SCHEMA = "${cfg.stateDir}/cache/schema.db"; | ||
|  |       environment.HOME = "${pkgs.redmine}/share/redmine"; | ||
|  |       environment.REDMINE_LANG = "en"; | ||
|  |       environment.GEM_HOME = "${pkgs.redmine}/share/redmine/vendor/bundle/ruby/1.9.1"; | ||
|  |       environment.GEM_PATH = "${rubyLibs.bundler}/lib/ruby/gems/1.9"; | ||
|  |       path = with pkgs; [ | ||
|  |         imagemagickBig | ||
|  |         subversion | ||
|  |         mercurial | ||
|  |         cvs | ||
|  |         config.services.postgresql.package | ||
|  |         bazaar | ||
|  |         gitAndTools.git | ||
|  |         # once we build binaries for darc enable it | ||
|  |         #darcs | ||
|  |       ]; | ||
|  |       preStart = ''
 | ||
|  |         # TODO: use env vars | ||
|  |         for i in plugins public/plugin_assets db files log config cache var/files tmp; do | ||
|  |           mkdir -p ${cfg.stateDir}/$i | ||
|  |         done | ||
|  | 
 | ||
|  |         chown -R redmine:redmine ${cfg.stateDir} | ||
|  |         chmod -R 755 ${cfg.stateDir} | ||
|  | 
 | ||
|  |         rm -rf ${cfg.stateDir}/public/*
 | ||
|  |         cp -R ${pkgs.redmine}/share/redmine/public/* ${cfg.stateDir}/public/
 | ||
|  |         for theme in ${concatStringsSep " " (mapAttrsToList unpackTheme cfg.themes)}; do | ||
|  |           ln -fs $theme/* ${cfg.stateDir}/public/themes/
 | ||
|  |         done | ||
|  | 
 | ||
|  |         rm -rf ${cfg.stateDir}/plugins/*
 | ||
|  |         for plugin in ${concatStringsSep " " (mapAttrsToList unpackPlugin cfg.plugins)}; do | ||
|  |           ln -fs $plugin/* ${cfg.stateDir}/plugins/''${plugin##*-redmine-plugin-}
 | ||
|  |         done | ||
|  | 
 | ||
|  |         ln -fs ${pkgs.writeText "database.yml" databaseYml} ${cfg.stateDir}/config/database.yml | ||
|  |         ln -fs ${pkgs.writeText "configuration.yml" configurationYml} ${cfg.stateDir}/config/configuration.yml | ||
|  | 
 | ||
|  |         if [ "${cfg.databaseHost}" = "127.0.0.1" ]; then | ||
|  |           if ! test -e "${cfg.stateDir}/db-created"; then | ||
|  |             psql postgres -c "CREATE ROLE redmine WITH LOGIN NOCREATEDB NOCREATEROLE NOCREATEUSER ENCRYPTED PASSWORD '${cfg.databasePassword}'" | ||
|  |             ${config.services.postgresql.package}/bin/createdb --owner redmine redmine || true | ||
|  |             touch "${cfg.stateDir}/db-created" | ||
|  |           fi | ||
|  |         fi | ||
|  | 
 | ||
|  |         cd ${pkgs.redmine}/share/redmine/ | ||
|  |         ${ruby}/bin/rake db:migrate | ||
|  |         ${ruby}/bin/rake redmine:plugins:migrate | ||
|  |         ${ruby}/bin/rake redmine:load_default_data | ||
|  |         ${ruby}/bin/rake generate_secret_token | ||
|  |       '';
 | ||
|  | 
 | ||
|  |       serviceConfig = { | ||
|  |         PermissionsStartOnly = true; # preStart must be run as root | ||
|  |         Type = "simple"; | ||
|  |         User = "redmine"; | ||
|  |         Group = "redmine"; | ||
|  |         TimeoutSec = "300"; | ||
|  |         WorkingDirectory = "${pkgs.redmine}/share/redmine"; | ||
|  |         ExecStart="${ruby}/bin/ruby ${pkgs.redmine}/share/redmine/script/rails server webrick -e production -P ${cfg.stateDir}/redmine.pid"; | ||
|  |       }; | ||
|  | 
 | ||
|  |     }; | ||
|  | 
 | ||
|  |   }; | ||
|  | 
 | ||
|  | } |