diff --git a/Dockerfile b/Dockerfile index 9f5960f..1ee0c3b 100644 --- a/Dockerfile +++ b/Dockerfile @@ -1,38 +1,38 @@ ####################################### #Dockerfile to build a ganetimgr image# # Uses Deban packages instead of pip # ####################################### # We use wheezy as a base (for now) FROM debian:wheezy MAINTAINER GRNET_NOC ENV GANETIMGR_UPSTREAM_URL https://github.com/grnet/ganetimgr.git # First layer - only system packages, nothing from the stack RUN apt-get update -q2 && DEBIAN_FRONTEND=noninteractive apt-get install --no-install-recommends -q2 git procps apt-utils # Django and rest of python dependencies for the project -RUN DEBIAN_FRONTEND=noninteractive apt-get install --no-install-recommends -q2 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 python-gevent +RUN DEBIAN_FRONTEND=noninteractive apt-get install --no-install-recommends -q2 python-django 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 python-gevent # Daemon dependencies RUN DEBIAN_FRONTEND=noninteractive apt-get install --no-install-recommends -q2 gunicorn beanstalkd nginx redis-server # Create a placeholder dir for the repo and switch context inside it ENV GANETIMGR_INSTALLDIR=/srv/ganetimgr RUN mkdir -p $GANETIMGR_INSTALLDIR WORKDIR $GANETIMGR_INSTALLDIR # Predifined Settings for use inside the container COPY settings.py $GANETIMGR_INSTALLDIR/ganetimgr/settings.py # Helper function to get the db connection info from envvars COPY dj_database_url.py $GANETIMGR_INSTALLDIR/ganetimgr/dj_database_url.py # Fixture to autoadd the cluster from the ganeti container (hardcoded for now) COPY cluster_insert.json $GANETIMGR_INSTALLDIR/cluster_insert.json COPY ganetimgr.nginx.conf /etc/nginx/nginx.conf # nginx run inside the container EXPOSE 80 COPY entrypoint.sh / # Set this as a CMD instead of ENTRYPOINT in order to be able to override it CMD ["/entrypoint.sh"] diff --git a/ganeti/entrypoint.sh b/ganeti/entrypoint.sh index 4d589ac..0314ba0 100755 --- a/ganeti/entrypoint.sh +++ b/ganeti/entrypoint.sh @@ -1,23 +1,36 @@ #!/bin/bash +# Create a dummy host entry for the cluster IP +# This will be used by the ganeti cluster once it's initialized +#TODO: find a non-racy way to add an IP echo "172.17.0.230 ganeti.example.com" >> /etc/hosts +# ganeti-instance-debootstrap patch to fix losetup usage for Jessie (deprecated switch) cd /usr/share/ganeti/os/debootstrap/ && patch < /gnt_deboo_losetup.patch > /dev/null +# Where ganeti will create instance disks (file template) mkdir /srv/ganeti && echo "/srv/ganeti" > /etc/ganeti/file-storage-paths +# bind on all ports so RAPi can be queried by outside sed -i "s/RAPI_ARGS=\"-b 127.0.0.1 --require-authentication\"/RAPI_ARGs=\"--require-authentication\"/" /etc/default/ganeti -#sed -i "s/WCONFD_ARGS=\"\"/WCONFD_ARGS=\"-f\"/" /etc/default/ganeti +# Create a rapi user +GANETI_USER=${GANETI_USER-ganeti} +GANETI_PASS=${GANETI_PASS-test} mkdir /var/lib/ganeti/rapi/ chown gnt-rapi:gnt-masterd /var/lib/ganeti/rapi/ -echo "ganeti test write" >> /var/lib/ganeti/rapi/users +echo "$GANETI_USER $GANETI_PASS write" >> /var/lib/ganeti/rapi/users +# Initialize a ganeti cluster with minimum configuration +#TODO: check if chroot works better for testing purposes /usr/sbin/gnt-cluster init --enabled-hypervisors=kvm --enabled-disk-templates=file --file-storage-dir=/srv/ganeti --master-netdev=eth0 --no-ssh-init --no-etc-hosts -H kvm:kernel_path='' ganeti.example.com +# Create a dummy bridge and register as a network on ganeti brctl addbr private_bridge gnt-network add --network=10.0.0.0/24 --gateway=10.0.0.1 private_bridge gnt-network connect --nic-parameters mode=bridged,link=private_bridge private_bridge +# Couldn't figure out a way to run ganeti on the foreground +# Run sshd instead, which is required for master -> node communincation mkdir /var/run/sshd /usr/sbin/sshd -D diff --git a/python-django-markdown_0.6.1-1_all.deb b/python-django-markdown_0.6.1-1_all.deb deleted file mode 100644 index 1ad0720..0000000 Binary files a/python-django-markdown_0.6.1-1_all.deb and /dev/null differ diff --git a/python-whitenoise_3.2.2-1_all.deb b/python-whitenoise_3.2.2-1_all.deb new file mode 100644 index 0000000..92f10fe Binary files /dev/null and b/python-whitenoise_3.2.2-1_all.deb differ diff --git a/settings.py b/settings.py index 084170d..8d45bef 100644 --- a/settings.py +++ b/settings.py @@ -1,308 +1,306 @@ -# -*- coding: utf-8 -*- vim:fileencoding=utf-8: - # shortcuts to create relative paths import os BASE_DIR = os.path.dirname(os.path.dirname(__file__)) PROJECT_DIR = os.path.join(BASE_DIR, 'ganetimgr') # helper function to get database connection from env.var import dj_database_url DATABASES= {} DATABASES['default'] = dj_database_url.config(default='sqlite:////%s' % os.path.join(BASE_DIR, 'db.sqlite3')) # DEBUG = os.environ.get('DJANGO_DEBUG', True) TIME_ZONE = os.environ.get('DJANGO_TIMEZONE','Europe/Athens') BEANSTALK_TUBE = os.environ.get('BEANSTALK_TUBE', None) ALLOWED_HOSTS=["*"] TEMPLATE_DEBUG = DEBUG SITE_ID = 1 ADMINS = ( ('John Doe', 'john@example.com'),) MANAGERS = ADMINS SECRET_KEY = '' # Locale settings # We provide English and Greek translations _ = lambda s: s #LANGUAGE_CODE = 'en-us' LANGUAGES = ( # ('el', u'Ελληνικά'), ('en', _('English')), ) 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', 'accounts', 'south', 'ganeti', 'apply', 'notifications', 'stats', 'auditlog', ) # 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": "", }, "debootstrap+default": { "description": "Debootstrap", "provider": "debootstrap+default", "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