Page MenuHomeGRNET

No OneTemporary

File Metadata

Created
Mon, Nov 25, 6:54 PM
diff --git a/Dockerfile b/Dockerfile
new file mode 100644
index 0000000..a8c6a3e
--- /dev/null
+++ b/Dockerfile
@@ -0,0 +1,31 @@
+FROM debian:wheezy
+
+RUN apt-get update -q
+RUN DEBIAN_FRONTEND=noninteractive apt-get install --quiet --yes git procps apt-utils
+RUN DEBIAN_FRONTEND=noninteractive apt-get install --no-install-recommends --quiet --yes python-django python-redis python-mysqldb python-django-south python-django-registration python-paramiko python-simplejson python-daemon python-setproctitle python-pycurl python-recaptcha python-ipaddr python-bs4 python-requests python-markdown
+RUN DEBIAN_FRONTEND=noninteractive apt-get install --quiet --yes gunicorn python-gevent beanstalkd nginx redis-server
+
+ADD python-django-markdown_0.6.1-1_all.deb /
+RUN dpkg -i /python-django-markdown_0.6.1-1_all.deb
+
+WORKDIR /srv
+RUN git clone --quiet https://github.com/grnet/ganetimgr.git
+
+COPY settings.py ganetimgr/ganetimgr/settings.py
+COPY dj_database_url.py ganetimgr/dj_database_url.py
+COPY ganetimgr.nginx.conf /etc/nginx/nginx.conf
+COPY ganetimgr.gunicorn.conf /etc/gunicorn/ganetimgr.conf
+COPY beanstalkd.conf /etc/default/beanstalkd
+#COPY run.sh /
+
+#RUN cp ganetimgr/ganetimgr/settings.py.dist ganetimgr/ganetimgr/settings.py
+RUN cp ganetimgr/templates/includes/analytics.html.dist ganetimgr/templates/includes/analytics.html
+RUN ./ganetimgr/manage.py syncdb --noinput
+#RUN echo "from django.contrib.auth.models import User; User.objects.create_superuser('admin', 'admin@example.com', DJANGO_ADMIN_PASS)" | python manage.py shell
+RUN ./ganetimgr/manage.py migrate
+RUN ./ganetimgr/manage.py collectstatic --noinput
+
+EXPOSE 80
+EXPOSE 8000
+#ENTRYPOINT bash /run.sh
+ENTRYPOINT nginx && ./ganetimgr/manage.py runserver 0.0.0.0:8080
diff --git a/README.md b/README.md
new file mode 100644
index 0000000..43cfa5d
--- /dev/null
+++ b/README.md
@@ -0,0 +1,12 @@
+ganetimgr-docker
+================
+
+docker build -t grnet/ganetimgr .
+
+docker run -p 80:80 grnet/ganetimgr:latest
+
+docker exec -ti ganetimgr /bin/bash
+
+
+from django.contrib.auth.models import User; User.objects.create_superuser('admin', 'admin@example.com','12345')
+
diff --git a/beanstalkd.conf b/beanstalkd.conf
new file mode 100644
index 0000000..4e2bd84
--- /dev/null
+++ b/beanstalkd.conf
@@ -0,0 +1,9 @@
+## Defaults for the beanstalkd init script, /etc/init.d/beanstalkd on
+## Debian systems. Append ``-b /var/lib/beanstalkd'' for persistent
+## storage.
+BEANSTALKD_LISTEN_ADDR=0.0.0.0
+BEANSTALKD_LISTEN_PORT=11300
+DAEMON_OPTS="-l $BEANSTALKD_LISTEN_ADDR -p $BEANSTALKD_LISTEN_PORT"
+
+## Uncomment to enable startup during boot.
+START=yes
diff --git a/dj_database_url.py b/dj_database_url.py
new file mode 100644
index 0000000..e269e9e
--- /dev/null
+++ b/dj_database_url.py
@@ -0,0 +1,129 @@
+# -*- coding: utf-8 -*-
+
+import os
+
+try:
+ import urlparse
+except ImportError:
+ import urllib.parse as urlparse
+
+
+# Register database schemes in URLs.
+urlparse.uses_netloc.append('postgres')
+urlparse.uses_netloc.append('postgresql')
+urlparse.uses_netloc.append('pgsql')
+urlparse.uses_netloc.append('postgis')
+urlparse.uses_netloc.append('mysql')
+urlparse.uses_netloc.append('mysql2')
+urlparse.uses_netloc.append('mysqlgis')
+urlparse.uses_netloc.append('mysql-connector')
+urlparse.uses_netloc.append('spatialite')
+urlparse.uses_netloc.append('sqlite')
+urlparse.uses_netloc.append('oracle')
+urlparse.uses_netloc.append('oraclegis')
+urlparse.uses_netloc.append('redshift')
+
+DEFAULT_ENV = 'DATABASE_URL'
+
+SCHEMES = {
+ 'postgres': 'django.db.backends.postgresql_psycopg2',
+ 'postgresql': 'django.db.backends.postgresql_psycopg2',
+ 'pgsql': 'django.db.backends.postgresql_psycopg2',
+ 'postgis': 'django.contrib.gis.db.backends.postgis',
+ 'mysql': 'django.db.backends.mysql',
+ 'mysql2': 'django.db.backends.mysql',
+ 'mysqlgis': 'django.contrib.gis.db.backends.mysql',
+ 'mysql-connector': 'mysql.connector.django',
+ 'spatialite': 'django.contrib.gis.db.backends.spatialite',
+ 'sqlite': 'django.db.backends.sqlite3',
+ 'oracle': 'django.db.backends.oracle',
+ 'oraclegis': 'django.contrib.gis.db.backends.oracle',
+ 'redshift': 'django_redshift_backend',
+}
+
+
+def config(env=DEFAULT_ENV, default=None, engine=None, conn_max_age=0):
+ """Returns configured DATABASE dictionary from DATABASE_URL."""
+
+ config = {}
+
+ s = os.environ.get(env, default)
+
+ if s:
+ config = parse(s, engine, conn_max_age)
+
+ return config
+
+
+def parse(url, engine=None, conn_max_age=0):
+ """Parses a database URL."""
+
+ if url == 'sqlite://:memory:':
+ # this is a special case, because if we pass this URL into
+ # urlparse, urlparse will choke trying to interpret "memory"
+ # as a port number
+ return {
+ 'ENGINE': SCHEMES['sqlite'],
+ 'NAME': ':memory:'
+ }
+ # note: no other settings are required for sqlite
+
+ # otherwise parse the url as normal
+ config = {}
+
+ url = urlparse.urlparse(url)
+
+ # Split query strings from path.
+ path = url.path[1:]
+ if '?' in path and not url.query:
+ path, query = path.split('?', 2)
+ else:
+ path, query = path, url.query
+ query = urlparse.parse_qs(query)
+
+ # If we are using sqlite and we have no path, then assume we
+ # want an in-memory database (this is the behaviour of sqlalchemy)
+ if url.scheme == 'sqlite' and path == '':
+ path = ':memory:'
+
+ # Handle postgres percent-encoded paths.
+ hostname = url.hostname or ''
+ if '%2f' in hostname.lower():
+ hostname = hostname.replace('%2f', '/').replace('%2F', '/')
+
+ # Update with environment configuration.
+ config.update({
+ 'NAME': urlparse.unquote(path or ''),
+ 'USER': urlparse.unquote(url.username or ''),
+ 'PASSWORD': urlparse.unquote(url.password or ''),
+ 'HOST': hostname,
+ 'PORT': url.port or '',
+ 'CONN_MAX_AGE': conn_max_age,
+ })
+
+ # Lookup specified engine.
+ engine = SCHEMES[url.scheme] if engine is None else engine
+
+ # Pass the query string into OPTIONS.
+ options = {}
+ for key, values in query.items():
+ if url.scheme == 'mysql' and key == 'ssl-ca':
+ options['ssl'] = {'ca': values[-1]}
+ continue
+
+ options[key] = values[-1]
+
+ # Support for Postgres Schema URLs
+ if 'currentSchema' in options and engine in (
+ 'django.db.backends.postgresql_psycopg2',
+ 'django_redshift_backend',
+ ):
+ options['options'] = '-c search_path={0}'.format(options.pop('currentSchema'))
+
+ if options:
+ config['OPTIONS'] = options
+
+ if engine:
+ config['ENGINE'] = engine
+
+ return config
diff --git a/docker-compose.yml b/docker-compose.yml
new file mode 100644
index 0000000..2ebb006
--- /dev/null
+++ b/docker-compose.yml
@@ -0,0 +1,24 @@
+version: "2"
+
+services:
+
+ beanstalkd:
+ image: agaveapi/beanstalkd
+
+ database:
+ image: mysql
+ environment:
+ MYSQL_ROOT_PASSWORD=
+ MYSQL_USER=ganetimgr
+ MYSQL_PASSWORD=
+ MYSQL_DATABASE=ganetimgr
+
+ worker:
+ build:
+ context: .
+ dockerfile: Dockerfile
+ links:
+ - beanstalkd
+ depends_on:
+ - database
+ - beanstalkd
diff --git a/ganetimgr.gunicorn.conf b/ganetimgr.gunicorn.conf
new file mode 100644
index 0000000..7b938cc
--- /dev/null
+++ b/ganetimgr.gunicorn.conf
@@ -0,0 +1,12 @@
+CONFIG = {
+ 'mode': 'django',
+ 'working_dir': '/srv/ganetimgr',
+ 'user': 'www-data',
+ 'group': 'www-data',
+ 'args': (
+ '--bind=127.0.0.1:8088',
+ '--workers=1',
+ '--worker-class=egg:gunicorn#gevent',
+ '--timeout=30',
+ ),
+}
diff --git a/ganetimgr.nginx.conf b/ganetimgr.nginx.conf
new file mode 100644
index 0000000..87b57e8
--- /dev/null
+++ b/ganetimgr.nginx.conf
@@ -0,0 +1,26 @@
+worker_processes 1;
+
+events {
+ worker_connections 1024;
+}
+
+http {
+ include mime.types;
+
+ server {
+ listen 80;
+ server_name _;
+
+ access_log /dev/stdout;
+ error_log /dev/stdout info;
+
+ location /static {
+ alias /srv/ganetimgr/static;
+ }
+
+ location / {
+ proxy_pass http://localhost:8080;
+ include proxy_params;
+ }
+ }
+}
diff --git a/python-django-markdown_0.6.1-1_all.deb b/python-django-markdown_0.6.1-1_all.deb
new file mode 100644
index 0000000..1ad0720
Binary files /dev/null and b/python-django-markdown_0.6.1-1_all.deb differ
diff --git a/run.sh b/run.sh
new file mode 100644
index 0000000..6caae93
--- /dev/null
+++ b/run.sh
@@ -0,0 +1,4 @@
+#!/bin/bash
+/etc/init.d/beanstalkd start
+/etc/init.d/redis-server start
+/etc/init.d/gunicorn start
diff --git a/settings.py b/settings.py
new file mode 100644
index 0000000..073af51
--- /dev/null
+++ b/settings.py
@@ -0,0 +1,336 @@
+# -*- coding: utf-8 -*- vim:fileencoding=utf-8:
+import os
+import dj_database_url
+BASE_DIR = os.path.dirname(os.path.dirname(__file__))
+PROJECT_DIR = os.path.join(BASE_DIR, 'ganetimgr')
+
+DATABASES= {}
+
+DATABASES['default'] = dj_database_url.config(default='sqlite:////%s' % os.path.join(BASE_DIR, 'db.sqlite3'))
+
+DEBUG = True
+ALLOWED_HOSTS=["*"]
+TEMPLATE_DEBUG = DEBUG
+
+SITE_ID = 1
+
+# Time zone & localization
+TIME_ZONE = 'Europe/Athens'
+
+_ = lambda s: s
+
+LANGUAGES = (
+# ('el', u'Ελληνικά'),
+ ('en', _('English')),
+)
+
+#LANGUAGE_CODE = 'en-us'
+
+LOCALE_PATHS = (
+ os.path.join(BASE_DIR, 'locale'),
+)
+
+DATE_FORMAT = "d/m/Y H:i"
+DATETIME_FORMAT = "d/m/Y H:i"
+
+
+# If you set this to False, Django will make some optimizations so as not
+# to load the internationalization machinery.
+USE_I18N = True
+USE_L10N = True
+
+MEDIA_ROOT = ''
+MEDIA_URL = ''
+
+# List of callables that know how to import templates from various sources.
+TEMPLATE_LOADERS = (
+ 'django.template.loaders.filesystem.Loader',
+ 'django.template.loaders.app_directories.Loader',
+)
+
+
+MIDDLEWARE_CLASSES = (
+ 'django.middleware.common.CommonMiddleware',
+ 'django.contrib.sessions.middleware.SessionMiddleware',
+ 'django.contrib.auth.middleware.AuthenticationMiddleware',
+ 'middleware.ForceLogout.ForceLogoutMiddleware',
+ 'django.middleware.csrf.CsrfViewMiddleware',
+ 'django.middleware.locale.LocaleMiddleware',
+ 'django.contrib.messages.middleware.MessageMiddleware',
+ 'django.contrib.flatpages.middleware.FlatpageFallbackMiddleware',
+ 'middleware.UserMessages.UserMessageMiddleware',
+)
+
+STATIC_URL = '/static/'
+STATIC_ROOT = os.path.join(BASE_DIR, 'static')
+
+STATICFILES_DIRS = (
+)
+
+STATICFILES_FINDERS = (
+ 'django.contrib.staticfiles.finders.FileSystemFinder',
+ 'django.contrib.staticfiles.finders.AppDirectoriesFinder',
+)
+
+ROOT_URLCONF = 'ganetimgr.urls'
+
+TEMPLATE_DIRS = (
+ os.path.join(BASE_DIR, 'templates'),
+)
+
+INSTALLED_APPS = (
+ 'django.contrib.auth',
+ 'django.contrib.contenttypes',
+ 'django.contrib.sessions',
+ 'django.contrib.sites',
+ 'django.contrib.flatpages',
+ 'django.contrib.messages',
+ 'django.contrib.admin',
+ 'django.contrib.staticfiles',
+ 'registration',
+ 'django_markdown',
+ 'accounts',
+ 'south',
+ 'ganeti',
+ 'apply',
+ 'notifications',
+ 'stats',
+ 'auditlog',
+# 'oauth2_provider',
+# 'corsheaders',
+)
+
+# Caching is a vital part of ganetimgr.
+# If you deploy more than one ganetimgr instances on the same server,
+# and want to use Redis for both, make sure you select a different db for each instance
+# Warning!!! Redis db should ALWAYS be an integer, denoting db index.
+# If memcache is your preferred cache, then select:
+#CACHE_BACKEND="redis_cache.cache://127.0.0.1:6379?timeout=1500"
+#CACHES = {
+# 'default': {
+# 'BACKEND': 'django.core.cache.backends.dummy.DummyCache',
+# }
+ # 'default': {
+ # 'BACKEND': 'django.core.cache.backends.memcached.MemcachedCache',
+ # 'LOCATION': '127.0.0.1:11211',
+ # 'TIMEOUT': 1,
+ # }
+#}
+
+LOGIN_URL = '/user/login'
+LOGIN_REDIRECT_URL = '/'
+
+TEMPLATE_CONTEXT_PROCESSORS = (
+ "django.contrib.auth.context_processors.auth",
+ "django.core.context_processors.debug",
+ "django.core.context_processors.i18n",
+ "django.core.context_processors.media",
+ "context.pending_notifications.notify",
+ "context.session_remaining.seconds",
+ "context.global_vars.settings_vars",
+ "django.core.context_processors.request",
+ "django.contrib.messages.context_processors.messages"
+)
+
+EMAIL_HOST = "127.0.0.1"
+EMAIL_PORT = 25
+USE_X_FORWARDED_HOST = True
+
+# Auth stuff
+# If you plan to deploy LDAP modify according to your needs
+AUTHENTICATION_BACKENDS = (
+ #'django_auth_ldap.backend.LDAPBackend',
+ 'django.contrib.auth.backends.ModelBackend',
+)
+
+#import ldap
+#from django_auth_ldap.config import LDAPSearch
+
+#AUTH_LDAP_BIND_DN = ""
+#AUTH_LDAP_BIND_PASSWORD = ""
+#AUTH_LDAP_SERVER_URI = "ldap://ldap.example.com"
+#AUTH_LDAP_START_TLS = True
+#AUTH_LDAP_USER_SEARCH = LDAPSearch("ou=People,dc=dept,dc=example,dc=com",
+# ldap.SCOPE_SUBTREE, "(uid=%(user)s)")
+#AUTH_LDAP_USER_ATTR_MAP = {
+# "first_name": "givenName",
+# "last_name": "sn",
+# "email": "mail"
+# }
+
+ACCOUNT_ACTIVATION_DAYS = 10
+
+AUTH_PROFILE_MODULE = 'accounts.UserProfile'
+
+SESSION_EXPIRE_AT_BROWSER_CLOSE = True
+#SESSION_ENGINE = "django.contrib.sessions.backends.cache"
+SESSION_COOKIE_AGE = 10800
+
+IDLE_ACCOUNT_NOTIFICATION_DAYS = '180'
+
+# Number of days that hash verification is active
+INSTANCE_ACTION_ACTIVE_DAYS = 7
+
+# This works for our GRNET NOC Jira installation. Default is False
+HELPDESK_INTEGRATION_JAVASCRIPT_URL = ""
+HELPDESK_INTEGRATION_JAVASCRIPT_PARAMS = {
+ 'customfield_11551': 'tier-1'
+}
+
+COLLECTD_URL = "http://stats.example.com"
+# Graphs nodata image
+NODATA_IMAGE = 'static/nodata.gif'
+
+SERVER_MONITORING_URL = 'https://monitoring.example.com'
+
+import _version
+SW_VERSION = _version.VERSION
+
+NODATA_IMAGE = 'static/nodata.gif'
+
+
+WHITELIST_IP_MAX_SUBNET_V4 = 26
+WHITELIST_IP_MAX_SUBNET_V6 = 64
+
+# RSS Feed for the login page
+FEED_URL = ""
+
+# Choose whether to support websockets console or not.
+WEBSOCK_VNC_ENABLED = True
+# 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 = "vnc.proxy.com:8888"
+NOVNC_USE_TLS = True
+
+BRANDING = {
+ "SERVICE_PROVIDED_BY": {
+ "NAME": "EXAMPLE",
+ "URL": "//example.dot.com",
+ "SOCIAL_NETWORKS": [
+ {
+ "URL": "https://facebook.com/",
+ "FONT_AWESOME_NAME": "fa-facebook",
+ "FONT_COLOR": "#3b5998"
+ },
+ {
+ "URL": "https://twitter.com/",
+ "FONT_AWESOME_NAME": "fa-twitter",
+ "FONT_COLOR": "#00acee"
+ }
+ ]
+ },
+ "VIDEO": "", # iframe url
+ "LOGO": "/static/ganetimgr/img/logo.png",
+ "FAVICON": "/static/ganetimgr/img/favicon.ico",
+ "MOTTO": "virtual private servers",
+ "FOOTER_ICONS_IFRAME": False,
+ # show the administrative contact
+ # option when creating a new vm
+ "SHOW_ADMINISTRATIVE_FORM": True,
+ "SHOW_ORGANIZATION_FORM": True,
+ "TITLE": "GanetiMGR",
+}
+
+# Set the email subject prefix:
+EMAIL_SUBJECT_PREFIX = "[GANETIMGR SERVICE] "
+SERVER_EMAIL = "no-reply@example.com"
+DEFAULT_FROM_EMAIL = "no-reply@example.com"
+
+# Flatpages manipulation. Show or hide flatpages links in page.
+FLATPAGES = {
+ "INFO": True,
+ "TOS": True,
+ "FAQ": True,
+}
+# Get a recaptcha key
+RECAPTCHA_PUBLIC_KEY = ''
+RECAPTCHA_PRIVATE_KEY = ''
+RECAPTCHA_USE_SSL = True
+
+MARKDOWN_EDITOR_SKIN = 'simple'
+
+
+#########################
+# #
+# Ganeti #
+# #
+#########################
+# Select your ganetimgr prefix. This is applied in the tags
+# of the instances. You could leave it as it is or set your own,
+# eg. GANETI_TAG_PREFIX = "vmservice"
+GANETI_TAG_PREFIX = "ganetimgr"
+RAPI_CONNECT_TIMEOUT = 8
+RAPI_RESPONSE_TIMEOUT = 15
+# List of operating system images you provide...
+OPERATING_SYSTEMS = {
+ "none": {
+ "description": "No operating system",
+ "provider": "noop",
+ "osparams": {},
+ "ssh_key_param": "",
+ },
+}
+
+
+# the urls of the available os images
+OPERATING_SYSTEMS_URLS = ['http://example.com/images']
+SNF_OPERATING_SYSTEMS_URLS = ['http://example.com/snf-images/']
+
+
+# the provider and ssh key param
+# We assume that they have the same configuration
+OPERATING_SYSTEMS_PROVIDER = 'image+default'
+OPERATING_SYSTEMS_SSH_KEY_PARAM = 'img_ssh_key_url'
+
+SNF_IMG_PROPERTIES = {
+ "SWAP": "2:512"
+}
+SNF_IMG_PASSWD = "example-passphrase"
+
+#########################
+# #
+# Auditlog #
+# #
+#########################
+
+# this option sets the amount of days old an audit entry has to be
+# in order to be shown in audit log page
+# '0' means show all entries
+
+AUDIT_ENTRIES_LAST_X_DAYS = 10
+
+
+# Instance specific django config.
+ADMINS = (
+ ('John Doe', 'john@example.com'),
+)
+MANAGERS = ADMINS
+
+#DATABASES = {
+# 'default': {
+# 'ENGINE': 'django.db.backends.', # 'postgresql_psycopg2', 'postgresql', 'mysql', 'sqlite3' or 'oracle'.
+# 'NAME': '', # Or path to database file if using sqlite3.
+# 'USER': '', # Not used with sqlite3.
+# 'PASSWORD': '', # Not used with sqlite3.
+# 'HOST': '', # Set to empty string for localhost. Not used with sqlite3.
+# 'PORT': '', # Set to empty string for default. Not used with sqlite3.
+# 'OPTIONS': {'init_command': 'SET storage_engine=MYISAM;'}
+# }
+#}
+
+# Make this unique, and don't share it with anybody.
+SECRET_KEY = '<CHANGE ME>'
+
+
+# OAUTH2
+if 'oauth2_provider' in INSTALLED_APPS and 'corsheaders' in INSTALLED_APPS:
+ OAUTH2_PROVIDER = {
+ 'ACCESS_TOKEN_EXPIRE_SECONDS': 60 * 60 * 24 * 7 * 10,
+ 'SCOPES': {
+ 'read': 'Read scope',
+ },
+ 'CLIENT_ID_GENERATOR_CLASS': 'oauth2_provider.generators.ClientIdGenerator',
+ }
+ CORS_ORIGIN_ALLOW_ALL = True
+ MIDDLEWARE_CLASSES += ('corsheaders.middleware.CorsMiddleware',)
+

Event Timeline