ansible playbooks

To simplify the installation process of riaf we wrote a few ansible playbooks. This allows a more precise description of the installation tasks. But of cause you should check the playbooks and maybe adapt them for your setting.

play_install_zfs.yaml

play_install_zfs.yaml

---
# ansible-playbook --ask-vault-pass -v play_install_zfs.yaml

- name: install zfs
  hosts: all
  become: yes
  tasks:
    - include: task_install_zfs.yaml

It uses the task task_install_zfs.yaml:

- name: install zfsutils-linux
  apt:
    name: zfsutils-linux
    state: present
    force_apt_get: yes
- name: create zfs pool data
  shell: zfs get all data || zpool create data /dev/sda5

play_install_riaf.yaml

play_install_riaf.yaml

---
# ansible-playbook --ask-vault-pass -v play_install_riaf.yaml

- name: installation and basic configuration
  hosts: all
  become: yes
  vars_prompt:
    - name: ssh_adminkey_gitolite
      prompt: "initial ssh adminkey for gitolite"
      private: no
    - name: gitolite_user
      prompt: "gitolite user name"
      default: "git"
      private: no
    - name: gitolite_home
      prompt: "path to the gitolite home directory (repositories are stored here)"
      default: "/data/gitolite"
      private: no
    - name: servername
      prompt: "DNS name of the server"
      default: "example.com"
      private: no
    - name: configfile_gitolite_site
      prompt: "config file of the gitolite web site"
      default: "configs/gitolite.conf"
      private: no
    - name: ssl_cert_crt
      prompt: "ssl certificate of the web site"
      default: "cert/gitolite.crt"
      private: no
    - name: ssl_cert_key
      prompt: "ssl certificate key of the web site"
      default: "cert/gitolite.key"
      private: no
    - name: gitolite_suexec_wrapper
      prompt: "path to gitolite-suexec-wrapper.sh"
      default: "configs/gitolite-suexec-wrapper.sh"
      private: no
    - name: index_html
      prompt: "path to index.html"
      default: "configs/index.html"
      private: no
    - name: gitolite_update_list_all_users
      prompt: "path to the script update_list_all_users"
      default: "configs/update_list_all_users"
      private: no
    - name: server_timestamping_script
      prompt: "path to the server_timestamping script"
      default: "configs/server_timestamping"
      private: no
    - name: riaf_landing_page_script
      prompt: "path to the riaf_landing_page script"
      default: "configs/riaf_landing_page"
      private: no
  tasks:
    - include: task_install_riaf_packages.yaml
    - include: task_install_pydabu.yaml
    - include: task_install_riaf_configuration_gitolite.yaml
    - include: task_install_riaf_gitolite_add_trigger_riaf_post_git.yaml
    - include: task_install_riaf_configuration_sshd.yaml
    - include: task_install_riaf_fuse_git_bare_fs.yaml
    - include: task_install_riaf_enable_apache_modules.yaml
    - include: task_install_riaf_configuration_apache.yaml
    - include: task_install_riaf_user_management_configuration.yaml
    - include: task_install_riaf_configuration_apache_gitolite_1.yaml
    - include: task_install_riaf_gitolite_web_interface.yaml
    - include: task_install_riaf_configuration_gitolite_web_interface.yaml
    - include: task_install_riaf_configuration_apache_gitolite_2.yaml
  handlers:
    - include: handler_install_riaf.yaml

It uses the following tasks and handler:

task_install_riaf_packages.yaml:

# https://docs.ansible.com/ansible/2.5/modules/apt_module.html

- name: update cache
  apt:
    force_apt_get: yes
    update_cache: yes
- name: install necessary tools
  apt:
    name:
      - apache2
      - apache2-suexec-custom
      - git
      - git-annex
      - gitolite3
      - python3-dulwich
      - python3-fusepy
      - python3-pip
      - python3-setuptools
    state: present
    force_apt_get: yes

task_install_riaf_configuration_gitolite.yaml:

# https://docs.ansible.com/ansible/2.5/modules/shell_module.html
# https://docs.ansible.com/ansible/2.5/modules/debconf_module.html
# https://docs.ansible.com/ansible/2.5/modules/file_module.html
# https://docs.ansible.com/ansible/2.5/modules/lineinfile_module.html
# https://docs.ansible.com/ansible/2.5/modules/replace_module.html

# configuration of gitolite
- name: get configuration options for gitolite3
  shell: debconf-show gitolite3
- name: 'configure gitolite: gitolite3/gituser'
  debconf:
    name: gitolite3
    question: gitolite3/gituser
    value: "{{ gitolite_user }}"
    vtype: string
- name: 'configure gitolite: gitolite3/gitdir'
  debconf:
    name: gitolite3
    question: gitolite3/gitdir
    value: "{{ gitolite_home }}"
    vtype: string
- name: 'configure gitolite: gitolite3/adminkey'
  debconf:
    name: gitolite3
    question: gitolite3/adminkey
    value: "{{ ssh_adminkey_gitolite }}"
    vtype: string
- name: install gitolite configuration
  shell:
    DEBIAN_FRONTEND=noninteractive dpkg-reconfigure gitolite3
- name: adapt rights on gitolite home
  file:
    group: "{{ gitolite_user }}"
    mode: 0750
    owner: "{{ gitolite_user }}"
    path: "{{ gitolite_home }}"
    state: directory
- name: enable git-annex in gitolite
  lineinfile:
    backup: yes
    insertafter: '# Uncomment or add new commands here.'
    path: "{{ gitolite_home }}/.gitolite.rc"
    regexp: "^            'git-annex-shell ua',"
    line: "            'git-annex-shell ua',"
- name: enable sskm (self-service key management) in gitolite
  lineinfile:
    backup: yes
    insertafter: '# Uncomment or add new commands here.'
    path: "{{ gitolite_home }}/.gitolite.rc"
    regexp: "^            'sskm',"
    line: "            'sskm',"
- name: unset daemon
  replace:
    backup: yes
    path: "{{ gitolite_home }}/.gitolite.rc"
    regexp: "^            'daemon',"
    replace: "            # 'daemon',"
- name: unset gitweb
  replace:
    backup: yes
    path: "{{ gitolite_home }}/.gitolite.rc"
    regexp: "^            'gitweb',"
    replace: "            # 'gitweb',"
- name: set Kindergarten
  replace:
    backup: yes
    path: "{{ gitolite_home }}/.gitolite.rc"
    regexp: "^            # 'Kindergarten',"
    replace: "            'Kindergarten',"
- name: create /var/lib/gitolite/gitolite-source
  file:
    group: "{{ gitolite_user }}"
    mode: 0755
    owner: "{{ gitolite_user }}"
    path: "{{ gitolite_home }}/gitolite-source"
    state: directory
- name: link gitolite source
  file:
    group: "{{ gitolite_user }}"
    mode: 0755
    owner: "{{ gitolite_user }}"
    path: "{{ gitolite_home }}/gitolite-source/src"
    src: /usr/share/gitolite3
    state: link

task_install_riaf_configuration_sshd.yaml:

# configuration of sshd
- name: unset AcceptEnv in /etc/ssh/sshd_config
  replace:
    backup: yes
    path: /etc/ssh/sshd_config
    regexp: '^AcceptEnv LANG LC_*'
    replace: '#AcceptEnv LANG LC_*'
  notify:
    - reload ssh

task_install_riaf_fuse_git_bare_fs.yaml:

# https://docs.ansible.com/ansible/2.5/modules/pip_module.html
# https://docs.ansible.com/ansible/2.5/modules/replace_module.html

# install and configure fuse_git_bare_fs
- name: install fuse_git_bare_fs
  pip:
    name: https://github.com/dlr-pa/fuse_git_bare_fs/archive/refs/heads/master.zip
- name: adapt fuse to allow non-root users to specify the allow_other option
  replace:
    backup: yes
    path: /etc/fuse.conf
    regexp: '^#user_allow_other'
    replace: 'user_allow_other'

task_install_riaf_enable_apache_modules.yaml:

# enable apache modules
- name: enable necessary apache module ssl
  apache2_module:
    name: ssl
    state: present
  notify:
    - restart apache2
- name: enable necessary apache module headers
  apache2_module:
    name: headers
    state: present
  notify:
    - restart apache2
- name: enable necessary apache module cgid
  apache2_module:
    name: cgid
    state: present
  notify:
    - restart apache2
- name: enable necessary apache module suexec
  apache2_module:
    name: suexec
    state: present
  notify:
    - restart apache2
- name: enable necessary apache module dav
  apache2_module:
    name: dav
    state: present
  notify:
    - restart apache2
- name: enable necessary apache module dav_fs
  apache2_module:
    name: dav_fs
    state: present
  notify:
    - restart apache2

task_install_riaf_configuration_apache.yaml:

# https://docs.ansible.com/ansible/2.5/modules/copy_module.html
# https://docs.ansible.com/ansible/2.5/modules/file_module.html
# https://docs.ansible.com/ansible/2.5/modules/shell_module.html
# https://docs.ansible.com/ansible/2.5/modules/replace_module.html

# adapt apache
- name: install ssl certificate
  copy:
    backup: yes
    dest: /etc/ssl/certs/gitolite.crt
    mode: 0644
    src: '{{ ssl_cert_crt }}'
  notify:
    - reload apache2
- name: install ssl certificate key
  copy:
    backup: yes
    dest: /etc/ssl/private/gitolite.key
    group: ssl-cert
    mode: 0640
    src: '{{ ssl_cert_key }}'
  notify:
    - reload apache2
- name: create server directory /var/www/gitolite
  file:
    group: "{{ gitolite_user }}"
    mode: 0755
    owner: "{{ gitolite_user }}"
    path: /var/www/gitolite
    state: directory
- name: create server directory /var/www/gitolite/dav
  file:
    group: "{{ gitolite_user }}"
    mode: 0750
    owner: "{{ gitolite_user }}"
    path: /var/www/gitolite/dav
    state: directory
- name: create server directory /var/www/gitolite/dabu
  file:
    group: "{{ gitolite_user }}"
    mode: 0750
    owner: "{{ gitolite_user }}"
    path: /var/www/gitolite/dabu
    state: directory
- name: create /etc/apache2/gitolite.passwd
  file:
    path: /etc/apache2/gitolite.passwd
    state: touch
- name: install gitolite site
  copy:
    backup: yes
    dest: /etc/apache2/sites-available/gitolite.conf
    src: '{{ configfile_gitolite_site }}'
  notify:
    - reload apache2
- name: add apache user www-data to group git
  shell: usermod -a -G "{{ gitolite_user }}" www-data
- name: set server name in /etc/apache2/sites-available/gitolite.conf 1/2
  lineinfile:
    backup: yes
    insertafter: '^	#Redirect / https://www.example.com/'
    line: '	Redirect / https://{{ servername }}/'
    path: /etc/apache2/sites-available/gitolite.conf
    regexp: '^	Redirect / https://{{ servername }}/'
- name: set server name in /etc/apache2/sites-available/gitolite.conf 2/2
  lineinfile:
    backup: yes
    insertafter: '^		#ServerName www.example.com'
    line: '		ServerName {{ servername }}'
    path: /etc/apache2/sites-available/gitolite.conf
    regexp: '^		ServerName {{ servername }}'
- name: disable default site
  shell: a2dissite 000-default
  notify:
    - reload apache2
- name: enable gitolite web site
  shell: a2ensite gitolite
  notify:
    - reload apache2

task_install_riaf_configuration_apache_gitolite_1.yaml:

# https://docs.ansible.com/ansible/2.5/modules/mount_module.html
# https://docs.ansible.com/ansible/2.5/modules/file_module.html
# https://docs.ansible.com/ansible/2.5/modules/copy_module.html
# https://docs.ansible.com/ansible/2.5/modules/replace_module.html

- name: add fuse mount dav in /etc/fstab
  mount:
    backup: yes
    boot: yes
    fstype: fuse.fuse_git_bare_fs
    opts: uid=git,gid=git,tree,allow_other,get_user_list_from_gitolite,provide_htaccess,root_object=master,gitolite_user_file={{ gitolite_home }}/dav_users,file_st_modes=33184=33256=41471=16872,default_permissions,nofail,ro
    path: /var/www/gitolite/dav
    src: "{{ gitolite_home }}/repositories"
    state: mounted

- name: add fuse mount dabu in /etc/fstab
  mount:
    backup: yes
    boot: yes
    fstype: fuse.fuse_git_bare_fs
    opts: uid=git,gid=git,tree,allow_other,root_object=landing_page,gitolite_user_file={{ gitolite_home }}/dav_users,file_st_modes=33184=33256=41471=16872,default_permissions,nofail,ro
    path: /var/www/gitolite/dabu
    src: "{{ gitolite_home }}/repositories"
    state: mounted

- name: create server directory /var/www/bin
  file:
    group: "{{ gitolite_user }}"
    mode: 0755
    owner: "{{ gitolite_user }}"
    path: /var/www/bin
    state: directory

# gitolite-suexec-wrapper.sh
- name: 'install gitolite-suexec-wrapper.sh'
  copy:
    backup: yes
    dest: /var/www/bin/gitolite-suexec-wrapper.sh
    group: "{{ gitolite_user }}"
    mode: 0700
    owner: "{{ gitolite_user }}"
    src: '{{ gitolite_suexec_wrapper }}'
  notify:
    - reload apache2
- name: 'adapt gitolite-suexec-wrapper.sh'
  replace:
    backup: yes
    path: /var/www/bin/gitolite-suexec-wrapper.sh
    regexp: "/var/lib/gitolite"
    replace: "{{ gitolite_home }}"

task_install_riaf_gitolite_web_interface.yaml:

# https://docs.ansible.com/ansible/2.5/modules/pip_module.html

# gitolite_web_interface.py https://github.com/dlr-pa/gitolite_web_interface
- name: install gitolite_web_interface
  pip:
    name: https://github.com/dlr-pa/gitolite_web_interface/archive/refs/heads/master.zip

task_install_riaf_configuration_gitolite_web_interface.yaml:

# https://docs.ansible.com/ansible/2.5/modules/get_url_module.html
# https://docs.ansible.com/ansible/2.5/modules/blockinfile_module.html

# gitolite_web_interface.py https://github.com/dlr-pa/gitolite_web_interface
- name: 'install/get gitolite_web_interface.py'
  get_url:
    backup: yes
    dest: /var/www/bin/gitolite_web_interface.py
    group: "{{ gitolite_user }}"
    mode: 0700
    owner: "{{ gitolite_user }}"
    url: https://raw.githubusercontent.com/dlr-pa/gitolite_web_interface/master/gitolite_web_interface.py
- name: 'adapt gitolite_web_interface.py'
  blockinfile:
    backup: yes
    block: |
      CONFIG['gitolite_wrapper_script'] = \
          '/var/www/bin/gitolite-suexec-wrapper.sh'
      CONFIG['ssh_gitolite_user'] = '{{ gitolite_user }}'
      CONFIG['gitolite_home'] = '{{ gitolite_home }}'
      CONFIG['provided_options'] = {
          'help': True,
          'info': True,
          'mngkey': True,
          'creategroup': True,
          'createrepo': True}
    group: "{{ gitolite_user }}"
    marker: '# {mark} special setting'
    marker_begin: start
    marker_end: end
    mode: 0700
    owner: "{{ gitolite_user }}"
    path: /var/www/bin/gitolite_web_interface.py
    state: present

task_install_riaf_configuration_apache_gitolite_2.yaml:

# https://docs.ansible.com/ansible/2.5/modules/copy_module.html

- name: 'install index.html'
  copy:
    backup: yes
    dest: /var/www/gitolite/index.html
    group: "{{ gitolite_user }}"
    mode: 0644
    owner: "{{ gitolite_user }}"
    src: '{{ index_html }}'
  notify:
    - reload apache2
- name: restart apache2
  service:
    name: apache2
    state: restarted

task_install_riaf_gitolite_add_trigger_riaf_post_git.yaml:

# https://docs.ansible.com/ansible/2.5/modules/copy_module.html
# https://docs.ansible.com/ansible/2.5/modules/blockinfile_module.html
# https://docs.ansible.com/ansible/2.5/modules/pause_module.html

- name: 'install gitolite trigger server_timestamping'
  copy:
    backup: yes
    dest: /usr/share/gitolite3/triggers/server_timestamping
    mode: 0755
    src: '{{ server_timestamping_script }}'
- name: 'install gitolite trigger riaf_landing_page'
  copy:
    backup: yes
    dest: /usr/share/gitolite3/triggers/riaf_landing_page
    mode: 0755
    src: '{{ riaf_landing_page_script }}'
- name: 'add gitolite trigger server_timestamping and riaf_landing_page'
  blockinfile:
    backup: yes
    block: |

      # add gitolite trigger
      POST_GIT                 =>
      [
        'server_timestamping',
        'riaf_landing_page'
      ],
    group: "{{ gitolite_user }}"
    marker: '    # {mark}'
    marker_begin: "------------------------------------------------------------------"
    marker_end: "List of commands and features to enable"
    mode: 0700
    owner: "{{ gitolite_user }}"
    path: "{{ gitolite_home }}/.gitolite.rc"
    state: present
- name: "###### information gpg key ######"
  pause:
    seconds: 1
    prompt: 'You can put the gpg key id to use in the file {{ gitolite_home }}/.server_timestamping.cfg on the server. Otherwise a gpg key will be created.'

handler_install_riaf.yaml:

# https://docs.ansible.com/ansible/2.5/modules/service_module.html

- name: reload ssh
  service:
    name: ssh
    state: reloaded
- name: restart apache2
  service:
    name: apache2
    state: restarted
- name: reload apache2
  service:
    name: apache2
    state: reloaded

play_gitolite_home2zfs_filesystem.yaml

play_gitolite_home2zfs_filesystem.yaml

---
# ansible-playbook --ask-vault-pass -v play_gitolite_home2zfs_filesystem.yaml

- name: gitolite home -> zfs filesystem
  hosts: all
  become: yes
  tasks:
    - include: task_gitolite_home2zfs_filesystem.yaml

It uses the task task_gitolite_home2zfs_filesystem.yaml:

- name: move gitolite home to other
  shell: mv /data/gitolite /data/gitolite.bak
- name: create zfs filesystem data/gitolite
  shell: zfs create -o compression=on data/gitolite
- name: set rights (chown)
  shell: chown -R --reference=/data/gitolite.bak /data/gitolite
- name: set rights (chmod)
  shell: chmod --reference=/data/gitolite.bak /data/gitolite
- name: rsync
  shell: rsync --archive --one-file-system --links --hard-links --sparse /data/gitolite.bak/ /data/gitolite/
- name: rm
  shell: rm -rf /data/gitolite.bak
- name: move gitolite home to other
  shell: mv /data/gitolite/repositories /data/gitolite.bak
- name: create zfs filesystem data/gitolite
  shell: zfs create -o compression=on data/gitolite/repositories
- name: set rights (chown)
  shell: chown -R --reference=/data/gitolite.bak /data/gitolite/repositories
- name: set rights (chmod)
  shell: chmod --reference=/data/gitolite.bak /data/gitolite/repositories
- name: rsync
  shell: rsync --archive --one-file-system --links --hard-links --sparse /data/gitolite.bak/ /data/gitolite/repositories/
- name: rm
  shell: rm -rf /data/gitolite.bak

play_add_user.yaml

play_add_user.yaml

---
# ansible-playbook --ask-vault-pass -v play_add_user.yaml

- name: add user for basic authentication in apache
  hosts: all
  become: yes
  vars_prompt:
    - name: username
      prompt: "username"
      private: no
    - name: userpassword
      prompt: "userpassword"
    - name: gitolite_user
      prompt: "gitolite user name"
      default: "git"
      private: no
    - name: gitolite_home
      prompt: "path to the gitolite home directory (repositories are stored here)"
      default: "/data/gitolite"
      private: no
  tasks:
    - include: task_riaf_add_user.yaml

It uses the following tasks and handler:

task_riaf_add_user.yaml:

# https://docs.ansible.com/ansible/2.5/modules/htpasswd_module.html
# https://docs.ansible.com/ansible/2.5/modules/command_module.html

- name: install passlib
  apt:
    name:
      - python3-passlib
      - python3-bcrypt
    state: present
    force_apt_get: yes

- name: add user for basic authentication in apache
  htpasswd:
    crypt_scheme: bcrypt
    group: root
    mode: 0644
    name: "{{ username }}"
    owner: root
    password: "{{ userpassword }}"
    path: /etc/apache2/gitolite.passwd
- name: run update_list_all_users once now
  command: '{{ gitolite_home }}/bin/update_list_all_users'
  become: true
  become_method: sudo
  become_user: '{{ gitolite_user }}'

play_update.yaml

play_update.yaml

---
- name: update system
  hosts: all
  become: yes
  tasks:
    - include: task_update.yaml
    - include: task_install_pydabu.yaml
    - include: task_install_riaf_fuse_git_bare_fs.yaml
    - include: task_install_riaf_gitolite_web_interface.yaml

It uses the following tasks and handler:

task_update.yaml:

- name: update cache and update all packages
  apt:
    force_apt_get: yes
    name: "*"
    state: latest
    update_cache: yes

task_install_riaf_fuse_git_bare_fs.yaml