Deploy
======

This tutorial describes the installation of a production environment. To
have a fully working environment, you have to set up the other components
as well. The full procedure is included in the :doc:`Puppet recipes
<puppet>` available for CIRCLE Cloud.

This component should normally deployed to a single head node.
This is the web-based entry point to the end users, and also the manager of
the compute and storage nodes.

Preparation
-----------

To get the project running, launch a new Ubuntu 14.04 machine, and
log in to it over SSH.


.. warning::
  If the first character of the hostname should not be a digit, because
  RabbitMQ won't work with it.

  The machine should have an :abbr:`fqdn (fully qualified domain name)`,
  which shoud be correctly printed by :kbd:`hostname -f`. You can achieve
  this with an IP address (e.g. 127.0.1.1) in :file:`/etc/hosts` having the
  short hostname as first, and the fqdn as second alias).


Setting up required software
----------------------------

Update the package lists, and install the required system software::

  sudo apt-get update
  sudo apt-get install --yes virtualenvwrapper postgresql git \
    python-pip rabbitmq-server libpq-dev python-dev ntp memcached \
    libmemcached-dev gettext wget pwgen nginx

Set up *PostgreSQL* to listen on localhost and restart it::

  sudo sed -i /etc/postgresql/9.1/main/postgresql.conf -e '/#listen_addresses/ s/^#//'
  sudo /etc/init.d/postgresql restart

Also, create a new database and user::

  pwgen 12 >pgpw
  sudo -u postgres createuser -S -D -R circle
  sudo -u postgres psql <<<"ALTER USER circle WITH PASSWORD '$(cat pgpw)';"
  sudo -u postgres createdb circle -O circle

Configure RabbitMQ: remove the guest user, add virtual host and user with
proper permissions::

  pwgen 12 >rmqpw
  sudo rabbitmqctl delete_user guest
  sudo rabbitmqctl add_vhost circle
  sudo rabbitmqctl add_user cloud $(cat rmqpw)
  sudo rabbitmqctl set_permissions -p circle cloud '.*' '.*' '.*'

Set up nginx to serve the CIRCLE portal. ::

  sudo tee /etc/nginx/conf.d/default.conf <<END
    ignore_invalid_headers   on;
    server {
        listen 443 ssl default;
        ssl on;
        ssl_certificate /etc/ssl/certs/ssl-cert-snakeoil.pem;
        ssl_certificate_key /etc/ssl/private/ssl-cert-snakeoil.key;
        location /static {
            alias ${PWD}/circle/static_collected;     # your Django project's static files
        }
        location / {
            uwsgi_pass  unix:///tmp/uwsgi.sock;
            include     /etc/nginx/uwsgi_params; # or the uwsgi_params you installed manually
        }
        location /vnc/ {
            proxy_pass http://localhost:9999;
            proxy_set_header X-Real-IP \$remote_addr;
            proxy_set_header Host \$host;
            proxy_set_header X-Forwarded-For \$proxy_add_x_forwarded_for;
            # WebSocket support (nginx 1.4)
            proxy_http_version 1.1;
            proxy_set_header Upgrade \$http_upgrade;
            proxy_set_header Connection "upgrade";
        }
    }

    server {
      listen 80 default;
      rewrite ^ https://\$host/;  # permanent;
    }
  END
  sudo /etc/init.d/nginx restart

.. warning::
  For a production deployment, you should use certificates issued by a
  recognized certificate authority. Until you get it, you can use a
  self-signed one automatically generated by the package.

Setting up Circle itself
------------------------

Clone the git repository::

  git clone https://git.ik.bme.hu/circle/cloud.git circle

Set up *virtualenvwrapper* and the *virtual Python environment* for the
project::

  source /etc/bash_completion.d/virtualenvwrapper
  mkvirtualenv circle

Set up default Circle configuration and activate the virtual environment::

  cat >>/home/cloud/.virtualenvs/circle/bin/postactivate <<END
  export DJANGO_SETTINGS_MODULE=circle.settings.production
  export DJANGO_DB_HOST=localhost
  export DJANGO_DB_PASSWORD=$(cat pgpw)
  export DJANGO_FIREWALL_SETTINGS='{"dns_ip": "152.66.243.60", "dns_hostname":
              "localhost", "dns_ttl": "300", "reload_sleep": "10",
              "rdns_ip": "152.66.243.60", "default_vlangroup": "publikus"}'
  export AMQP_URI='amqp://cloud:$(cat rmqpw)@localhost:5672/circle'
  export CACHE_URI='pylibmc://127.0.0.1:11211/'
  END
  workon circle
  cd ~/circle

You should change DJANGO_FIREWALL_SETTINGS to your needs.

Install the required Python libraries to the virtual environment::

  pip install -r requirements.txt

Sync the database and create a superuser::

  circle/manage.py syncdb --all --noinput
  circle/manage.py migrate --fake
  circle/manage.py createsuperuser

Copy the init files to Upstart's config directory and start the manager and
the portal application server::

  sudo cp miscellaneous/mancelery.conf /etc/init/
  sudo start mancelery
  sudo cp miscellaneous/portal-uwsgi.conf /etc/init/
  sudo start portal-uwsgi