Snippets

Anton Shestakov hgweb-apache2-ansible

Created by Anton Shestakov last modified
---
- hosts: all
  become: yes
  vars:
    hostname: mydomain
  pre_tasks:
    # NOTE: you probably don't want to run these pre_tasks on a real box. Just
    # bear in mind that to be able to access hgweb from inside the box, you
    # need to use the virtual host name (i.e. http://127.0.0.1/ won't work).
    # So make sure you either have DNS records for hg.mydomain or it's in
    # /etc/hosts.
    - name: Set hostname
      hostname:
        name: '{{ hostname }}'
    - name: Update /etc/hosts
      lineinfile:
        dest: /etc/hosts
        line: '127.0.0.1 {{ hostname }} hg.{{ hostname }}'

    # NOTE: hgweb role depends on Apache httpd (and mod_wsgi) being installed.
    # It's recommended to install them in a separate apache2 role, not in
    # pre_tasks like in this example playbook.
    - name: Install Apache httpd
      apt:
        update_cache: yes
        cache_valid_time: 3600
        package: '{{ item }}'
        state: installed
      with_items:
        - apache2
        - libapache2-mod-wsgi
    - name: Enable mod_wsgi
      apache2_module:
        state: present
        name: wsgi
    - name: Disable default Apache httpd site
      file:
        path: /etc/apache2/sites-enabled/000-default.conf
        state: absent
  roles:
#    - role: apache2
#      tags: [apache2]
    - role: hgweb
      tags: [hgweb]
  handlers:
    # NOTE: hgweb role notifies this handler:
    # - restart apache2
    # Naturally, the handler is not defined in the role itself, so this example
    # playbook includes it here.
    - name: restart apache2
      service:
        name: apache2
        state: restarted
...
# NOTE: how to test that it works correctly (also see the note about DNS):
# curl -I http://hg.mydomain/
#   will check hgweb pages, look for "200 Script output follows" status
# curl -I http://hg.mydomain/static/mercurial.js
#   will check serving static files via Apache httpd, look for "200 OK" status
---
hgweb_contact: 'Me Myself <me@mydomain>'
hgweb_subdomain: hg
hgweb_user: hguser
hgweb_mercurial_url: https://www.mercurial-scm.org/repo/hg
hgweb_mercurial_rev: stable
hgweb_evolve_url: https://www.mercurial-scm.org/repo/evolve
hgweb_evolve_rev: stable
hgweb_workers: 1
...
User-agent: *

# Expensive pages
Disallow: /*/annotate/
Disallow: /*/comparison/
Disallow: /*/diff/
Disallow: /*/archive/

# File log is too much
Disallow: /*/log/*/

# API is off-limits
Disallow: /*/json-*
Disallow: /*/raw-*

# Paginate instead
Disallow: /*?revcount=

# Graph page is a more expensive log
Disallow: /*/graph$
Disallow: /*/graph/

# It's for humans
Disallow: /*/help$
Disallow: /*/help/
---
- name: make local
  command: make --directory /home/{{ hgweb_user }}/hg/ local
  become: yes
  become_user: '{{ hgweb_user }}'

- name: restart hgweb
  file:
    path: /home/{{ hgweb_user }}/hgwebfiles/hgweb.wsgi
    state: touch
...
---
- name: Ensure required directories exist
  file:
    path: /home/{{ hgweb_user }}/{{ item }}/
    state: directory
  with_items:
    - hgwebfiles
    - repos

- name: Pull Mercurial {{ hgweb_mercurial_rev }}
  hg:
    repo: '{{ hgweb_mercurial_url }}'
    dest: /home/{{ hgweb_user }}/hg/
    revision: '{{ hgweb_mercurial_rev }}'
  notify:
    - make local
    - restart hgweb
  tags: [inert]

- name: Pull Evolve {{ hgweb_evolve_rev }}
  hg:
    repo: '{{ hgweb_evolve_url }}'
    dest: /home/{{ hgweb_user }}/evolve/
    revision: '{{ hgweb_evolve_rev }}'
  notify:
    - restart hgweb
  tags: [inert]

- name: Add config files
  template:
    src: '{{ item }}'
    dest: /home/{{ hgweb_user }}/hgwebfiles/{{ item }}
  with_items:
    - hgweb.wsgi
    - hgweb.conf
  notify:
    - restart hgweb

- name: Copy robots.txt
  copy:
    src: robots.txt
    dest: /home/{{ hgweb_user }}/hgwebfiles/robots.txt
    mode: 0644
  tags: [robots]
...
---
- name: Create user
  user:
    name: '{{ hgweb_user }}'

- name: Install packages
  apt:
    pkg: '{{ item }}'
    state: present
  with_items:
    - build-essential
    - mercurial
    - python-dev
    - python-pygments  # for hightlight extension
  tags: [packages, inert]

- include: appinstall.yml
  become: yes
  become_user: '{{ hgweb_user }}'

- name: Add {{ hgweb_subdomain }}.{{ hostname }} Apache httpd site
  template:
    src: etc/apache2/sites-available/hgweb.conf
    dest: /etc/apache2/sites-available/{{ hgweb_subdomain }}.{{ hostname }}.conf
  notify:
    - restart apache2

- name: Enable {{ hgweb_subdomain }}.{{ hostname }} Apache httpd site
  file:
    src: /etc/apache2/sites-available/{{ hgweb_subdomain }}.{{ hostname }}.conf
    dest: /etc/apache2/sites-enabled/050-{{ hgweb_subdomain }}.{{ hostname }}.conf
    state: link
  notify:
    - restart apache2
...
[paths]
/ = /home/{{ hgweb_user }}/repos/*

[extensions]
highlight =
evolve.serveronly = /home/{{ hgweb_user }}/evolve/hgext3rd/evolve/serveronly.py

[web]
baseurl = http://{{ hgweb_subdomain }}.{{ hostname }}/
logourl = http://{{ hgweb_subdomain }}.{{ hostname }}/
staticurl = /static
contact = {{ hgweb_contact }}
pygments_style = tango
highlightfiles = size('<100k')
highlightonlymatchfilename = True
# Path to repo or hgweb config to serve (see 'hg help hgweb')
config = "/home/{{ hgweb_user }}/hgwebfiles/hgweb.conf"

# Uncomment and adjust if Mercurial is not installed system-wide
# (consult "installed modules" path from 'hg debuginstall'):
import sys; sys.path.insert(0, "/home/{{ hgweb_user }}/hg/")

# Uncomment to send python tracebacks to the browser if an error occurs:
#import cgitb; cgitb.enable()

# enable demandloading to reduce startup time
from mercurial import demandimport; demandimport.enable()

from mercurial.hgweb import hgweb
application = hgweb(config)
<VirtualHost *:80>
	ServerName {{ hgweb_subdomain }}.{{ hostname }}
	ServerAdmin webmaster@{{ hostname }}

	DocumentRoot /home/{{ hgweb_user }}/hg/mercurial/templates

	ErrorLog ${APACHE_LOG_DIR}/{{ hgweb_subdomain }}.{{ hostname }}.error.log
	CustomLog ${APACHE_LOG_DIR}/{{ hgweb_subdomain }}.{{ hostname }}.access.log combined
	# LogLevel info

	WSGIScriptAlias / /home/{{ hgweb_user }}/hgwebfiles/hgweb.wsgi
	WSGIProcessGroup hgweb
	WSGIDaemonProcess hgweb user='{{ hgweb_user }}' processes={{ hgweb_workers }}
	# home=/home/{{ hgweb_user }}/hgwebfiles/
	# group='{{ hgweb_user }}'
	# maximum-requests=100
	# umask=0027

	Alias /static/ /home/{{ hgweb_user }}/hg/mercurial/templates/static/
	<Directory /home/{{ hgweb_user }}/hg/mercurial/templates/static>
		Options -Indexes
		Require all granted
	</Directory>

	Alias /robots.txt /home/{{ hgweb_user }}/hgwebfiles/robots.txt
	<Directory /home/{{ hgweb_user }}/hgwebfiles>
		<Files hgweb.wsgi>
			Require all granted
		</Files>
		<Files robots.txt>
			Require all granted
		</Files>
	</Directory>

	Redirect 301 /favicon.ico /static/hgicon.png
</VirtualHost>

Comments (0)