From 9957096b834f28863c89bcea7b7984d99bac035c Mon Sep 17 00:00:00 2001
From: Disassembler
Date: Wed, 29 Nov 2017 20:01:17 +0100
Subject: [PATCH] Introduce install script for CTS
---
80-cts.sh | 65 +++++++++++++++++++++++++++
basic/srv/portal/img/CTS.png | Bin 0 -> 17279 bytes
basic/srv/portal/index.html | 9 ++++
cts/etc/nginx/sites-available/cts | 43 ++++++++++++++++++
cts/etc/uwsgi/apps-available/cts.ini | 8 ++++
cts/srv/cts/cts/settings/spotter.py | 46 +++++++++++++++++++
cts/tmp/cts-adminpwd.sql | 1 +
cts/tmp/cts-createdb.sql | 10 +++++
8 files changed, 182 insertions(+)
create mode 100644 80-cts.sh
create mode 100644 basic/srv/portal/img/CTS.png
create mode 100644 cts/etc/nginx/sites-available/cts
create mode 100644 cts/etc/uwsgi/apps-available/cts.ini
create mode 100644 cts/srv/cts/cts/settings/spotter.py
create mode 100644 cts/tmp/cts-adminpwd.sql
create mode 100644 cts/tmp/cts-createdb.sql
diff --git a/80-cts.sh b/80-cts.sh
new file mode 100644
index 0000000..ec72873
--- /dev/null
+++ b/80-cts.sh
@@ -0,0 +1,65 @@
+#!/bin/bash
+
+SOURCE_DIR=$(realpath $(dirname "${0}"))
+
+# Install packages
+apt-get -y --no-install-recommends install build-essential libpq-dev python-dev python-virtualenv virtualenv zlib1g-dev
+
+# Clone CTS git repository
+git clone --depth 1 https://github.com/theirc/CTS /srv/cts
+
+# Install CTS python virtual environment
+virtualenv --no-site-packages --python=/usr/bin/python2.7 /srv/cts
+/srv/cts/bin/pip install -r /srv/cts/requirements/production.txt
+
+# Create database
+export CTS_PWD=$(head -c 18 /dev/urandom | base64)
+envsubst <${SOURCE_DIR}/cts/tmp/cts-createdb.sql >/tmp/cts-createdb.sql
+sudo -u postgres psql -f /tmp/cts-createdb.sql
+rm /tmp/cts-createdb.sql
+
+# Configure CTS
+export CTS_SECRET=$(head -c 26 /dev/urandom | base64)
+envsubst <${SOURCE_DIR}/cts/srv/cts/cts/settings/spotter.py >/srv/cts/cts/settings/spotter.py
+ln -s /srv/cts/lib/python2.7/site-packages/django/contrib/admin/static/admin /srv/cts/cts/static/admin
+ln -s /srv/cts/lib/python2.7/site-packages/django_extensions/static/django_extensions /srv/cts/cts/static/django_extensions
+ln -s /srv/cts/lib/python2.7/site-packages/django_tables2/static/django_tables2 /srv/cts/cts/static/django_tables2
+ln -s /srv/cts/lib/python2.7/site-packages/leaflet/static/leaflet /srv/cts/cts/static/leaflet
+ln -s /srv/cts/lib/python2.7/site-packages/rest_framework/static/rest_framework /srv/cts/cts/static/rest_framework
+ln -s /srv/cts/lib/python2.7/site-packages/rest_framework_swagger/static/rest_framework_swagger /srv/cts/cts/static/rest_framework_swagger
+ln -s /srv/cts/lib/python2.7/site-packages/selectable/static/selectable /srv/cts/cts/static/selectable
+ln -s /srv/cts/lib/python2.7/site-packages/session_security/static/session_security /srv/cts/cts/static/session_security
+
+# Set "production values" (increases performance) only if the DEBUG environment variable is not set
+if [ ${DEBUG:-0} -eq 0 ]; then
+ sed -i 's/DEBUG = True/DEBUG = False/' /srv/cts/cts/settings/spotter.py
+fi
+
+# Populate database
+DJANGO_SETTINGS_MODULE=cts.settings.spotter /srv/cts/bin/python /srv/cts/manage.py migrate
+
+# Create admin account
+export CTS_ADMIN_EMAIL=admin@example.com
+export CTS_ADMIN_PWD=$(head -c 12 /dev/urandom | base64)
+export CTS_ADMIN_HASH=$(cd /srv/cts && DJANGO_SETTINGS_MODULE=cts.settings.spotter /srv/cts/bin/python -c "from django.contrib.auth.hashers import make_password; print make_password('${CTS_ADMIN_PWD}')")
+export CTS_ADMIN_SECRET=$(head -c 12 /dev/urandom | sha256sum | cut -c1-13)
+envsubst <${SOURCE_DIR}/cts/tmp/cts-adminpwd.sql >/tmp/cts-adminpwd.sql
+sudo -u postgres psql -f /tmp/cts-adminpwd.sql cts
+rm /tmp/cts-adminpwd.sql
+
+# Create CTS OS user
+adduser --system --group --home /srv/cts --shell /bin/false cts
+chown -R cts:cts /srv/cts
+
+# Create uwsgi and nginx app definition
+cp ${SOURCE_DIR}/cts/etc/uwsgi/apps-available/cts.ini /etc/uwsgi/apps-available/cts.ini
+ln -s /etc/uwsgi/apps-available/cts.ini /etc/uwsgi/apps-enabled/cts.ini
+cp ${SOURCE_DIR}/cts/etc/nginx/sites-available/cts /etc/nginx/sites-available/cts
+ln -s /etc/nginx/sites-available/cts /etc/nginx/sites-enabled/cts
+
+# Restart services
+systemctl restart uwsgi
+systemctl restart nginx
+
+# Add portal application definition
+${SOURCE_DIR}/basic/portal-app-manager.py cts "https://{host}:8004/" "${CTS_ADMIN_EMAIL}" "${CTS_ADMIN_PWD}"
diff --git a/basic/srv/portal/img/CTS.png b/basic/srv/portal/img/CTS.png
new file mode 100644
index 0000000000000000000000000000000000000000..9bd35f4b5eef8a268589332dcfa4e356a73b7cc3
GIT binary patch
literal 17279
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
T>4{I5CLqX4DoT`z8TtKx433CD
literal 0
HcmV?d00001
diff --git a/basic/srv/portal/index.html b/basic/srv/portal/index.html
index d14b716..8c584a0 100644
--- a/basic/srv/portal/index.html
+++ b/basic/srv/portal/index.html
@@ -160,6 +160,15 @@
+
Autonomní sociání síť s možností propojení do cizích sociálních sítí.
diff --git a/cts/etc/nginx/sites-available/cts b/cts/etc/nginx/sites-available/cts
new file mode 100644
index 0000000..0e38569
--- /dev/null
+++ b/cts/etc/nginx/sites-available/cts
@@ -0,0 +1,43 @@
+server {
+ listen 8004 ssl http2;
+
+ root /srv/cts/cts;
+
+ access_log /var/log/nginx/cts.access.log;
+ error_log /var/log/nginx/cts.error.log;
+
+ location /robots.txt {
+ alias /srv/cts/cts/static/robots.txt;
+ }
+
+ location /media {
+ alias /srv/cts/cts/media;
+ }
+
+ location /static {
+ gzip on;
+ alias /srv/cts/cts/static;
+ expires max;
+ add_header Cache-Control public;
+
+ location /static/protected {
+ return 401;
+ }
+ }
+
+ location /protected {
+ internal;
+ root /srv/cts/cts/static;
+ }
+
+ error_page 502 503 504 /502.html;
+
+ location /502.html {
+ alias /srv/cts/cts/static/502.html;
+ }
+
+ location / {
+ uwsgi_pass unix:///run/uwsgi/app/cts/socket;
+ include uwsgi_params;
+ }
+}
diff --git a/cts/etc/uwsgi/apps-available/cts.ini b/cts/etc/uwsgi/apps-available/cts.ini
new file mode 100644
index 0000000..5ccfa87
--- /dev/null
+++ b/cts/etc/uwsgi/apps-available/cts.ini
@@ -0,0 +1,8 @@
+[uwsgi]
+uid = cts
+gid = cts
+chown-socket = www-data:www-data
+chdir = /srv/cts
+home = /srv/cts
+module = cts.wsgi:application
+env = DJANGO_SETTINGS_MODULE=cts.settings.spotter
diff --git a/cts/srv/cts/cts/settings/spotter.py b/cts/srv/cts/cts/settings/spotter.py
new file mode 100644
index 0000000..3bd2f7f
--- /dev/null
+++ b/cts/srv/cts/cts/settings/spotter.py
@@ -0,0 +1,46 @@
+import os
+import sys
+
+os.environ['ENVIRONMENT'] = 'dev'
+os.environ['INSTANCE'] = 'local'
+os.environ['PREFIX_URL'] = ''
+
+from cts.settings.base import *
+
+INSTANCE_NAME = 'Local'
+INSTANCES = [
+ (INSTANCE_NAME, ''),
+]
+
+DATABASES = {
+ 'default': {
+ 'ENGINE': 'django.contrib.gis.db.backends.postgis',
+ 'NAME': 'cts',
+ 'USER': 'cts',
+ 'PASSWORD': '${CTS_PWD}',
+ 'HOST': '',
+ 'PORT': '',
+ }
+}
+SECRET_KEY = '${CTS_SECRET}'
+
+ADMINS = (
+ ('Admin', 'admin@example.com'),
+)
+
+INTERNAL_IPS = ('127.0.0.1', )
+PUBLIC_ROOT = os.path.join(PROJECT_ROOT, 'public')
+SENDFILE_ROOT = os.path.join(PUBLIC_ROOT, 'static/protected')
+COMPRESS_ENABLED = False
+
+EMAIL_BACKEND = 'django.core.mail.backends.console.EmailBackend'
+SERVER_EMAIL = 'cts@spotter.ngo'
+
+CELERY_ALWAYS_EAGER = True
+CELERY_EAGER_PROPAGATES_EXCEPTIONS = True
+
+TIME_ZONE = 'Europe/Prague'
+LANGUAGE_CODE = 'cs'
+
+DEBUG = True
+TEMPLATE_DEBUG = DEBUG
diff --git a/cts/tmp/cts-adminpwd.sql b/cts/tmp/cts-adminpwd.sql
new file mode 100644
index 0000000..f10ebd5
--- /dev/null
+++ b/cts/tmp/cts-adminpwd.sql
@@ -0,0 +1 @@
+INSERT INTO accounts_ctsuser (id, password, last_login, is_superuser, name, email, is_staff, is_active, date_joined, mobile, code, skype, notes, role, referrer_id, city_id, colour, deviceid) VALUES (nextval('accounts_ctsuser_id_seq'), '${CTS_ADMIN_HASH}', now(), true, '${CTS_ADMIN_USER}', '${CTS_ADMIN_EMAIL}', true, true, now(), '', '${CTS_ADMIN_SECRET}', '', '', 'partner', NULL, NULL, '', '');
diff --git a/cts/tmp/cts-createdb.sql b/cts/tmp/cts-createdb.sql
new file mode 100644
index 0000000..3c800c2
--- /dev/null
+++ b/cts/tmp/cts-createdb.sql
@@ -0,0 +1,10 @@
+CREATE ROLE cts NOSUPERUSER NOCREATEDB NOCREATEROLE NOINHERIT LOGIN ENCRYPTED PASSWORD '${CTS_PWD}';
+CREATE DATABASE cts;
+REVOKE ALL ON DATABASE cts FROM public;
+ALTER DATABASE cts OWNER TO cts;
+\c cts;
+CREATE EXTENSION hstore;
+CREATE EXTENSION postgis;
+GRANT ALL ON geometry_columns TO cts;
+GRANT ALL ON spatial_ref_sys TO cts;
+GRANT ALL ON geography_columns TO cts;