Note: This is partly based on the instructions at
https://ganetimgr.readthedocs.io/en/latest/install.html and https://ganetimgr.readthedocs.io/en/latest/version2.html
with some modifications (v2.0)
Most of the commands below will require root access, so we'll start by going to the root user (use su or sudo)
$ sudo -s
Password:
#
We'll need to be installing some packages from the backports repository, to avoid problems in the "stock" version of the packages that ship with Debian 8.
If you haven't already done so, create the file /etc/apt/sources.list.d/jessie-backports.list with the following contents:
deb http://httpredir.debian.org/debian/ jessie-backports main contrib non-free
Now, run apt-get update (as root) to update the package lists.
Next, we install the packages:
# apt-get install -t jessie-backports python-django gunicorn python-gevent
The rest of the packages we can install normally:
# apt-get install git nginx mysql-server beanstalkd memcached \
python-dev python-mysqldb python-paramiko python-ipaddr python-pycurl \
python-memcache python-bs4 python-recaptcha gettext python-daemon \
python-setproctitle python-django-jsonfield python-beanstalkc python-pip
When prompted for a password for the mysql root user, pick one and remember it.
A few remaining packages needs to be instaled using pip:
pip install django-registration-redux vncauthproxy
We'll create a startup script for the VNC proxy we just installed.
Create the file /lib/systemd/system/vncauthproxy.service
# editor /lib/systemd/system/vncauthproxy.service
And paste in the following lines:
[Unit]
Description=VNC AuthProxy
After=network.target auditd.service
[Service]
Environment='PIDFILE=/var/run/vncauthproxy/proxy.pid'
Environment='LOGFILE=/var/log/vncauthproxy/proxy.log'
Environment='PORT=8888'
Environment='INTERFACE=0.0.0.0'
EnvironmentFile=-/etc/default/vncauthproxy
ExecStart=/usr/local/bin/twistd --pidfile=${PIDFILE} --nodaemon --logfile=${LOGFILE} vncap -c tcp:${PORT}:interface=${INTERFACE}
[Install]
WantedBy=multi-user.target
Alias=vncauthproxy.service
Create the log and PID directories:
# mkdir /var/log/vncauthproxy
# mkdir /var/run/vncauthproxy
Now enable and start the service:
# systemctl enable vncauthproxy
# systemctl start vncauthproxy
You can verify it's running:
# ps ax | grep twistd
# tail /var/log/vncauthproxy/proxy.log
We have now started the VNC Auth Proxy that will allow for browser-based VNC consoles.
# mysql -u root -p
Enter password: <passwork picked earlier here>
mysql> CREATE DATABASE ganetimgr CHARACTER SET utf8;
mysql> CREATE USER 'ganetimgr'@'localhost' IDENTIFIED BY '<PICK_A_PASSWORD>';
mysql> GRANT ALL PRIVILEGES ON ganetimgr.* TO 'ganetimgr';
mysql> flush privileges;
mysql> exit
Test that the created database works:
# mysql -u ganetimgr -p ganetimgr
Enter password: <password_for_ganetimgr_db_user>
mysql> exit
# mkdir /srv/
# mkdir /var/log/ganetimgr
# cd /srv/
# git clone https://www.ws.nsrc.org/ganetimgr
# cd ganetimgr
# git checkout v2.0
Note: the "official" Git repo for GanetiMGR is here:
https://github.com/grnet/ganetimgr.git
... but we clone from the local copy on www.ws.nsrc.org so we don't have to wait too long.
# cd ganetimgr
# cp settings.py.dist settings.py
# editor settings.py
The following changes will need to be made
The first change to be made is to find:
ALLOWED_HOSTS = [
'.example.com', # Allow domain and subdomains
'.example.com.', # Also allow FQDN and subdomains
]
and change it to:
ALLOWED_HOSTS = [
'127.0.0.1',
]
Then, find the section:
ADMINS = (
('John Doe', 'john@example.com'),
)
Change the line above, adding and entry for the main admin user, for example:
ADMINS = (
('admin','your@email.address'),
)
Next, find the DATABASES section, and the line:
'ENGINE' : 'django.db.backends.',
And change it to:
'ENGINE' : 'django.db.backends.mysql'
This tells the Django application framework that we'll be using MySQL as a backend.
Next, set the NAME, USER and PASSWORD to those of the database you created earlier:
'NAME' : 'ganetimgr', # Or path to database file if using sqlite3.
'USER' : 'ganetimgr # Not used with sqlite3.
'PASSWORD' : '<PASSWORD_PICKED_EARLIER>', # Not used with sqlite3.
Set TIME_ZONE to your location, for instance:
TIME_ZONE = 'Africa/Nairobi'
Next, find the section:
SECRET_KEY = <CHANGE_ME>
And change it to a random string, for example:
SECRET_KEY = 'wlj84oaliehgzi48ol9qo3ijhesrbykjdzn,.38h,u4gbrg'
Please, don't copy the above key! Generate your own!
Comment out the sections OPERATING_SYSTEM_URLS and SNF_OPERATING_SYSTEMS_URLS for the time being, so they look like:
# OPERATING_SYSTEMS_URLS = ['http://repo.noc.grnet.gr/images/']
# SNF_OPERATING_SYSTEMS_URLS = ['http://repo.noc.grnet.gr/images/snf-image/']
Next, find SERVER_EMAIL and DEFAULT_FROM_EMAIL and set them accordingly, for example:
SERVER_EMAIL = "ganetimgr@ganetimgr.ws.nsrc.org"
DEFAULT_FROM_EMAIL = "ganetimgr@ganetimgr.ws.nsrc.org"
Find COLLECTD_URL, and comment it out:
# COLLECTD_URL = "http://stats.example.com"
Find the section concerning the websockets console:
# This is meant to be used with twistednovncauthproxy
# twistd --pidfile=/tmp/proxy.pid -n vncap -c tcp:8888:interface=0.0.0.0
NOVNC_PROXY = "example.com:8888"
NOVNC_USE_TLS = True
And change it as follows:
NOVNC_PROXY = "ip.of.this.machine:8888"
NOVNC_USE_TLS = False
... where ip.of.this.machine is the IP of the machine that ganetimgr is being installed on. It's preferable to use a hostname, i.e.: ganetimgr.ws.nsrc.org.
Set up caching - find the CACHING section:
#CACHES = {
# 'default': {
# 'BACKEND': 'django.core.cache.backends.memcached.MemcachedCache',
# 'LOCATION': '127.0.0.1:11211',
# 'TIMEOUT': 1,
# }
#}
And uncomment it, so it looks like this:
CACHES = {
'default': {
'BACKEND': 'django.core.cache.backends.memcached.MemcachedCache',
'LOCATION': '127.0.0.1:11211',
'TIMEOUT': 1,
}
}
Find the line:
NODATA_IMAGE = 'static/nodata.gif'
And change it to:
NODATA_IMAGE = 'static/ganetimgr/img/nodata.jpg'
Find:
TEST_RUNNER = 'django.test.simple.DjangoTestSuiteRunner'
and replace it with
TEST_RUNNER = 'django.test.runner.DiscoverRunner'
Lastly, find the BRANDING section and update it with the information for your organization.
Finally, it's time to get the database populated and create a user:
# cd /srv/ganetimgr
# python manage.py syncdb --noinput
If everything goes well some output about tables being created will scroll past, and end with something similar to:
...
Applying ganeti.0003_auto_20170807_1459... OK
Applying notifications.0001_initial... OK
Applying sessions.0001_initial... OK
One more command to run:
# python manage.py migrate
Again, some output will flash by. If nothing needed to be done, it should end with:
...
Running migrations:
No migrations to apply.
Now, let's create a user:
# python manage.py createsuperuser
Here, we'll create an admin user, so at the question:
Username (leave blank to use 'root'):
Enter admin
Next, you'll be prompted for an email address. Here, you can enter your email address, although for testing it might be better to start by using the mail address of the local user, root@ganetimgr.ws.nsrc.org.
Finally, you'll be asked to provide a password. Don't use something too easy to guess when deploying this in production!
If all goes well, you'll see:
Superuser created successfully.
The next command creates the pages that will be displayed in the administrative interface:
# cd /srv/ganetimgr
# python manage.py collectstatic
You will be prompted:
This will overwrite existing files!
Are you sure you want to do this?
Type 'yes' to continue, or 'no' to cancel:
Answer yes and press <enter>.
This is responsible for tracking the state of jobs (tasks)
We'll create a startup script for the GanetiMgr Watcher
Create the file /lib/systemd/system/ganetimgr-watcher.service
[Unit]
Description=GanetiMgr watcher
After=network.target auditd.service
[Service]
Environment='PIDFILE=/var/run/ganetimgr-watcher/ganetimgr-watcher.pid'
Environment='LOGFILE=/var/log/ganetimgr/watcher.log'
ExecStart=/srv/ganetimgr/watcher.py
[Install]
WantedBy=multi-user.target
Alias=ganetimgr-watcher.service
Create the log directory:
# mkdir /var/run/ganetimgr-watcher
Now enable and start the service:
# systemctl enable ganetimgr-watcher
# systemctl start ganetimgr-watcher
Verify that it is running:
# ps ax | grep watcher.py
gunicorn is a python web server, which will run the Ganeti Manager application.
We'll start by using a sample configuration provided with ganetimgr:
# mkdir /etc/gunicorn.d
# cd /srv/ganetimgr
# cp contrib/gunicorn/ganetimgr_jessie /etc/gunicorn.d/ganetimgr
Now edit the file /etc/gunicorn.d/ganetimgr, and update the config section to look like:
CONFIG = {
'mode': 'wsgi',
'user': 'www-data',
'group': 'www-data',
'args': (
'--chdir=/srv/ganetimgr',
'--bind=0.0.0.0:8088',
'--workers=2',
'--worker-class=gevent',
'--timeout=30',
'--log-file=/var/log/ganetimgr/ganetimgr.log',
'ganetimgr.wsgi:application',
),
}
# service gunicorn restart
Nginx, the web server, runs as the "front-end" for gunicorn.
Here's a minimal configuration get the web interface up and running:
Edit the file /etc/nginx/sites-enabled/default, erasing ALL THE LINES IN THE FILE, and copy the following lines into it:
server {
server_name ganetimgr.ws.nsrc.org; # replace with your hostname
location / {
proxy_pass http://127.0.0.1:8088;
}
location /static {
root /srv/ganetimgr;
}
}
Test the configuration:
# service nginx configtest
And if all is well, proceed to restart nginx:
# service nginx restart
We now need to create a user on the Ganeti cluster nodes, that will allow Ganeti Manager to control the cluster.
Pick a random string (for example, generate it with):
head -c18 /dev/urandom | base64
... and run it through the following command (replace 'random_string' with the output from the previous command)
echo -n 'ganetimgr_api_user:Ganeti Remote API:random_string' | openssl md5
Note that random string should probably not contain ':'.
Here's a sample output, which is a hashed password:
b20990f88c544cea982645e99b08d8c8
The final authentication / authorization line will look like this:
ganetimgr_api_user {HA1}b20990f88c544cea982645e99b08d8c8 write
... where write indicates that this user ganetimgr_api_user has write access to the cluster (i.e: can modify/create/delete instances!)
Now, on the master node (NOT ON THE GANETIMGR MACHINE!), create the following file (as root):
# editor /var/lib/ganeti/rapi/users
... and copy the authentication/authorization line, with the correct hashed password.
Once you've done this, distribute this file to the other nodes in the cluster with the following command:
# gnt-cluster copyfile /var/lib/ganeti/rapi/users
We have to make one more change, so that the Ganeti RAPI (Remote API) becomes reachable over the network - for security reasons, it's disabled by default.
To make this happen, on the master node, edit the ganeti daemon config file:
# editor /etc/default/ganeti
And change the line:
RAPI_ARGS="-b 127.0.0.1 --require-authentication"
So it looks like:
RAPI_ARGS="--require-authentication"
... save the file and exit.
Copy the file to all nodes:
# gnt-cluster copyfile /etc/default/ganeti
And finally, restart Ganeti:
# service ganeti restart
That's it! We are now ready to test the front-end!
Open http://ganetimgr.ws.nsrc.org/ in your browser.
You should be presented with the login screen.
Login with the admin user and password you created earlier.
Now, click on Admin in the top menu.
Click on Add next to Clusters under the Ganeti section.
For hostname, enter the hostname (it must be in the DNS!) of the cluster, i.e.: gnt.ws.nsrc.org.
For the "Slug", you can put "nsrc" for instance. It's best to avoid '-' in the cluster name, it seems.
For username, use the ganetimgr_api_user specified earlier.
For password, you use the randomly generated password (NOT the hashed version!) created earlier.
Click Save
Now it's time to navigate back to the mainpage:
`http://ganetimgr.ws.nsrc.org`
At this point, we are ready to add VMs!
/etc/hosts on ganetimgrWe have the cluster node names and the ganetimgr host names in /etc/hosts as vncauthproxy uses gevent and greenlets for the event loop and connection handling / forwarding. gevent (<1.0beta) uses libevent2 and its async DNS resolver, and libevent2-dns doesn't read /etc/hosts.
If you get this when trying to open the web page for ganetimgr, then check the Gunicorn log:
# tail -f /var/log/ganetimgr/ganetimgr.log
If you see the error "ImportError: No module named urls"
... then you may need to make the following change.
# cd /srv/ganetimgr
# editor accounts/urls.py
Find the line:
(r'^', include('registration.backends.admin_approval.urls')),
And comment it out:
# (r'^', include('registration.backends.admin_approval.urls')),
Save the file and exit, then restart the Gunicorn server:
# service gunicorn restart