Set up or update a trac project.

    This trac installation uses python2, git, sqlite (trac-default), gunicorn,
    and nginx.

    The connection is https-only and secured by a letsencrypt certificate.  This
    certificate must be created separately with task setup.server_letsencrypt.

    This task installes or updates to the latest trac version hosted at
    https://pypi.python.org/pypi/Trac

    Created and modified files and dirs of this task:

        ```
        ~/sites/<sitename>      <--- example: sitename = trac.example.com
        │
        ├── backup.sh           <--- create a local backup (deletes dir backup/
        ├── backup                                     |    before it creates
        │   └── <sitename>_tracenv_hotcopy.tar.gz  <--´     the tarball)
        ├── run
        │   └── trac.sock       <--- file-socket for binding to nginx
        ├── scripts
        │   └── tracwsgi.py
        ├── tracenv
        │   ├── conf
        │   │   ├── trac.htpasswd   <--- trac user password hashes
        │   │   └── trac.ini        <--- trac config file
        │   ├── db
        │   │   └── trac.db         <--- sqlite database
        │   ├── files
        │   ├── git
        │   ├── htdocs
        │   ├── log
        │   ├── plugins
        │   ├── README
        │   ├── templates
        │   └── VERSION
        └── virtualenv
            ├── bin
            ├── include
            ├── lib
            ├── local
            └── pip-selfcheck.json
        ```

    How to create a backup tarball "manually":
    `~/sites/<sitename>/backup/tracenv_hotcopy_<yyyy-mm-dd>.tar.gz`:

        ```
        cd ~/sites/<sitename>  &&  rm -rf ./backup
        ./virtualenv/bin/trac-admin ./tracenv  hotcopy ./backup/tracenv_hotcopy
        mkdir -p ./backup  &&  cd ./backup
        tar czf <sitename>_tracenv_hotcopy_$(date +%F).tar.gz  tracenv_hotcopy/
        rm -rf tracenv_hotcopy; ls -hl
        ```

    More infos:
      https://trac.edgewall.org/wiki/TracInstall
      https://trac.edgewall.org/wiki/TracFastCgi#NginxConfiguration
      https://trac.edgewall.org/wiki/TracNginxRecipe
      https://trac.edgewall.org/wiki/Gunicorn
      http://www.obeythetestinggoat.com/book/chapter_08.html#_getting_to_a_production_ready_deployment
      Setting REMOTE_USER for Trac in Gunicorn behind Nginx:
        http://serverfault.com/a/392096
      https://trac.edgewall.org/wiki/TracBackup

def trac():
    '''Set up or update a trac project.

    This trac installation uses python2, git, sqlite (trac-default), gunicorn,
    and nginx.

    The connection is https-only and secured by a letsencrypt certificate.  This
    certificate must be created separately with task setup.server_letsencrypt.

    This task installes or updates to the latest trac version hosted at
    https://pypi.python.org/pypi/Trac

    Created and modified files and dirs of this task:

        ```
        ~/sites/<sitename>      <--- example: sitename = trac.example.com
        │
        ├── backup.sh           <--- create a local backup (deletes dir backup/
        ├── backup                                     |    before it creates
        │   └── <sitename>_tracenv_hotcopy.tar.gz  <--´     the tarball)
        ├── run
        │   └── trac.sock       <--- file-socket for binding to nginx
        ├── scripts
        │   └── tracwsgi.py
        ├── tracenv
        │   ├── conf
        │   │   ├── trac.htpasswd   <--- trac user password hashes
        │   │   └── trac.ini        <--- trac config file
        │   ├── db
        │   │   └── trac.db         <--- sqlite database
        │   ├── files
        │   ├── git
        │   ├── htdocs
        │   ├── log
        │   ├── plugins
        │   ├── README
        │   ├── templates
        │   └── VERSION
        └── virtualenv
            ├── bin
            ├── include
            ├── lib
            ├── local
            └── pip-selfcheck.json
        ```

    How to create a backup tarball "manually":
    `~/sites/<sitename>/backup/tracenv_hotcopy_<yyyy-mm-dd>.tar.gz`:

        ```
        cd ~/sites/<sitename>  &&  rm -rf ./backup
        ./virtualenv/bin/trac-admin ./tracenv  hotcopy ./backup/tracenv_hotcopy
        mkdir -p ./backup  &&  cd ./backup
        tar czf <sitename>_tracenv_hotcopy_$(date +%F).tar.gz  tracenv_hotcopy/
        rm -rf tracenv_hotcopy; ls -hl
        ```

    More infos:
      https://trac.edgewall.org/wiki/TracInstall
      https://trac.edgewall.org/wiki/TracFastCgi#NginxConfiguration
      https://trac.edgewall.org/wiki/TracNginxRecipe
      https://trac.edgewall.org/wiki/Gunicorn
      http://www.obeythetestinggoat.com/book/chapter_08.html#_getting_to_a_production_ready_deployment
      Setting REMOTE_USER for Trac in Gunicorn behind Nginx:
        http://serverfault.com/a/392096
      https://trac.edgewall.org/wiki/TracBackup
    '''
    hostname = re.sub(r'^[^@]+@', '', env.host)  # without username if any
    sitename = query_input(
                   question='\nEnter site-name of Your trac web service',
                   default=flo('trac.{hostname}'))
    username = env.user

    site_dir = flo('/home/{username}/sites/{sitename}')
    bin_dir = flo('{site_dir}/virtualenv/bin')

    # provisioning steps
    install_or_upgrade_virtualenv_pip_package()
    create_directory_structure(site_dir)
    update_virtualenv(site_dir, sitename)
    set_up_trac_plugins(sitename, site_dir, bin_dir)
    set_up_gunicorn(site_dir, sitename)
    configure_nginx(username, sitename, hostname)

    if query_yes_no('\nRestore trac environment from backup tarball?',
                    default='no'):
        restore_tracenv_from_backup_tarball(site_dir, bin_dir)
    elif not tracenv_exists(site_dir):
        init_tracenv(site_dir, bin_dir, username)

    upgrade_tracenv(site_dir, bin_dir)

    set_up_upstart_for_gunicorn(sitename, username, site_dir)