diff --git a/README.md b/README.md index 3637db8..68bb192 100644 --- a/README.md +++ b/README.md @@ -1,31 +1,124 @@ Role Name ========= -A brief description of the role goes here. - -Requirements ------------- - -Any pre-requisites that may not be covered by Ansible itself or the role should be mentioned here. For instance, if the role uses the EC2 module, it may be a good idea to mention in this section that the boto package is required. +A role that that installs Redmine and some of its plugins. Role Variables -------------- -A description of the settable variables for this role should go here, including any variables that are in defaults/main.yml, vars/main.yml, and any variables that can/should be set via parameters to the role. Any variables that are read from other roles and/or the global scope (ie. hostvars, group vars, etc.) should be mentioned here as well. +The most important variables are listed below: + +``` yaml +redmine_version: 4.0.1 +redmine_inst_name: redmine +redmine_main_project: redmine +redmine_db_user: redm_db_user +redmine_db_name: redm_db_name +redmine_db_host: localhost +# The commented variables need to be set on the playbooks +#redmine_glob_root_dir: /srv/redmine +# It is a redmine_glob_root_dir subdirectory +redmine_inst_dir: redmine +redmine_user: redmine +redmine_group: '{{ redmine_user }}' + +# Ubuntu 14.04: install ruby from a ppa to get a newer version +redmine_trusty_ruby_repo: 'ppa:brightbox/ruby-ng' +trusty_ruby_version: 2.3 + +redmine_sysvinit_service_name: '{{ redmine_inst_name }}' +redmine_systemd_service_name: 'unicorn@{{ redmine_inst_name }}.service' +redmine_service_name: '{{ redmine_systemd_service_name }}' + +redmine_log_level: warn +# Minutes, from 1 to 60 +redmine_ldap_sync_freq: 10 +# users, groups, all +redmine_ldap_sync_who: all + +redmine_glob_user: www-data +redmine_glob_group: www-data +redmine_glob_users_home_base: /srv/redmine-home + +redmine_imap_sync: False +redmine_imap_server: localhost +redmine_imap_user: '' +#redmine_imap_password: 'Use a vault file' +redmine_imap_unknown_user_action: ignore +redmine_imap_starttls: true +redmine_imap_sync_additional_options: '' + +# Plugins +rm_ldap_auth: False +rm_ldap_synch: False +rm_better_gant_plugin: False +rm_login_audit_plugin: False +rm_progressive_projects_plugin: False +rm_didyoumean_plugin: False +rm_graphs_plugin: False +rm_embedded_tabs_plugin: False +rm_recurring_tasks_plugin: False +redmine_install_agile_plugin: False +rm_scrum_plugin: False +rm_advanced_roadmap_plugin: False +rm_scrum2b_plugin: False +rm_autowatcher_plugin: False +rm_issuereminder_plugin: False +rm_issue_reminder_plugin_freq_min: 0 +rm_issue_reminder_plugin_freq_hour: 5 +rm_issue_reminder_plugin_freq_weekday: 1 +# https://github.com/arkhitech/redmine_update_reminder +# We configure to send the email reminders once a week on monday morning by default +rm_updatereminder_plugin: False +rm_updatereminder_plugin_freq_min: 0 +rm_updatereminder_plugin_freq_hour: 5 +rm_updatereminder_plugin_freq_weekday: 1 +rm_mention_plugin: False +rm_mentions_plugin: False +rm_defaultcustomquery_plugin: False +rm_gamification_plugin: False +rm_closesresolvedissue_plugin: False +rm_defaultassign_plugin: False +rm_onceassignedeverwatcher_plugin: False +rm_clipboardimagepaste_plugin: False +rm_hotkeysjs_plugin: False +rm_issuessorting_plugin: False +rm_mylyn_plugin: False +rm_quickedit_plugin: False +rm_quickview_plugin: False +rm_codereview_plugin: False +rm_globalroles_plugin: False +rm_unreadissues_plugin: False +rm_usability_plugin: False +rm_mylynconnector_plugin: False +rm_addsubversionlinks_plugin: False +rm_wiki_external_plugin: False +rm_pastebin_plugin: False +rm_issue_templates_plugin: False +# TODO lists plugin: https://redmine.org/plugins/redmine_issue_todo_lists +rm_issue_todo_lists_plugin: False +# +# IMPORTANT: these are mutually exclusive. One of the two needs to be set to True +ruby_use_mod_passenger: False +ruby_use_unicorn: True +# Redmine 2.x only +rm_involvement_plugin: False +rm_omniauth_plugin: False + +# Used by unicorn +unicorn_listen_port: 4000 +unicorn_listen_address: 127.0.0.1 +unicorn_worker_processes: 5 +unicorn_timeout: 120 +unicorn_log_dir: /var/log/unicorn +unicorn_pid_dir: '{{ unicorn_log_dir }}' +unicorn_pid_file: '{{ unicorn_pid_dir }}/unicorn.pid' +``` Dependencies ------------ -A list of other roles hosted on Galaxy should go here, plus any details in regards to parameters that may need to be set for other roles, or variables that are used from other roles. - -Example Playbook ----------------- - -Including an example of how to use your role (for instance, with variables passed in as parameters) is always nice for users too: - - - hosts: servers - roles: - - { role: username.rolename, x: 42 } +None License ------- @@ -35,4 +128,4 @@ EUPL-1.2 Author Information ------------------ -An optional section for the role authors to include contact information, or a website (HTML is not allowed). +Andrea Dell'Amico, diff --git a/defaults/main.yml b/defaults/main.yml index 95d3c70..c9ee644 100644 --- a/defaults/main.yml +++ b/defaults/main.yml @@ -1,2 +1,108 @@ --- -# defaults file for ansible-role-template \ No newline at end of file +redmine_version: 4.0.1 +redmine_inst_name: redmine +redmine_main_project: redmine +redmine_db_user: redm_db_user +redmine_db_name: redm_db_name +redmine_db_host: localhost +# The commented variables need to be set on the playbooks +#redmine_glob_root_dir: /srv/redmine +# It is a redmine_glob_root_dir subdirectory +redmine_inst_dir: redmine +redmine_user: redmine +redmine_group: '{{ redmine_user }}' + +# Ubuntu 14.04: install ruby from a ppa to get a newer version +redmine_trusty_ruby_repo: 'ppa:brightbox/ruby-ng' +trusty_ruby_version: 2.3 + +redmine_sysvinit_service_name: '{{ redmine_inst_name }}' +redmine_systemd_service_name: 'unicorn@{{ redmine_inst_name }}.service' +redmine_service_name: '{{ redmine_systemd_service_name }}' + +redmine_log_level: warn +# Minutes, from 1 to 60 +redmine_ldap_sync_freq: 10 +# users, groups, all +redmine_ldap_sync_who: all + +redmine_glob_user: www-data +redmine_glob_group: www-data +redmine_glob_users_home_base: /srv/redmine-home + +redmine_imap_sync: False +redmine_imap_server: localhost +redmine_imap_user: '' +#redmine_imap_password: 'Use a vault file' +redmine_imap_unknown_user_action: ignore +redmine_imap_starttls: true +redmine_imap_sync_additional_options: '' + +# Plugins +rm_ldap_auth: False +rm_ldap_synch: False +rm_better_gant_plugin: False +rm_login_audit_plugin: False +rm_progressive_projects_plugin: False +rm_didyoumean_plugin: False +rm_graphs_plugin: False +rm_embedded_tabs_plugin: False +rm_recurring_tasks_plugin: False +redmine_install_agile_plugin: False +rm_scrum_plugin: False +rm_advanced_roadmap_plugin: False +rm_scrum2b_plugin: False +rm_autowatcher_plugin: False +rm_issuereminder_plugin: False +rm_issue_reminder_plugin_freq_min: 0 +rm_issue_reminder_plugin_freq_hour: 5 +rm_issue_reminder_plugin_freq_weekday: 1 +# https://github.com/arkhitech/redmine_update_reminder +# We configure to send the email reminders once a week on monday morning by default +rm_updatereminder_plugin: False +rm_updatereminder_plugin_freq_min: 0 +rm_updatereminder_plugin_freq_hour: 5 +rm_updatereminder_plugin_freq_weekday: 1 +rm_mention_plugin: False +rm_mentions_plugin: False +rm_defaultcustomquery_plugin: False +rm_gamification_plugin: False +rm_closesresolvedissue_plugin: False +rm_defaultassign_plugin: False +rm_onceassignedeverwatcher_plugin: False +rm_clipboardimagepaste_plugin: False +rm_hotkeysjs_plugin: False +rm_issuessorting_plugin: False +rm_mylyn_plugin: False +rm_quickedit_plugin: False +rm_quickview_plugin: False +rm_codereview_plugin: False +rm_globalroles_plugin: False +rm_unreadissues_plugin: False +rm_usability_plugin: False +rm_mylynconnector_plugin: False +rm_addsubversionlinks_plugin: False +rm_wiki_external_plugin: False +rm_pastebin_plugin: False +rm_issue_templates_plugin: False +# TODO lists plugin: https://redmine.org/plugins/redmine_issue_todo_lists +rm_issue_todo_lists_plugin: False +# +# IMPORTANT: these are mutually exclusive. One of the two needs to be set to True +ruby_use_mod_passenger: False +ruby_use_unicorn: True +# Redmine 2.x only +rm_involvement_plugin: False +rm_omniauth_plugin: False + +# Used by unicorn +unicorn_listen_port: 4000 +unicorn_listen_address: 127.0.0.1 +unicorn_worker_processes: 5 +unicorn_timeout: 120 +unicorn_log_dir: /var/log/unicorn +unicorn_pid_dir: '{{ unicorn_log_dir }}' +unicorn_pid_file: '{{ unicorn_pid_dir }}/unicorn.pid' + +redmine_additional_gems: [] + diff --git a/files/a1-theme.zip b/files/a1-theme.zip new file mode 100644 index 0000000..104fb52 Binary files /dev/null and b/files/a1-theme.zip differ diff --git a/files/circle-theme.zip b/files/circle-theme.zip new file mode 100644 index 0000000..bdb8e4b Binary files /dev/null and b/files/circle-theme.zip differ diff --git a/files/global_roles.zip b/files/global_roles.zip new file mode 100644 index 0000000..1bee29d Binary files /dev/null and b/files/global_roles.zip differ diff --git a/files/mod-passenger.load b/files/mod-passenger.load new file mode 100644 index 0000000..502a02e --- /dev/null +++ b/files/mod-passenger.load @@ -0,0 +1,3 @@ +LoadModule passenger_module /var/lib/gems/1.9.1/gems/passenger-4.0.21/buildout/apache2/mod_passenger.so +PassengerRoot /var/lib/gems/1.9.1/gems/passenger-4.0.21 +PassengerDefaultRuby /usr/bin/ruby1.9.1 diff --git a/files/redmine.init b/files/redmine.init new file mode 100644 index 0000000..ea0df4b --- /dev/null +++ b/files/redmine.init @@ -0,0 +1,61 @@ +#! /bin/bash + +### BEGIN INIT INFO +# Provides: unicorn +# Required-Start: $local_fs $remote_fs $network $syslog +# Required-Stop: $local_fs $remote_fs $network $syslog +# Default-Start: 2 3 4 5 +# Default-Stop: 0 1 6 +# Short-Description: starts the unicorn web server +# Description: starts unicorn +### END INIT INFO +APP= +USER= +DAEMON=unicorn +DAEMON_OPTS="-c $APP/config/unicorn.rb -E production -D" +NAME=unicorn +DESC="Unicorn app for $USER" +PID_DIR=/run/unicorn +PID=${PID_DIR}/unicorn.pid + +if [ -f /etc/default/unicorn-redmine ] ; then + . /etc/default/unicorn-redmine +fi + +case "$1" in + start) + CD_TO_APP_DIR="cd $APP" + START_DAEMON_PROCESS="bundle exec $DAEMON $DAEMON_OPTS" + + mkdir -p ${PID_DIR} + chown ${USER}:${USER} ${PID_DIR} + echo -n "Starting $DESC: " + if [ `whoami` = root ]; then + su - $USER -c "$CD_TO_APP_DIR > /dev/null 2>&1 && $START_DAEMON_PROCESS" + else + $CD_TO_APP_DIR > /dev/null 2>&1 && $START_DAEMON_PROCESS + fi + echo "$NAME." + ;; + stop) + echo -n "Stopping $DESC: " + kill -QUIT `cat $PID` + echo "$NAME." + ;; + restart) + echo -n "Restarting $DESC: " + kill -USR2 `cat $PID` + echo "$NAME." + ;; + reload) + echo -n "Reloading $DESC configuration: " + kill -HUP `cat $PID` + echo "$NAME." + ;; + *) + echo "Usage: $NAME {start|stop|restart|reload}" >&2 + exit 1 + ;; +esac + +exit 0 diff --git a/files/redmine_agile.zip b/files/redmine_agile.zip new file mode 100644 index 0000000..b55af89 Binary files /dev/null and b/files/redmine_agile.zip differ diff --git a/files/unread_issues.zip b/files/unread_issues.zip new file mode 100644 index 0000000..5099ea0 Binary files /dev/null and b/files/unread_issues.zip differ diff --git a/files/usability.zip b/files/usability.zip new file mode 100644 index 0000000..7507c4e Binary files /dev/null and b/files/usability.zip differ diff --git a/handlers/main.yml b/handlers/main.yml index 27474e0..29bc5a8 100644 --- a/handlers/main.yml +++ b/handlers/main.yml @@ -1,2 +1,69 @@ --- -# handlers file for ansible-role-template \ No newline at end of file +- name: apache2 reload + service: name=apache2 state=reloaded + when: ruby_use_mod_passenger + +- name: apache2 reload when needed + service: name=apache2 state=reloaded + when: ruby_use_mod_passenger + +- name: Reload unicorn + service: name={{ redmine_sysvinit_service_name }} state=reloaded + when: ansible_service_mgr != 'systemd' + +- name: Reload unicorn + service: name={{ redmine_systemd_service_name }} state=reloaded + when: ansible_service_mgr == 'systemd' + +- name: Reload unicorn when needed + service: name={{ redmine_sysvinit_service_name }} state=restarted + when: + - ruby_use_unicorn + - ansible_service_mgr != 'systemd' + +- name: Reload unicorn when needed + service: name={{ redmine_systemd_service_name }} state=restarted + when: + - ruby_use_unicorn + - ansible_service_mgr == 'systemd' + +- name: Reconfigure redmine + shell: cd {{ redmine_glob_root_dir }}/{{ redmine_inst_dir }}; bundle exec rake redmine:plugins:migrate RAILS_ENV=production + notify: + - apache2 reload when needed + - Reload unicorn when needed + +- name: Reconfigure agile plugin + shell: cd {{ redmine_glob_root_dir }}/{{ redmine_inst_dir }}; bundle exec rake redmine:plugins NAME=redmine_agile RAILS_ENV=production + notify: + - apache2 reload when needed + - Reload unicorn when needed + +- name: Bundle install + shell: cd {{ redmine_glob_root_dir }}/{{ redmine_inst_dir }}; bundle install --without development test mysql RAILS_ENV=production + notify: + - apache2 reload when needed + - Reload unicorn when needed + +- name: Bundle install and reconfigure redmine + shell: cd {{ redmine_glob_root_dir }}/{{ redmine_inst_dir }}; bundle install ; bundle exec rake redmine:plugins:migrate RAILS_ENV=production + notify: + - apache2 reload when needed + - Reload unicorn when needed + +- name: Remove a plugin and reconfigure redmine + shell: cd {{ redmine_glob_root_dir }}/{{ redmine_inst_dir }}; bundle exec rake redmine:plugins:migrate NAME=redmine_plugin_name VERSION=0 RAILS_ENV=production + notify: + - apache2 reload when needed + - Reload unicorn when needed + +- name: Generate the mod-passenger executable + shell: passenger-install-apache2-module -a + when: ruby_use_mod_passenger + +- name: change the redmine permissions recursively + shell: chown -R {{ redmine_user }}:{{ redmine_group }} {{ redmine_glob_root_dir }}/{{ redmine_inst_dir }}/files {{ redmine_glob_root_dir }}/{{ redmine_inst_dir }}/log {{ redmine_glob_root_dir }}/{{ redmine_inst_dir }}/tmp {{ redmine_glob_root_dir }}/{{ redmine_inst_dir }}/public/plugin_assets + ignore_errors: True + +- name: Reload systemd after the system unit installation + systemd: daemon_reload=yes diff --git a/meta/main.yml b/meta/main.yml index 1126a5e..84a5a62 100644 --- a/meta/main.yml +++ b/meta/main.yml @@ -1,61 +1,35 @@ galaxy_info: - author: your name - description: your description + author: Andrea Dell'Amico + description: Systems Architect company: ISTI-CNR - # If the issue tracker for your role is not on github, uncomment the - # next line and provide a value issue_tracker_url: https://redmine-s2i2s.isti.cnr.it/projects/provisioning - # Some suggested licenses: - # - BSD (default) - # - MIT - # - GPLv2 - # - GPLv3 - # - Apache - # - CC-BY - license: EUPL-1.2 + license: EUPL 1.2+ min_ansible_version: 2.8 - # If this a Container Enabled role, provide the minimum Ansible Container version. - # min_ansible_container_version: - - # Optionally specify the branch Galaxy will use when accessing the GitHub - # repo for this role. During role install, if no tags are available, - # Galaxy will use this branch. During import Galaxy will access files on - # this branch. If Travis integration is configured, only notifications for this - # branch will be accepted. Otherwise, in all cases, the repo's default branch - # (usually master) will be used. - #github_branch: - - # - # Provide a list of supported platforms, and for each platform a list of versions. - # If you don't wish to enumerate all versions for a particular platform, use 'all'. # To view available platforms and versions (or releases), visit: # https://galaxy.ansible.com/api/v1/platforms/ # - # platforms: - # - name: Fedora - # versions: - # - all - # - 25 - # - name: SomePlatform - # versions: - # - all - # - 1.0 - # - 7 - # - 99.99 + platforms: + - name: Ubuntu + versions: + - bionic - galaxy_tags: [] - # List tags for your role here, one per line. A tag is a keyword that describes - # and categorizes the role. Users find roles by searching for tags. Be sure to - # remove the '[]' above, if you add tags to this list. - # - # NOTE: A tag is limited to a single word comprised of alphanumeric characters. - # Maximum 20 tags per role. + galaxy_tags: + - redmine + +dependencies: + - src: git+https://gitea-s2i2s.isti.cnr.it/ISTI-ansible-roles/ansible-role-apache.git + version: master + name: apache + state: latest + when: ruby_use_mod_passenger + - src: git+https://gitea-s2i2s.isti.cnr.it/ISTI-ansible-roles/ansible-role-nginx.git + version: master + name: nginx + state: latest + when: ruby_use_unicorn -dependencies: [] - # List your role dependencies here, one per line. Be sure to remove the '[]' above, - # if you add dependencies to this list. diff --git a/tasks/base-config.yml b/tasks/base-config.yml new file mode 100644 index 0000000..ed3ef4c --- /dev/null +++ b/tasks/base-config.yml @@ -0,0 +1,11 @@ +--- +- name: Load the required apache modules + apache2_module: name={{ item }} state=present + with_items: '{{ redmine_base_apache_modules }}' + notify: apache2 reload + tags: [ 'apache', 'redmine' ] + +- name: Ensure that the apache ssl directory exists + file: dest=/etc/apache2/ssl state=directory owner=root group=root mode=0750 + tags: [ 'apache', 'redmine' ] + diff --git a/tasks/deb-packages.yml b/tasks/deb-packages.yml new file mode 100644 index 0000000..71b388a --- /dev/null +++ b/tasks/deb-packages.yml @@ -0,0 +1,18 @@ +--- +- block: + - name: Install a PPA on trusty to get a newer version of ruby + apt_repository: repo={{ redmine_trusty_ruby_repo }} state=present update_cache=yes + + - name: Install the packages needed to run the redmine infrastructure. install the ruby packages needed to run redmine, Ubuntu Trusty + apt: pkg={{ redmine_base_packages }} state=present cache_valid_time=1800 + + when: ansible_distribution_version is version_compare('14.04', '==') + tags: [ 'ruby', 'redmine' ] + +- block: + - name: Install the packages needed to run the redmine infrastructure. install the ruby packages needed to run redmine, Ubuntu Bionic + apt: pkg={{ redmine_bionic_packages }} state=present cache_valid_time=1800 + + when: ansible_distribution_version is version_compare('18.04', '==') + tags: [ 'ruby', 'redmine' ] + diff --git a/tasks/main.yml b/tasks/main.yml index 53c6cae..7864225 100644 --- a/tasks/main.yml +++ b/tasks/main.yml @@ -1,2 +1,22 @@ --- -# tasks file for ansible-role-template \ No newline at end of file +- import_tasks: deb-packages.yml + when: ansible_distribution_file_variety == "Debian" +- import_tasks: rubygems.yml + when: ansible_distribution_file_variety == "Debian" +- import_tasks: redmine.yml + when: ansible_distribution_file_variety == "Debian" +- import_tasks: redmine-plugins.yml + when: ansible_distribution_file_variety == "Debian" +- import_tasks: base-config.yml + when: + - ruby_use_mod_passenger + - ansible_distribution_file_variety == "Debian" +- import_tasks: mod_passenger.yml + when: + - ruby_use_mod_passenger + - ansible_distribution_file_variety == "Debian" +- import_tasks: unicorn.yml + when: + - ruby_use_unicorn + - ansible_distribution_file_variety == "Debian" + diff --git a/tasks/mod_passenger.yml b/tasks/mod_passenger.yml new file mode 100644 index 0000000..861bfd3 --- /dev/null +++ b/tasks/mod_passenger.yml @@ -0,0 +1,24 @@ +--- +- name: Install the phusion passenger repo key + apt_key: id=561F9B9CAC40B2F7 keyserver=keyserver.ubuntu.com state=present + register: update_apt_cache + when: ruby_use_mod_passenger + tags: [ 'ruby', 'redmine', 'passenger' ] + +- name: Install the phusion passenger repo + apt_repository: repo='deb https://oss-binaries.phusionpassenger.com/apt/passenger {{ ansible_distribution_release }} main' state=present update_cache=yes + when: ruby_use_mod_passenger + tags: [ 'ruby', 'redmine', 'passenger' ] + +- name: Install the apache mod_passenger package + apt: pkg=libapache2-mod-passenger state=present + when: ruby_use_mod_passenger + notify: apache2 reload + tags: [ 'ruby', 'redmine', 'passenger' ] + +- name: Install the mod-passenger configuration + apache2_module: name=passenger state=present + when: ruby_use_mod_passenger + notify: apache2 reload + tags: [ 'ruby', 'redmine', 'passenger' ] + diff --git a/tasks/redmine-plugins.yml b/tasks/redmine-plugins.yml new file mode 100644 index 0000000..5240676 --- /dev/null +++ b/tasks/redmine-plugins.yml @@ -0,0 +1,334 @@ +--- +# +# Plugins +# +- name: Create the directory where the plugins are downloaded + file: dest={{ redmine_glob_root_dir }}/plugins_download state=directory + tags: [ 'redmine', 'redmine_plugins' ] + +- name: Redmine better gantt plugin + get_url: url=https://github.com/kulesa/redmine_better_gantt_chart/releases/download/v.0.9.0/redmine_better_gantt_chart_0.9.0.zip dest={{ redmine_glob_root_dir }}/plugins_download/redmine_better_gantt_chart_0.9.0.zip + when: rm_better_gant_plugin + tags: [ 'redmine', 'redmine_plugins' ] + +- name: Install the better gantt plugin + unarchive: src={{ redmine_glob_root_dir }}/plugins_download/redmine_better_gantt_chart_0.9.0.zip dest={{ redmine_glob_root_dir }}/{{ redmine_inst_dir }}/plugins copy=no owner=root group=root creates={{ redmine_glob_root_dir }}/{{ redmine_inst_dir }}/plugins/redmine_better_gantt_chart/init.rb + notify: + - apache2 reload when needed + - Reload unicorn when needed + when: rm_better_gant_plugin + tags: [ 'redmine', 'redmine_plugins' ] + +- name: Install the ldap sync plugin + git: repo=https://github.com/thorin/redmine_ldap_sync.git dest={{ redmine_glob_root_dir }}/{{ redmine_inst_dir }}/plugins/redmine_ldap_sync update=no + notify: + - Bundle install and reconfigure redmine + when: rm_ldap_synch + tags: [ 'redmine', 'redmine_plugins', 'rm_ldap_synch' ] + +- name: Cron job that manages the ldap synch + template: src=redmine-ldap-sync.cron.j2 dest=/etc/cron.d/redmine-ldap-sync owner=root group=root mode=0444 + when: rm_ldap_synch + tags: [ 'redmine', 'redmine_plugins', 'rm_ldap_synch' ] + +- name: Redmine login audit plugin + git: repo=https://github.com/martin-denizet/redmine_login_audit.git dest={{ redmine_glob_root_dir }}/{{ redmine_inst_dir }}/plugins/redmine_login_audit update=no + notify: + - Reconfigure redmine + when: rm_login_audit_plugin + tags: [ 'redmine', 'redmine_plugins' ] + +- name: Redmine subversion links plugin + git: repo=https://github.com/masamitsu-murase/redmine_add_subversion_links.git dest={{ redmine_glob_root_dir }}/{{ redmine_inst_dir }}/plugins/redmine_add_subversion_links update=no + when: rm_addsubversionlinks_plugin + notify: + - apache2 reload when needed + - Reload unicorn when needed + tags: [ 'redmine', 'redmine_plugins' ] + +- name: Progressive projects list plugin + git: repo=https://github.com/stgeneral/redmine-progressive-projects-list.git dest={{ redmine_glob_root_dir }}/{{ redmine_inst_dir }}/plugins/progressive_projects_list update=no + notify: + - Reconfigure redmine + when: rm_progressive_projects_plugin + tags: [ 'redmine', 'redmine_plugins' ] + +- name: didyoumean plugin + git: repo=https://github.com/abahgat/redmine_didyoumean.git dest={{ redmine_glob_root_dir }}/{{ redmine_inst_dir }}/plugins/redmine_didyoumean update=no + notify: + - Reconfigure redmine + when: rm_didyoumean_plugin + tags: [ 'redmine', 'redmine_plugins' ] + +- name: Install the graphs plugin + git: repo=https://github.com/bradbeattie/redmine-graphs-plugin.git dest={{ redmine_glob_root_dir }}/{{ redmine_inst_dir }}/plugins/redmine_graphs update=no + notify: + - Reconfigure redmine + when: rm_graphs_plugin + tags: [ 'redmine', 'redmine_plugins' ] + +- name: Install the embedded tab plugin + git: repo=https://github.com/jamtur01/redmine_tab.git dest={{ redmine_glob_root_dir }}/{{ redmine_inst_dir }}/plugins/redmine_tab update=no + notify: + - apache2 reload when needed + - Reload unicorn when needed + when: rm_embedded_tabs_plugin + tags: [ 'redmine', 'redmine_plugins', 'rm_embedded_tabs' ] + +- name: Install the recurring-tasks plugin + git: repo=https://github.com/nutso/redmine-plugin-recurring-tasks.git dest={{ redmine_glob_root_dir }}/{{ redmine_inst_dir }}/plugins/recurring_tasks update=no + notify: + - Bundle install and reconfigure redmine + when: rm_recurring_tasks_plugin + tags: [ 'redmine', 'redmine_plugins', 'rm_recurring_tasks' ] + +- name: Cron job that manages the recurring tasks + template: src=redmine-recurring-tasks.cron.j2 dest=/etc/cron.d/redmine-recurring-tasks owner=root group=root mode=0444 + when: rm_recurring_tasks_plugin + tags: [ 'redmine', 'redmine_plugins', 'rm_recurring_tasks' ] + +- name: Redmine agile plugin. Free version from www.redminecrm.com + unarchive: src=redmine_agile.zip dest={{ redmine_glob_root_dir }}/{{ redmine_inst_dir }}/plugins creates={{ redmine_glob_root_dir }}/{{ redmine_inst_dir }}/plugins/redmine_agile/init.rb + when: redmine_install_agile_plugin + notify: + - Reconfigure agile plugin + - Bundle install + tags: [ 'redmine', 'redmine_plugins' ] + +- name: Get the scrum plugin + get_url: url=https://redmine.ociotec.com/attachments/download/302/scrum%20v0.9.1.tar.gz dest={{ redmine_glob_root_dir }}/plugins_download/scrum_v0.9.1.tar.gz validate_certs=no + when: rm_scrum_plugin + tags: [ 'redmine', 'redmine_plugins' ] + +- name: Unarchive the scrum plugin + unarchive: src={{ redmine_glob_root_dir }}/plugins_download/scrum_v0.9.1.tar.gz dest={{ redmine_glob_root_dir }}/{{ redmine_inst_dir }}/plugins copy=no owner=root group=root creates={{ redmine_glob_root_dir }}/{{ redmine_inst_dir }}/plugins/scrum/init.rb + when: rm_scrum_plugin + tags: [ 'redmine', 'redmine_plugins' ] + +- name: Rename the scrum plugin + shell: mv "{{ redmine_glob_root_dir }}/{{ redmine_inst_dir }}/plugins/scrum v0.9.1" {{ redmine_glob_root_dir }}/{{ redmine_inst_dir }}/plugins/scrum creates={{ redmine_glob_root_dir }}/{{ redmine_inst_dir }}/plugins/scrum/init.rb + when: rm_scrum_plugin + notify: + - Bundle install and reconfigure redmine + tags: [ 'redmine', 'redmine_plugins' ] + +- name: Install the redmine advanced roadmap plugin + git: repo=https://github.com/Coren/redmine_advanced_roadmap_v2.git dest={{ redmine_glob_root_dir }}/{{ redmine_inst_dir }}/plugins/advanced_roadmap_v2 update=no + when: rm_advanced_roadmap_plugin + notify: + - Bundle install and reconfigure redmine + tags: [ 'redmine', 'redmine_plugins', 'redmine_plugins_ar' ] + +- name: Install the redmine scrum2b plugin + git: repo=https://github.com/scrum2b/scrum2b version=2-1-stable dest={{ redmine_glob_root_dir }}/{{ redmine_inst_dir }}/plugins/scrum2b update=no + when: rm_scrum2b_plugin + notify: + - Bundle install and reconfigure redmine + tags: [ 'redmine', 'redmine_plugins', 'redmine_plugins_scrum2b' ] + +- name: Install the auto watcher for groups plugin + git: repo=https://github.com/akuznecov/redmine_auto_watchers_from_groups dest={{ redmine_glob_root_dir }}/{{ redmine_inst_dir }}/plugins/redmine_auto_watchers_from_groups update=no + when: rm_autowatcher_plugin + notify: + - Bundle install and reconfigure redmine + tags: [ 'redmine', 'redmine_plugins', 'redmine_plugins_autowatcher' ] + +- name: Install the issue reminder plugin + git: repo=https://github.com/Hopebaytech/redmine_issue_reminder version=redmine2.6 dest={{ redmine_glob_root_dir }}/{{ redmine_inst_dir }}/plugins/redmine_issue_reminder update=no + when: rm_issuereminder_plugin + notify: + - Bundle install and reconfigure redmine + tags: [ 'redmine', 'redmine_plugins', 'redmine_plugins_issuereminder' ] + +- name: Install the issue reminder plugin cron job. + template: src=redmine_issue_reminder.cron.j2 dest=/etc/cron.d/redmine_issue_reminder owner=root group=root mode=0644 + when: rm_issuereminder_plugin + tags: [ 'redmine', 'redmine_plugins', 'redmine_plugins_issuereminder' ] + +- name: Install the update reminder plugin + git: repo=https://github.com/arkhitech/redmine_update_reminder dest={{ redmine_glob_root_dir }}/{{ redmine_inst_dir }}/plugins/redmine_update_reminder update=no + when: rm_updatereminder_plugin + notify: + - Bundle install and reconfigure redmine + tags: [ 'redmine', 'redmine_plugins', 'redmine_plugins_updatereminder' ] + +- name: Install the update reminder plugin cron job. The ruby scheduler does not work, it seems + template: src=redmine_update_reminder.cron.j2 dest=/etc/cron.d/redmine_update_reminder owner=root group=root mode=0644 + when: rm_updatereminder_plugin + tags: [ 'redmine', 'redmine_plugins', 'redmine_plugins_updatereminder' ] + +- name: Install the mention plugin + git: repo=https://github.com/stpl/redmine_mention_plugin dest={{ redmine_glob_root_dir }}/{{ redmine_inst_dir }}/plugins/redmine_mention_plugin update=no + when: rm_mention_plugin + notify: + - Bundle install and reconfigure redmine + tags: [ 'redmine', 'redmine_plugins', 'redmine_plugins_mention' ] + +- name: Install the default custom query plugin + git: repo=https://github.com/hidakatsuya/redmine_default_custom_query dest={{ redmine_glob_root_dir }}/{{ redmine_inst_dir }}/plugins/redmine_default_custom_query update=no + when: rm_defaultcustomquery_plugin + notify: + - Bundle install and reconfigure redmine + tags: [ 'redmine', 'redmine_plugins', 'redmine_plugins_defaultcustomquery' ] + +- name: Install the gamification plugin + git: repo=https://github.com/mauricio-camayo/redmine_gamification_plugin dest={{ redmine_glob_root_dir }}/{{ redmine_inst_dir }}/plugins/redmine_gamification_plugin update=no + when: rm_gamification_plugin + notify: + - Bundle install and reconfigure redmine + tags: [ 'redmine', 'redmine_plugins', 'redmine_plugins_gamification' ] + +- name: Install the closes resolved issues plugin + git: repo=https://github.com/Jogi1j/redmine_closes_resolved_issues dest={{ redmine_glob_root_dir }}/{{ redmine_inst_dir }}/plugins/redmine_closes_resolved_issues update=no + when: rm_closesresolvedissue_plugin + notify: + - Bundle install and reconfigure redmine + tags: [ 'redmine', 'redmine_plugins', 'redmine_plugins_closesresolvedissue' ] + +- name: Install the default assign plugin + git: repo=https://github.com/giddie/redmine_default_assign dest={{ redmine_glob_root_dir }}/{{ redmine_inst_dir }}/plugins/redmine_default_assign update=no + when: rm_defaultassign_plugin + notify: + - Bundle install and reconfigure redmine + tags: [ 'redmine', 'redmine_plugins', 'redmine_plugins_defaultassign' ] + +- name: Install the once assigned ever watcher plugin + git: repo=https://github.com/raafael911/redmine_once_assigned_ever_watcher dest={{ redmine_glob_root_dir }}/{{ redmine_inst_dir }}/plugins/redmine_once_assigned_ever_watcher update=no + when: rm_onceassignedeverwatcher_plugin + notify: + - Bundle install and reconfigure redmine + tags: [ 'redmine', 'redmine_plugins', 'redmine_plugins_onceassignedeverwatcher' ] + +- name: Install the clipboard image paste plugin + git: repo=https://github.com/peclik/clipboard_image_paste dest={{ redmine_glob_root_dir }}/{{ redmine_inst_dir }}/plugins/clipboard_image_paste update=no + when: rm_clipboardimagepaste_plugin + notify: + - Bundle install and reconfigure redmine + tags: [ 'redmine', 'redmine_plugins', 'redmine_plugins_clipboardimagepaste' ] + +- name: Install the hotkeys js plugin + git: repo=https://github.com/sasha-ch/redmine_hotkeys_js version=v0.0.3 dest={{ redmine_glob_root_dir }}/{{ redmine_inst_dir }}/plugins/clipboard_hotkeys_js update=no + when: rm_hotkeysjs_plugin + notify: + - Bundle install and reconfigure redmine + tags: [ 'redmine', 'redmine_plugins', 'redmine_plugins_hotkeysjs' ] + +- name: Install the issues sorting plugin + git: repo=https://github.com/JohnBat26/redmine_issues_sorting dest={{ redmine_glob_root_dir }}/{{ redmine_inst_dir }}/plugins/redmine_issues_sorting update=no + when: rm_issuessorting_plugin + notify: + - Bundle install and reconfigure redmine + tags: [ 'redmine', 'redmine_plugins', 'redmine_plugins_issuessorting' ] + +- name: Install the mylyn plugin + git: repo=https://github.com/ljader/redmine-mylyn-plugin dest={{ redmine_glob_root_dir }}/{{ redmine_inst_dir }}/plugins/redmine_mylyn_plugin update=no + when: rm_mylyn_plugin + notify: + - Bundle install and reconfigure redmine + tags: [ 'redmine', 'redmine_plugins', 'redmine_plugins_mylyn' ] + +- name: Install the quick edit plugin + git: repo=git://git.sourceforge.jp/gitroot/quickedit/quick_edit.git accept_hostkey=yes dest={{ redmine_glob_root_dir }}/{{ redmine_inst_dir }}/plugins/quick_edit update=no + when: rm_quickedit_plugin + notify: + - Bundle install and reconfigure redmine + tags: [ 'redmine', 'redmine_plugins', 'redmine_plugins_quickedit' ] + +- name: Install the quick view plugin + git: repo=git://git.sourceforge.jp/gitroot/quickedit/quick_view.git accept_hostkey=yes dest={{ redmine_glob_root_dir }}/{{ redmine_inst_dir }}/plugins/quick_view update=no + when: rm_quickview_plugin + notify: + - Bundle install and reconfigure redmine + tags: [ 'redmine', 'redmine_plugins', 'redmine_plugins_quickview' ] + +- name: Get the code review plugin + get_url: url=https://bitbucket.org/haru_iida/redmine_code_review/downloads/redmine_code_review-0.6.5.zip dest={{ redmine_glob_root_dir }}/plugins_download/redmine_code_review-0.6.5.zip validate_certs=no + when: rm_codereview_plugin + tags: [ 'redmine', 'redmine_plugins', 'redmine_plugins_codereview' ] + +- name: Unarchive the code review plugin + unarchive: src={{ redmine_glob_root_dir }}/plugins_download/redmine_code_review-0.6.5.zip dest={{ redmine_glob_root_dir }}/{{ redmine_inst_dir }}/plugins copy=no owner=root group=root creates={{ redmine_glob_root_dir }}/{{ redmine_inst_dir }}/plugins/redmine_code_review/init.rb + when: rm_codereview_plugin + notify: + - Bundle install and reconfigure redmine + tags: [ 'redmine', 'redmine_plugins', 'redmine_plugins_codereview' ] + +- name: Unarchive the global roles plugin +# manual download required http://rmplus.pro/en/redmine/plugins/global_roles + unarchive: src={{ redmine_glob_root_dir }}/plugins_download/global_roles.zip dest={{ redmine_glob_root_dir }}/{{ redmine_inst_dir }}/plugins copy=no owner=root group=root creates={{ redmine_glob_root_dir }}/{{ redmine_inst_dir }}/plugins/global_roles/init.rb + when: rm_globalroles_plugin + notify: + - Bundle install and reconfigure redmine + tags: [ 'redmine', 'redmine_plugins', 'redmine_plugins_globalroles' ] + +- name: Unarchive the unread issues plugin +# manual download required http://rmplus.pro/en/redmine/plugins/unread_issues + unarchive: src={{ redmine_glob_root_dir }}/plugins_download/unread_issues.zip dest={{ redmine_glob_root_dir }}/{{ redmine_inst_dir }}/plugins copy=no owner=root group=root creates={{ redmine_glob_root_dir }}/{{ redmine_inst_dir }}/plugins/unread_issues/init.rb + when: rm_unreadissues_plugin + notify: + - Bundle install and reconfigure redmine + tags: [ 'redmine', 'redmine_plugins', 'redmine_plugins_unreadissues' ] + +- name: Unarchive the usability plugin +# manual download required http://rmplus.pro/en/redmine/plugins/usability + unarchive: src={{ redmine_glob_root_dir }}/plugins_download/usability.zip dest={{ redmine_glob_root_dir }}/{{ redmine_inst_dir }}/plugins copy=no owner=root group=root creates={{ redmine_glob_root_dir }}/{{ redmine_inst_dir }}/plugins/usability/init.rb + when: rm_usability_plugin + notify: + - Bundle install and reconfigure redmine + tags: [ 'redmine', 'redmine_plugins', 'redmine_plugins_usability' ] + +- name: Install the mylyn connector plugin + git: repo=git://github.com/danmunn/redmine_mylyn_connector.git accept_hostkey=yes dest={{ redmine_glob_root_dir }}/{{ redmine_inst_dir }}/plugins/redmine_mylyn_connector update=no + when: rm_mylynconnector_plugin + notify: + - Bundle install and reconfigure redmine + tags: [ 'redmine', 'redmine_plugins', 'redmine_plugins_mylynconnector' ] + +- name: Install the mentions plugin + git: repo=https://github.com/arkhitech/redmine_mentions dest={{ redmine_glob_root_dir }}/{{ redmine_inst_dir }}/plugins/redmine_mentions update=no + when: rm_mentions_plugin + notify: + - Bundle install and reconfigure redmine + tags: [ 'redmine', 'redmine_plugins', 'redmine_plugins_mentions' ] + +- name: Install the external wiki plugin + git: repo=https://github.com/nutso/redmine-plugin-wiki-external.git dest={{ redmine_glob_root_dir }}/{{ redmine_inst_dir }}/plugins/wiki_external update=no + when: rm_wiki_external_plugin + notify: Bundle install and reconfigure redmine + tags: [ 'redmine', 'redmine_plugins', 'redmine_plugins_wiki_external' ] + +- name: Install the paste plugin + git: repo=https://github.com/commandprompt/redmine_pastebin.git dest={{ redmine_glob_root_dir }}/{{ redmine_inst_dir }}/plugins/redmine_pastebin update=no + when: rm_pastebin_plugin + notify: + - Bundle install and reconfigure redmine + tags: [ 'redmine', 'redmine_plugins', 'redmine_plugins_pastebin' ] + +- name: Install the issue_templates plugin + git: repo=https://github.com/akiko-pusu/redmine_issue_templates dest={{ redmine_glob_root_dir }}/{{ redmine_inst_dir }}/plugins/redmine_issue_templates update=no + when: rm_issue_templates_plugin + notify: + - Bundle install and reconfigure redmine + tags: [ 'redmine', 'redmine_plugins', 'redmine_plugins_issue_templates' ] + +- name: Install the issue_todo_lists plugin + git: repo=https://github.com/canidas/redmine_issue_todo_lists dest={{ redmine_glob_root_dir }}/{{ redmine_inst_dir }}/plugins/redmine_issue_todo_lists update=no + when: rm_issue_todo_lists_plugin + notify: + - Bundle install and reconfigure redmine + tags: [ 'redmine', 'redmine_plugins', 'redmine_plugins_issue_todo_lists' ] + +- name: Install the involvement filter plugin + git: repo=https://github.com/commandprompt/redmine_involvement_filter.git dest={{ redmine_glob_root_dir }}/{{ redmine_inst_dir }}/plugins/redmine_involvement_filter update=no + when: rm_involvement_plugin + notify: + - Bundle install and reconfigure redmine + tags: [ 'redmine', 'redmine_plugins', 'redmine_plugins_involvement_filter' ] + +- name: Install the omniauth Oauth plugin + git: repo=https://github.com/arlin2050/redmine_omniauth_client.git dest={{ redmine_glob_root_dir }}/{{ redmine_inst_dir }}/plugins/redmine_omniauth_client update=no + notify: + - Bundle install and reconfigure redmine + when: rm_omniauth_plugin + tags: [ 'redmine', 'redmine_plugins', 'rm_oauth', 'rm_omniauth' ] + diff --git a/tasks/redmine.yml b/tasks/redmine.yml new file mode 100644 index 0000000..f97814e --- /dev/null +++ b/tasks/redmine.yml @@ -0,0 +1,127 @@ +--- +- block: + - name: Fail if the redmine data directory variable is not defined + fail: msg="redmine_glob_root_dir is required for this role" + when: redmine_glob_root_dir is not defined + + - name: ensure that the redmine data directories exist + file: dest={{ item }} state=directory owner=root group=root + with_items: + - '{{ redmine_glob_root_dir }}' + - '{{ redmine_glob_users_home_base }}' + + - name: Create the user that will run the redmine process + user: name={{ redmine_user }} createhome=true home={{ redmine_user_home }} shell=/usr/bin/nologin system=yes + + - name: Ensure that the redmine user can write its $HOME/.subversion to store the svn site ssl certificate + file: dest={{ redmine_user_home }}/.subversion state=directory owner={{ redmine_user }} group={{ redmine_group }} + + - name: Get the redmine tarball + get_url: url=http://www.redmine.org/releases/redmine-{{ redmine_version }}.tar.gz dest={{ redmine_glob_root_dir }}/redmine-{{ redmine_version }}.tar.gz + + - name: Explode the redmine archive + unarchive: src={{ redmine_glob_root_dir }}/redmine-{{ redmine_version }}.tar.gz dest={{ redmine_glob_root_dir }} copy=no owner=root group=root creates={{ redmine_glob_root_dir }}/redmine-{{ redmine_version }}/Rakefile + register: redmine_install + + - name: Create the right path for the application. + file: src={{ redmine_glob_root_dir }}/redmine-{{ redmine_version }} dest={{ redmine_glob_root_dir }}/{{ redmine_inst_dir }} state=link + + - name: Install the database configuration + template: src=redmine-database.yml.j2 dest={{ redmine_glob_root_dir }}/{{ redmine_inst_dir }}/config/database.yml owner=root group={{ redmine_group }} mode=0440 + notify: + - apache2 reload when needed + - Reload unicorn when needed + + - name: Install the configuration file. Needed to send email + template: src=redmine-configuration.yml.j2 dest=/{{ redmine_glob_root_dir }}/{{ redmine_inst_dir }}/config/configuration.yml owner=root group={{ redmine_group }} mode=0440 + notify: + - apache2 reload when needed + - Reload unicorn when needed + + - name: Install the additional environment file + template: src=redmine_additional_environment.rb.j2 dest=/{{ redmine_glob_root_dir }}/{{ redmine_inst_dir }}/config/additional_environment.rb owner=root group={{ redmine_group }} mode=0440 + notify: + - apache2 reload when needed + - Reload unicorn when needed + + - name: Install the gems required by redmine + shell: cd {{ redmine_glob_root_dir }}/{{ redmine_inst_dir }}; bundle install --without development test sqlite mysql && touch {{ redmine_glob_root_dir }}/.{{ redmine_inst_dir }}_gems_installed + args: + creates: '{{ redmine_glob_root_dir }}/.{{ redmine_inst_dir }}_gems_installed' + + - name: Generate the secret token + shell: cd {{ redmine_glob_root_dir }}/{{ redmine_inst_dir }}; rake generate_secret_token ; chmod 440 {{ redmine_glob_root_dir }}/{{ redmine_inst_dir }}/config/initializers/secret_token.rb ; chgrp {{ redmine_group }} {{ redmine_glob_root_dir }}/{{ redmine_inst_dir }}/config/initializers/secret_token.rb + args: + creates: '{{ redmine_glob_root_dir }}/{{ redmine_inst_dir }}/config/initializers/secret_token.rb' + + - name: Initialize the DB + shell: cd {{ redmine_glob_root_dir }}/{{ redmine_inst_dir }}; RAILS_ENV=production rake db:migrate && touch {{ redmine_glob_root_dir }}/.{{ redmine_inst_dir }}.db_initialized + args: + creates: '{{ redmine_glob_root_dir }}/.{{ redmine_inst_dir }}.db_initialized' + tags: [ 'redmine', 'redmine_db_init' ] + + - name: Install the defauld DB data + shell: cd {{ redmine_glob_root_dir }}/{{ redmine_inst_dir }}; RAILS_ENV=production REDMINE_LANG=en rake redmine:load_default_data && touch {{ redmine_glob_root_dir }}/.{{ redmine_inst_dir }}.db_data_loaded + args: + creates: '{{ redmine_glob_root_dir }}/.{{ redmine_inst_dir }}.db_data_loaded' + tags: [ 'redmine', 'redmine_db_init' ] + + - name: Install the packages needed by plugins or to build plugins required gems + apt: pkg={{ item }} state=present + with_items: + - libxslt1-dev + + # The themes come from http://www.redminecrm.com/ + - name: Install some optional themes + unarchive: src={{ item }}-theme.zip dest={{ redmine_glob_root_dir }}/{{ redmine_inst_dir }}/public/themes creates={{ redmine_glob_root_dir }}/{{ redmine_inst_dir }}/public/themes/{{ item }} + with_items: + - a1 + - circle + notify: + - apache2 reload when needed + - Reload unicorn when needed + + - name: Add unicorn to the redmine Gemfile + copy: dest={{ redmine_glob_root_dir }}/{{ redmine_inst_dir }}/Gemfile.local content='gem "unicorn"\n' owner={{ redmine_user }} group={{ redmine_group }} + when: ruby_use_unicorn + tags: [ 'redmine', 'unicorn' ] + + - name: Upgrade rake to fix all the gems mess + shell: cd {{ redmine_glob_root_dir }}/{{ redmine_inst_dir }}; bundle update rake + + - name: Fix the permission of some files + file: dest={{ redmine_glob_root_dir }}/{{ redmine_inst_dir }}/{{ item }} owner={{ redmine_user }} group={{ redmine_group }} + with_items: + - Gemfile + - Gemfile.lock + + - name: Ensure that redmine can write into some directories + file: dest={{ redmine_glob_root_dir }}/{{ redmine_inst_dir }}/{{ item }} state=directory owner={{ redmine_user }} group={{ redmine_group }} recurse=yes + with_items: + - files + - log + - tmp + - public/plugin_assets + + - name: Install a logrotate script to take care of the ever growing production.log file + template: src=redmine-logrotate.j2 dest=/etc/logrotate.d/redmine-{{ redmine_inst_name }} owner=root group=root mode=0444 + tags: [ 'redmine', 'logrotate' ] + + - name: Install a script that syncs the email to redmine reading from a imap account + template: src=redmine-imap-sync.j2 dest=/usr/local/bin/redmine-imap-sync owner=root group={{ redmine_user }} mode=0750 + when: redmine_imap_sync | bool + tags: [ 'redmine', 'redmine_imap' ] + + - name: Install a cron job that configures the task that reads emails via imap + cron: + cron_file: redmine-email-sync + disabled: no + job: '/usr/local/bin/redmine-imap-sync' + user: '{{ redmine_user }}' + minute: '*/10' + name: 'Redmine update tasks by email' + state: present + when: redmine_imap_sync | bool + tags: [ 'redmine', 'redmine_imap' ] + + tags: redmine diff --git a/tasks/rubygems.yml b/tasks/rubygems.yml new file mode 100644 index 0000000..0434122 --- /dev/null +++ b/tasks/rubygems.yml @@ -0,0 +1,14 @@ +--- +- name: Install the gem bundler + gem: name=bundler state=latest + tags: + - ruby + - redmine + +- name: Install the gem packages needed by some external utilities + gem: name={{ redmine_additional_gems }} state=latest + when: redmine_additional_gems is defined + tags: + - ruby + - redmine + diff --git a/tasks/unicorn.yml b/tasks/unicorn.yml new file mode 100644 index 0000000..cd9e4c5 --- /dev/null +++ b/tasks/unicorn.yml @@ -0,0 +1,65 @@ +--- +- block: + - name: Install the unicorn ruby-on-rails service and its dependencies + gem: name={{ item }} state=latest + with_items: '{{ unicorn_gems }}' + + - name: Create the unicorn pid directory + file: dest=/var/run/unicorn state=directory owner={{ redmine_user }} group={{ redmine_user }} mode=0750 + + - name: Install the unicorn startup file for redmine + copy: src=redmine.init dest=/etc/init.d/redmine owner=root group=root mode=0755 + + - name: Ensure that the unicorn service is enabled and running on trusty + service: name={{ redmine_sysvinit_service_name }} state=started enabled=yes + when: ruby_use_unicorn + + tags: [ 'ruby', 'redmine', 'unicorn' ] + when: + - ruby_use_unicorn + - ansible_distribution_version is version_compare('14.04', '==') + +- block: + - name: Install the unicorn package + apt: pkg=unicorn state=present cache_valid_time=1800 + + - name: Install a nginx configuration of the unicorn backend + template: src=nginx_unicorn.conf dest=/etc/nginx/conf.d/nginx_unicorn.conf + notify: Restart nginx + + tags: [ 'ruby', 'redmine', 'unicorn' ] + when: + - ruby_use_unicorn + - ansible_distribution_version is version_compare('18.04', '==') + +- block: + - name: Create the unicorn log directory + file: dest={{ unicorn_log_dir }} state=directory owner={{ redmine_user }} group={{ redmine_user }} mode=0750 + + - name: Install the unicorn defaults file + template: src=unicorn-redmine.default.j2 dest=/etc/default/unicorn-{{ redmine_inst_name }} owner=root group=root mode=0644 + notify: Reload unicorn when needed + + - name: Install the unicorn logrotate file + template: src=unicorn-logrotate.j2 dest=/etc/logrotate.d/unicorn-{{ redmine_inst_name }} owner=root group=root mode=0644 + + - name: Install the unicorn config + template: src=unicorn.conf.rb.j2 dest={{ redmine_glob_root_dir }}/{{ redmine_inst_dir }}/config/unicorn.conf.rb owner=root group=root mode=0644 + + - name: Install the systemd unit that globally manages the unicorn service + template: src=systemd_unicorn.service dest={{ redmine_glob_root_dir }}/{{ redmine_inst_dir }}/config/unicorn@.service + notify: Reload systemd after the system unit installation + + - name: Link the systemd unit that globally manages the unicorn service + file: src={{ redmine_glob_root_dir }}/{{ redmine_inst_dir }}/config/unicorn@.service dest=/etc/systemd/system/multi-user.target.wants/unicorn@.service state=link + + - name: Reload systemd after the system unit installation + meta: flush_handlers + + - name: Ensure that the unicorn service for redmine is started and enabled + service: name={{ redmine_systemd_service_name }} state=started enabled=yes + ignore_errors: True + + tags: [ 'ruby', 'redmine', 'unicorn' ] + when: ruby_use_unicorn + diff --git a/templates/nginx_unicorn.conf b/templates/nginx_unicorn.conf new file mode 100644 index 0000000..4756bb8 --- /dev/null +++ b/templates/nginx_unicorn.conf @@ -0,0 +1,13 @@ +upstream unicorn { + # fail_timeout=0 means we always retry an upstream even if it failed + # to return a good HTTP response (in case the Unicorn master nukes a + # single worker for timing out). + + # for UNIX domain socket setups: + # server unix:/tmp/.sock fail_timeout=0; + + # for TCP setups, point these to your backend servers + {% for i in 0, 4 %} + server 127.0.0.1:{{ unicorn_listen_port + i }} fail_timeout=0; + {% endfor %} + } diff --git a/templates/redmine-configuration.yml.j2 b/templates/redmine-configuration.yml.j2 new file mode 100644 index 0000000..beceb01 --- /dev/null +++ b/templates/redmine-configuration.yml.j2 @@ -0,0 +1,43 @@ +# specific configuration options for production environment +# that overrides the default ones +# production: +# email_delivery: +# delivery_method: :async_smtp +# async_smtp_settings: +# address: 127.0.0.1 +# domain: 'research-infrastructures.eu' +# port: 25 +# enable_starttls_auto: false + +production: + email_delivery: + delivery_method: :async_sendmail + +# Key used to encrypt sensitive data in the database (SCM and LDAP passwords). +# If you don't want to enable data encryption, just leave it blank. +# WARNING: losing/changing this key will make encrypted data unreadable. +# +# If you want to encrypt existing passwords in your database: +# * set the cipher key here in your configuration file +# * encrypt data using 'rake db:encrypt RAILS_ENV=production' +# +# If you have encrypted data and want to change this key, you have to: +# * decrypt data using 'rake db:decrypt RAILS_ENV=production' first +# * change the cipher key here in your configuration file +# * encrypt data using 'rake db:encrypt RAILS_ENV=production' +# database_cipher_key: + +# Your secret key for verifying cookie session data integrity. If you +# change this key, all old sessions will become invalid! Make sure the +# secret is at least 30 characters and all random, no regular words or +# you'll be exposed to dictionary attacks. +# +# If you have a load-balancing Redmine cluster, you have to use the +# same secret token on each machine. +{% if redmine_secret_token is defined %} +secret_token: '{{ redmine_secret_token }}' +{% endif %} + +# specific configuration options for development environment +# that overrides the default ones +development: diff --git a/templates/redmine-database.yml.j2 b/templates/redmine-database.yml.j2 new file mode 100644 index 0000000..c7a9502 --- /dev/null +++ b/templates/redmine-database.yml.j2 @@ -0,0 +1,8 @@ +production: + adapter: postgresql + database: {{ redmine_db_name }} + host: {{ redmine_db_host }} + username: {{ redmine_db_user }} + password: {{ redmine_db_pwd }} + encoding: utf8 +# schema_search_path: (default - public) diff --git a/templates/redmine-imap-sync.j2 b/templates/redmine-imap-sync.j2 new file mode 100644 index 0000000..3484d16 --- /dev/null +++ b/templates/redmine-imap-sync.j2 @@ -0,0 +1,4 @@ +#!/bin/bash + +rake -f {{ redmine_glob_root_dir }}/{{ redmine_inst_dir }}/Rakefile redmine:email:receive_imap RAILS_ENV="production" host={{ redmine_imap_server }} username={{ redmine_imap_user }} password='{{ redmine_imap_password }}' unknown_user={{ redmine_imap_unknown_user_action }} starttls={{ redmine_imap_starttls }} {{ redmine_imap_sync_additional_options }} >> {{ redmine_glob_root_dir }}/{{ redmine_inst_dir }}/log/imap_sync.log 2>&1 + diff --git a/templates/redmine-ldap-sync.cron.j2 b/templates/redmine-ldap-sync.cron.j2 new file mode 100644 index 0000000..67bb8e9 --- /dev/null +++ b/templates/redmine-ldap-sync.cron.j2 @@ -0,0 +1 @@ +*/{{ redmine_ldap_sync_freq }} * * * * {{ redmine_user }} /usr/local/bin/rake -f {{ redmine_glob_root_dir }}/{{ redmine_inst_dir }}/Rakefile --silent redmine:plugins:ldap_sync:sync_{{ redmine_ldap_sync_who }} RAILS_ENV=production >{{ redmine_glob_root_dir }}/{{ redmine_inst_dir }}/log/redmine-ldap-sync.log 2>&1 diff --git a/templates/redmine-logrotate.j2 b/templates/redmine-logrotate.j2 new file mode 100644 index 0000000..b478d20 --- /dev/null +++ b/templates/redmine-logrotate.j2 @@ -0,0 +1,6 @@ +{{ redmine_glob_root_dir }}/{{ redmine_inst_dir }}/log/*.log { + missingok + notifempty + delaycompress + copytruncate +} \ No newline at end of file diff --git a/templates/redmine-recurring-tasks.cron.j2 b/templates/redmine-recurring-tasks.cron.j2 new file mode 100644 index 0000000..6604ed1 --- /dev/null +++ b/templates/redmine-recurring-tasks.cron.j2 @@ -0,0 +1,2 @@ +*/30 * * * * {{ redmine_user }} rake -f {{ redmine_glob_root_dir }}/{{ redmine_inst_dir }}/Rakefile --silent RAILS_ENV=production redmine:recur_tasks >{{ redmine_glob_root_dir }}/{{ redmine_inst_dir }}/log/redmine-recurring-tasks.log 2>&1 +#*/30 * * * * {{ redmine_user }} rake -f {{ redmine_glob_root_dir }}/{{ redmine_inst_dir }}/Rakefile --silent RAILS_ENV=production redmine:check_periodictasks >{{ redmine_glob_root_dir }}/{{ redmine_inst_dir }}/log/redmine-periodic-tasks.log 2>&1 diff --git a/templates/redmine_additional_environment.rb.j2 b/templates/redmine_additional_environment.rb.j2 new file mode 100644 index 0000000..ed6f309 --- /dev/null +++ b/templates/redmine_additional_environment.rb.j2 @@ -0,0 +1,3 @@ + +config.action_controller.allow_forgery_protection = false +config.log_level = :{{ redmine_log_level }} diff --git a/templates/redmine_issue_reminder.cron.j2 b/templates/redmine_issue_reminder.cron.j2 new file mode 100644 index 0000000..662d2f5 --- /dev/null +++ b/templates/redmine_issue_reminder.cron.j2 @@ -0,0 +1 @@ +{{ rm_issue_reminder_plugin_freq_min }} {{ rm_issue_reminder_plugin_freq_hour }} * * {{ rm_issue_reminder_plugin_freq_weekday }} {{ redmine_user }} cd {{ redmine_glob_root_dir }}/{{ redmine_inst_dir }} ; bundle exec /usr/local/bin/rake -f {{ redmine_glob_root_dir }}/{{ redmine_inst_dir }}/Rakefile --silent RAILS_ENV=production reminder:exec >{{ redmine_glob_root_dir }}/{{ redmine_inst_dir }}/log/redmine-issue_reminder.log 2>&1 diff --git a/templates/redmine_update_reminder.cron.j2 b/templates/redmine_update_reminder.cron.j2 new file mode 100644 index 0000000..d137e55 --- /dev/null +++ b/templates/redmine_update_reminder.cron.j2 @@ -0,0 +1 @@ +{{ rm_updatereminder_plugin_freq_min }} {{ rm_updatereminder_plugin_freq_hour }} * * {{ rm_updatereminder_plugin_freq_weekday }} {{ redmine_user }} /usr/local/bin/rake -f {{ redmine_glob_root_dir }}/{{ redmine_inst_dir }}/Rakefile --silent RAILS_ENV=production redmine_update_reminder:send_reminders >{{ redmine_glob_root_dir }}/{{ redmine_inst_dir }}/log/redmine-update_send_reminders.log 2>&1 diff --git a/templates/systemd_unicorn.service b/templates/systemd_unicorn.service new file mode 100644 index 0000000..0d05e68 --- /dev/null +++ b/templates/systemd_unicorn.service @@ -0,0 +1,22 @@ +[Unit] +# You can create multiple unicorn service by linking unicorn@.service to unicorn@appone.service, unicorn@apptwo.service +# each application reads its settings from /etc/default/unicorn_appone, /etc/default/unicorn_apptwo +Description=Unicorn serving %I app +After=syslog.target + +[Service] +Restart=always +RestartSec=10 +Type=forking +User={{ redmine_user }} +Group={{ redmine_group }} +WorkingDirectory=/srv/redmine/%I +EnvironmentFile=/etc/default/unicorn-%I +SyslogIdentifier=unicorn-%I +PIDFile={{ unicorn_pid_file }} +KillMode=mixed +KillSignal=SIGQUIT +ExecStart=/usr/bin/bundle exec "${DAEMON} ${DAEMON_OPTS}" + +[Install] +WantedBy=multi-user.target diff --git a/templates/unicorn-logrotate.j2 b/templates/unicorn-logrotate.j2 new file mode 100644 index 0000000..b145822 --- /dev/null +++ b/templates/unicorn-logrotate.j2 @@ -0,0 +1,9 @@ +{{ unicorn_log_dir }}/*.log { + weekly + missingok + rotate 52 + compress + delaycompress + notifempty + copytruncate +} diff --git a/templates/unicorn-redmine.default.j2 b/templates/unicorn-redmine.default.j2 new file mode 100644 index 0000000..95a176e --- /dev/null +++ b/templates/unicorn-redmine.default.j2 @@ -0,0 +1,10 @@ +APP={{ redmine_glob_root_dir }}/{{ redmine_inst_dir }} +APP_ROOT={{ redmine_glob_root_dir }}/{{ redmine_inst_dir }} +USER={{ redmine_user }} +DAEMON=unicorn +DAEMON_OPTS="-c {{ redmine_glob_root_dir }}/{{ redmine_inst_dir }}/config/unicorn.conf.rb -E production -D -l {{ unicorn_listen_address }}:3999" +NAME=unicorn +DESC="Unicorn app for $USER" +PID_DIR={{ unicorn_pid_dir }} +PID={{ unicorn_pid_file }} +RACK_ENV=production diff --git a/templates/unicorn.conf.rb.j2 b/templates/unicorn.conf.rb.j2 new file mode 100644 index 0000000..91a273c --- /dev/null +++ b/templates/unicorn.conf.rb.j2 @@ -0,0 +1,60 @@ +app_dir = "{{ redmine_glob_root_dir }}/{{ redmine_inst_dir }}" +working_directory app_dir +pid "{{ unicorn_pid_file }}" + +preload_app true +timeout {{ unicorn_timeout }} +worker_processes {{ unicorn_worker_processes }} + +# Log files +stderr_path "{{ unicorn_log_dir }}/unicorn.stderr.log" +stdout_path "{{ unicorn_log_dir }}/unicorn.stdout.log" + +GC.respond_to?(:copy_on_write_friendly=) and GC.copy_on_write_friendly = true + +before_fork do |server, worker| + # the following is highly recomended for Rails + "preload_app true" + # as there's no need for the master process to hold a connection + defined?(ActiveRecord::Base) and ActiveRecord::Base.connection.disconnect! + + ## + # When sent a USR2, Unicorn will suffix its pidfile with .oldbin and + # immediately start loading up a new version of itself (loaded with a new + # version of our app). When this new Unicorn is completely loaded + # it will begin spawning workers. The first worker spawned will check to + # see if an .oldbin pidfile exists. If so, this means we've just booted up + # a new Unicorn and need to tell the old one that it can now die. To do so + # we send it a QUIT. + # + # Using this method we get 0 downtime deploys. + + old_pid = "#{server.config[:pid]}.oldbin" + + if File.exists?(old_pid) && server.pid != old_pid + begin + sig = (worker.nr + 1) >= server.worker_processes ? :QUIT : :TTOU + Process.kill(sig, File.read(old_pid).to_i) + rescue Errno::ENOENT, Errno::ESRCH + # someone else did our job for us + end + end +end + +after_fork do |server, worker| + # Unicorn master loads the app then forks off workers - because of the way + # Unix forking works, we need to make sure we aren't using any of the parent's + # sockets, e.g. db connection + defined?(ActiveRecord::Base) and ActiveRecord::Base.establish_connection + # Redis and Memcached would go here but their connections are established + # on demand, so the master never opens a socket + #start the worker on port 4000, 4001, 4002 etc... + addr = "{{ unicorn_listen_address }}:#{ {{ unicorn_listen_port }} + worker.nr}" + # infinite tries to start the worker + server.listen(addr, :tries => 10, :delay => 5, :backlog => 128) + +end + + + + + diff --git a/vars/main.yml b/vars/main.yml index 3808477..2475a45 100644 --- a/vars/main.yml +++ b/vars/main.yml @@ -1,2 +1,50 @@ --- -# vars file for ansible-role-template \ No newline at end of file + unicorn_gems: + - unicorn + - coderay + unicorn_apache_modules: + - proxy_balancer + - proxy + - proxy_http + - lbmethod_byrequests + - lbmethod_bytraffic + - lbmethod_bybusyness + - lbmethod_heartbeat + + # For Ubuntu trusty + redmine_base_packages: + - subversion + - git-core + - curl + - 'ruby{{ trusty_ruby_version }}' + - rails + - ruby-rmagick + - 'ruby{{ trusty_ruby_version }}-dev' + - rails + - zlib1g-dev + - libpq-dev + - libmysqld-dev + - libmagickwand-dev + - libmagickcore-dev + - imagemagick + + redmine_bionic_packages: + - subversion + - git-core + - curl + - ruby + - rails + - ruby-rmagick + - ruby-dev + - rails + - zlib1g-dev + - libpq-dev + - libmysqld-dev + - libmagickwand-dev + - libmagickcore-dev + - imagemagick + + redmine_base_apache_modules: + - ssl + - rewrite + - expires