Commit 7cb6bce6 by Őry Máté

Merge branch 'master' into releases

parents e84c01cf f5608fb2
......@@ -5,7 +5,7 @@ jsfiles += one/static/script/util.min.js
jsfiles += one/static/script/store.min.js
cssfiles += one/static/style/style.css
default: migrate generatestatic collectstatic mo setbranch restart
default: migrate generatestatic collectstatic mo restart
pulldef: pull default
pull:
......@@ -23,10 +23,6 @@ generatestatic: $(jsfiles) $(cssfiles)
collectstatic:
./manage.py collectstatic --noinput
setbranch:
sed -i cloud/local_settings.py -e '/RELEASE=/d' || true
echo "RELEASE='`git rev-parse --abbrev-ref HEAD`'" >>cloud/local_settings.py
mo:
for i in */locale/*/*/*.po; do echo -ne "$$i:\t"; msgfmt --statistics $$i;done
for i in */; do cd $$i; ls locale &>/dev/null && ../manage.py compilemessages || true; cd ..; done
......
from cloud.settings import DEBUG, STAT_DEBUG, RELEASE
from django.core.cache import cache
import subprocess
import json
import subprocess
from django.conf import settings
from django.core.cache import cache
def process_debug(req):
return {'DEBUG': DEBUG}
return {'DEBUG': settings.DEBUG}
def process_stat(req):
if STAT_DEBUG:
if settings.STAT_DEBUG:
stat = {
'CPU': {
'USED_CPU': 10,
......@@ -23,11 +24,11 @@ def process_stat(req):
else:
stat = cache.get('cloud_stat')
return {
'STAT_DEBUG': STAT_DEBUG,
'STAT_DEBUG': settings.STAT_DEBUG,
'cloud_stat': stat,
}
def process_release(req):
return {
'release': RELEASE,
'release': settings.RELEASE,
}
# Django settings for cloud project.
# coding=utf8
# Django base settings for cloud project.
import os
import subprocess
DEBUG = True
TEMPLATE_DEBUG = DEBUG
STAT_DEBUG = True
from django.core.exceptions import ImproperlyConfigured
def get_env_variable(var_name, default=None):
""" Get the environment variable or return exception/default """
try:
return os.environ[var_name]
except KeyError:
if default is None:
error_msg = "Set the %s environment variable" % var_name
raise ImproperlyConfigured(error_msg)
else:
return default
DEBUG = False
TEMPLATE_DEBUG = False
STAT_DEBUG = False
ADMINS = (
('IK', 'cloud@cloud.ik.bme.hu'),
......@@ -13,16 +30,12 @@ MANAGERS = ADMINS
DATABASES = {
'default': {
'ENGINE': 'django.db.backends.mysql', # Add 'postgresql_psycopg2',
# 'mysql', 'sqlite3' or 'oracle'.
'NAME': 'webadmin', # Or path to database file if
# using sqlite3.
'USER': 'webadmin', # Not used with sqlite3.
'PASSWORD': 'asjklddfjklqjf', # 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.
'ENGINE': 'django.db.backends.mysql',
'NAME': get_env_variable('DJANGO_DB_NAME', 'webadmin'),
'USER': get_env_variable('DJANGO_DB_USER', 'webadmin'),
'PASSWORD': get_env_variable('DJANGO_DB_PASSWORD'),
'HOST': get_env_variable('DJANGO_DB_HOST', ''),
'PORT': get_env_variable('DJANGO_DB_PORT', ''),
}
}
......@@ -82,17 +95,17 @@ STATICFILES_DIRS = (
STATICFILES_FINDERS = (
'django.contrib.staticfiles.finders.FileSystemFinder',
'django.contrib.staticfiles.finders.AppDirectoriesFinder',
# 'django.contrib.staticfiles.finders.DefaultStorageFinder',
# 'django.contrib.staticfiles.finders.DefaultStorageFinder',
)
# Make this unique, and don't share it with anybody.
SECRET_KEY = 'sx%4b1oa2)mn%##6+e1+25g@r8ht(cqk(nko^fr66w&26f22ba'
SECRET_KEY = get_env_variable('DJANGO_SECRET_KEY')
# 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',
# 'django.template.loaders.eggs.Loader',
# 'django.template.loaders.eggs.Loader',
)
MIDDLEWARE_CLASSES = (
......@@ -125,8 +138,8 @@ TEMPLATE_CONTEXT_PROCESSORS = (
)
TEMPLATE_DIRS = (
# Put strings here, like "/home/html/django_templates" or "C:/www/django/templates".
# Always use forward slashes, even on Windows.
# Put strings here, like "/home/html/django_templates" or
# "C:/www/django/templates". Always use forward slashes, even on Windows.
# Don't forget to use absolute paths, not relative paths.
)
......@@ -154,7 +167,7 @@ INSTALLED_APPS = (
# the site admins on every HTTP 500 error when DEBUG=False.
# See http://docs.djangoproject.com/en/dev/topics/logging for
# more details on how to customize your logging configuration.
from logging.handlers import SysLogHandler
# from logging.handlers import SysLogHandler
LOGGING = {
'version': 1,
......@@ -170,8 +183,8 @@ LOGGING = {
'filters': ['require_debug_false'],
'class': 'django.utils.log.AdminEmailHandler'
},
'syslog':{
'level':'WARNING',
'syslog': {
'level': 'WARNING',
'class': 'logging.handlers.SysLogHandler',
'address': '/dev/log',
},
......@@ -189,12 +202,18 @@ LOGGING = {
},
}
}
LOGIN_URL="/login"
LOGIN_URL = "/login"
AUTH_PROFILE_MODULE = 'school.Person'
import djcelery
djcelery.setup_loader()
BROKER_URL = 'amqp://nyuszi:teszt@localhost:5672/django'
CELERY_CACHE_BACKEND = "default"
CELERY_RESULT_BACKEND = "amqp"
CELERY_TASK_RESULT_EXPIRES = 3600
BROKER_URL = get_env_variable(
'DJANGO_BROKER_URL', 'amqp://nyuszi:teszt@localhost:5672/django')
CELERY_ROUTES = {
'firewall.tasks.ReloadTask': {'queue': 'local'},
'firewall.tasks.reload_dns_task': {'queue': 'dns'},
......@@ -203,7 +222,14 @@ CELERY_ROUTES = {
'firewall.tasks.reload_blacklist_task': {'queue': 'firewall'},
'firewall.tasks.Periodic': {'queue': 'local'},
'one.tasks.SendMailTask': {'queue': 'local'},
'one.tasks.UpdateInstanceStateTask': {'queue': 'local'}
'one.tasks.UpdateInstanceStateTask': {'queue': 'local'},
'one.tasks.UpdateDiskTask': {'queue': 'opennebula'},
'one.tasks.UpdateNetworkTask': {'queue': 'opennebula'},
'one.tasks.ChangeInstanceStateTask': {'queue': 'opennebula'},
'one.tasks.SaveAsTask': {'queue': 'opennebula'},
'one.tasks.CreateInstanceTask': {'queue': 'opennebula'},
'one.tasks.DeleteInstanceTask': {'queue': 'opennebula'},
}
CACHES = {
......@@ -214,7 +240,7 @@ CACHES = {
}
store_settings = {
STORE_SETTINGS = {
"basic_auth": "True",
"verify_ssl": "False",
"ssl_auth": "False",
......@@ -226,7 +252,7 @@ store_settings = {
"store_public": "store.ik.bme.hu",
}
firewall_settings = {
FIREWALL_SETTINGS = {
"default_vlangroup": "publikus",
"reload_sleep": "10",
"dns_hostname": "dns1.ik.bme.hu",
......@@ -234,14 +260,12 @@ firewall_settings = {
"dns_ip": "152.66.243.60",
"dns_ttl": "300",
}
EMAIL_HOST='152.66.243.92' # giccero ipv4
CLOUD_URL='https://cloud.ik.bme.hu/'
RELEASE='master'
try:
from cloud.local_settings import *
except:
pass
SITE_NAME = "IK Cloud"
DEFAULT_FROM_EMAIL = "noreply@cloud.ik.bme.hu"
DELETE_VM = False
EMAIL_HOST = '152.66.243.92' # giccero ipv4
CLOUD_URL = 'https://cloud.ik.bme.hu/'
RELEASE = subprocess.check_output(
['git', 'rev-parse', '--symbolic-full-name', '--abbrev-ref', 'HEAD'])
# vim: et sw=4 ai fenc=utf8 smarttab :
# coding=utf8
# Django development settings for cloud project.
from .base import *
DEBUG = True
TEMPLATE_DEBUG = DEBUG
EMAIL_HOST = "localhost"
EMAIL_PORT = 1025
ADMINS = (
('Ory, Mate', 'orymate@localhost'),
)
MANAGERS = (
('Ory Mate', 'maat@localhost'),
)
INSTALLED_APPS += ("debug_toolbar", )
MIDDLEWARE_CLASSES += ("debug_toolbar.middleware.DebugToolbarMiddleware", )
# coding=utf8
# Django production settings for cloud project.
from .base import *
DEBUG = False
TEMPLATE_DEBUG = DEBUG
from django.contrib import auth
from firewall import models
import os
from cloud.settings import firewall_settings as settings
import django.conf
import subprocess
import re
......@@ -10,6 +11,7 @@ from datetime import datetime, timedelta
from django.db.models import Q
settings = django.conf.settings.FIREWALL_SETTINGS
class Firewall:
IPV6=False
RULES = None
......
......@@ -7,11 +7,12 @@ from django.utils.translation import ugettext_lazy as _
from firewall.fields import *
from south.modelsinspector import add_introspection_rules
from django.core.validators import MinValueValidator, MaxValueValidator
from cloud.settings import firewall_settings as settings
import django.conf
from django.db.models.signals import post_save
import re
import random
settings = django.conf.settings.FIREWALL_SETTINGS
class Rule(models.Model):
CHOICES_type = (('host', 'host'), ('firewall', 'firewall'),
('vlan', 'vlan'))
......
......@@ -4,7 +4,9 @@ from django.core.cache import cache
import os
import time
from firewall.fw import *
from cloud.settings import firewall_settings as settings
import django.conf
settings = django.conf.settings.FIREWALL_SETTINGS
@celery.task
def reload_dns_task(data):
......
from django.shortcuts import render_to_response
from django.http import HttpResponse
from firewall.models import *
from firewall.fw import *
from django.views.decorators.csrf import csrf_exempt
from django.views.decorators.http import require_POST
from django.db import IntegrityError
from tasks import *
from celery.task.control import inspect
from django.utils.translation import ugettext_lazy as _
from django.template.loader import render_to_string
from cloud.settings import CLOUD_URL as url
from django.utils import translation
import re
import base64
import datetime
import json
import re
import sys
import datetime
from django.conf import settings
from django.db import IntegrityError
from django.http import HttpResponse
from django.shortcuts import render_to_response
from django.template.loader import render_to_string
from django.utils import translation
from django.utils.timezone import utc
from django.utils.translation import ugettext_lazy as _
from django.views.decorators.csrf import csrf_exempt
from django.views.decorators.http import require_POST
from celery.task.control import inspect
from tasks import *
from firewall.fw import *
from firewall.models import *
from one.tasks import SendMailTask
def reload_firewall(request):
......@@ -52,7 +53,11 @@ def firewall_api(request):
user = obj.host.owner
lang = user.person_set.all()[0].language
translation.activate(lang)
msg = render_to_string('mails/notification-ban-now.txt', { 'user': user, 'bl': obj, 'instance:': obj.host.instance_set.get(), 'url': url} )
msg = render_to_string('mails/notification-ban-now.txt',
{ 'user': user,
'bl': obj,
'instance:': obj.host.instance_set.get(),
'url': settings.CLOUD_URL} )
SendMailTask.delay(to=obj.host.owner.email, subject='[IK Cloud] %s' % obj.host.instance_set.get().name, msg=msg, sender=u'cloud@ik.bme.hu')
except (Host.DoesNotExist, ValidationError, IntegrityError, AttributeError):
pass
......
#!/usr/bin/env python
import subprocess
from celery import Celery, task
import time, re
import socket
import sys
import tempfile, os, stat, re, base64, struct, logging
from celery.contrib import rdb
BROKER_URL = 'amqp://nyuszi:teszt@localhost:5672/django'
try:
from local_settings import *
except:
pass
celery = Celery('tasks', broker=BROKER_URL, backend=BROKER_URL)
celery.conf.update(
CELERY_TASK_RESULT_EXPIRES=3600,
)
def update_vm(one_id, template):
out = ""
with tempfile.NamedTemporaryFile(delete=False) as f:
os.chmod(f.name, stat.S_IRUSR|stat.S_IWUSR|stat.S_IRGRP|stat.S_IROTH)
tpl = u'''
<COMPUTE>
<ID>%(id)d</ID>
%(template)s
</COMPUTE>''' % {
"id": one_id,
"template": template
}
f.write(tpl)
f.close()
proc = subprocess.Popen(["/opt/occi.sh", "compute", "update",
f.name], stdout=subprocess.PIPE)
try:
(out, err) = proc.communicate()
except:
pass
os.unlink(f.name)
@task(name="one.tasks.CreateInstanceTask")
def t(name, instance_type, disk_id, network_id, ctx):
out = ''
f2 = tempfile.NamedTemporaryFile(delete=False)
f2.close()
with tempfile.NamedTemporaryFile(delete=False) as f:
os.chmod(f.name, stat.S_IRUSR|stat.S_IWUSR|stat.S_IRGRP|stat.S_IROTH)
tpl = u"""
<COMPUTE>
<NAME>%(name)s</NAME>
<INSTANCE_TYPE href="http://www.opennebula.org/instance_type/%(instance)s"/>
<DISK>
<STORAGE href="http://www.opennebula.org/storage/%(disk)d"/>
</DISK>
<NIC>
<NETWORK href="http://www.opennebula.org/network/%(net)d"/>
</NIC>
<CONTEXT>
%(context)s
</CONTEXT>
</COMPUTE>""" % {
"name": name,
"instance": instance_type,
"disk": disk_id,
"net": network_id,
"context": ctx,
}
f.write(tpl)
f.close()
proc = subprocess.Popen(["/opt/occi.sh compute creatE %s > %s" %
( f.name, f2.name )], shell=True)
try:
proc.communicate()
except:
pass
with open(f2.name, 'r') as f3:
out = f3.read()
os.unlink(f.name)
os.unlink(f2.name)
from xml.dom.minidom import parse, parseString
try:
x = parseString(out)
return {
'one_id': int(x.getElementsByTagName("ID")[0].childNodes[0].nodeValue),
'interfaces': [
{
'ip': x.getElementsByTagName("IP")[0].childNodes[0].nodeValue,
'mac': x.getElementsByTagName("MAC")[0].childNodes[0].nodeValue,
},
],
}
except:
pass
@task(name="one.tasks.ChangeInstanceStateTask")
def t(one_id, new_state):
update_vm(one_id, '<STATE>%s</STATE>' % (new_state, ))
@task(name="one.tasks.SaveAsTask")
def t(one_id, new_img):
update_vm(one_id, '<DISK id="0"><SAVE_AS name="%s"/></DISK>' % new_img)
@task(name="one.tasks.UpdateDiskTask")
def t():
f = tempfile.NamedTemporaryFile(delete=False)
f.close()
out=''
proc = subprocess.Popen(["/opt/occi.sh storage list > %s" % f.name],
shell=True)
try:
(out, err) = proc.communicate()
except:
pass
from xml.dom.minidom import parse, parseString
try:
with open(f.name, 'r') as f2:
out = f2.read()
x = parseString(out)
return [ {
'id': int(d.getAttributeNode('href').nodeValue.split('/')[-1]),
'name': d.getAttributeNode('name').nodeValue,
} for d in x.getElementsByTagName("STORAGE")
]
except:
pass
os.unlink(f)
@task(name="one.tasks.UpdateNetworkTask")
def t():
f = tempfile.NamedTemporaryFile(delete=False)
f.close()
out=''
proc = subprocess.Popen(["/opt/occi.sh network list > %s" % f.name],
shell=True)
try:
(out, err) = proc.communicate()
except:
pass
from xml.dom.minidom import parse, parseString
try:
with open(f.name, 'r') as f2:
out = f2.read()
x = parseString(out)
return [ {
'id': int(d.getAttributeNode('href').nodeValue.split('/')[-1]),
'name': d.getAttributeNode('name').nodeValue,
} for d in x.getElementsByTagName("NETWORK")
]
except:
pass
os.unlink(f)
@task(name="one.tasks.DeleteInstanceTask")
def t(one_id):
proc = subprocess.Popen(["/opt/occi.sh", "compute", "delete",
"%d" % one_id], stdout=subprocess.PIPE)
try:
(out, err) = proc.communicate()
except:
pass
def update_state(one_id):
"""Get and update VM state from OpenNebula."""
proc = subprocess.Popen(["/opt/occi.sh", "compute", "show",
"%d" % one_id], stdout=subprocess.PIPE)
(out, err) = proc.communicate()
state = 'UNKNOWN'
try:
if(len(sys.argv) == 3 and sys.argv[2] == 'UNKNOWN'):
raise Exception(':(')
from xml.dom.minidom import parse, parseString
x = parseString(out)
state = x.getElementsByTagName("STATE")[0].childNodes[0].nodeValue
except:
state = 'UNKNOWN'
print state
celery.send_task('one.tasks.UpdateInstanceStateTask', [one_id, state],
queue='local')
if __name__ == "__main__":
update_state(int(sys.argv[1]))
#!/usr/bin/env python
from celery import Celery, task
import subprocess
import time, re
import socket
import sys
BROKER_URL = 'amqp://nyuszi:teszt@localhost:5672/django'
try:
from local_settings import *
except:
pass
CELERY_CREATE_MISSING_QUEUES=True
celery = Celery('tasks', broker=BROKER_URL)
def main(argv):
celery.send_task('one.tasks.UpdateInstanceStateTask', [ int(sys.argv[1]),
], queue='local')
if __name__ == "__main__":
main(sys.argv)
......@@ -5,5 +5,8 @@ stop on runlevel [!2345]
respawn
respawn limit 30 30
env DJANGO_SETTINGS_MODULE=cloud.settings.dev
env DJANGO_DB_PASSWORD=asjklddfjklqjf
env DJANGO_SECRET_KEY=asjklddfjklqjfasjklddfjklqjfasjklddfjklqjf
exec sudo -u cloud /opt/webadmin/cloud/manage.py runserver 0.0.0.0:8080
......@@ -43,7 +43,7 @@ cd /opt/webadmin/
mv cloud cloud.$(date +%s) || true
git clone 'ssh://git@giccero.cloud.ik.bme.hu/cloud'
git clone 'git@git.cloud.ik.bme.hu:circle/cloud.git'
cd cloud
source miscellaneous/devenv/nextinit.sh
......
#!/bin/bash
sudo pip install django_extensions
sudo pip install django-debug-toolbar
for i in cloudstore toplist django
do
sudo stop $i || true
done
sudo apt-get install rabbitmq-server gettext memcached
sudo tee /etc/sudoers.d/djangokeep <<A
Defaults env_keep += DJANGO_DB_PASSWORD
Defaults env_keep += DJANGO_SECRET_KEY
Defaults env_keep += DJANGO_SETTINGS_MODULE
A
sudo chmod 0440 /etc/sudoers.d/djangokeep
sudo apt-get install rabbitmq-server gettext memcached nodejs
sudo rabbitmqctl delete_user guest || true
sudo rabbitmqctl add_user nyuszi teszt || true
sudo rabbitmqctl add_vhost django || true
......@@ -14,6 +22,9 @@ sudo rabbitmqctl set_permissions -p django nyuszi '.*' '.*' '.*' || true
sudo pip install python-memcached
sudo npm install -g less
sudo npm install -g uglify-js@1
sudo cp /opt/webadmin/cloud/miscellaneous/devenv/boot_url.py /opt/
#Set up store server
......
\documentclass[12pt,a4paper]{article}
\title{Harnessing Wasted Computing Power for Scientific Computing}
\author{S\'andor Guba, M\'at\'e \H{O}ry and Imre Szeber\'enyi\\
Budapest University of Technology and Economics, %\\
%Magyar Tud\'osok k\"or\'utja 2, H-1117 Budapest,
Hungary}
\date{\empty}
\begin{document}
\maketitle
Nowadays more and more general purpose workstations installed in a student
laboratory have built in multi-core CPU and graphics card providing significant
computing power. In most cases the utilization of these resources is low, and
limited to lecture hours. The concept of utility computing plays an important
role in nowadays technological development. As part of utility computing, cloud
computing offers greater flexibility and responsiveness to ICT users at lower
cost.
In  this paper, we introduce a cloud management system which enables the
simultaneous use of both dedicated resources and opportunistic environment. All
the free workstations (powered or not) are automatically added to a resource
pool, and can be used like ordinary cloud resources. Researchers can launch
various virtualized software appliances. Our solution leverages the advantages
of HTCondor and OpenNebula systems.
Modern graphics processing units (GPUs) with many-core architectures have
emerged as general-purpose parallel computing platforms that can dramatically
accelerate  scientific applications used for various simulations. Our business
model harnesses computing power of GPUs as well, using the needed amount of
unused machines. This makes the infrastructure flexible and power efficient.
Our pilot infrastructure consist of a high performance cluster and 28
workstations with dual-core CPUs and dedicated graphics cards. Altogether we
can use 10,752 CUDA cores through the network.
\end{document}
@inproceedings{younge2011analysis,
title={Analysis of virtualization technologies for high performance computing environments},
author={Younge, Andrew J and Henschel, Robert and Brown, James T and von Laszewski, Gregor and Qiu, Judy and Fox, Geoffrey C},
booktitle={Cloud Computing (CLOUD), 2011 IEEE International Conference on},
pages={9--16},
year={2011},
organization={IEEE}
}
@article{creasy1981origin,
title={The origin of the VM/370 time-sharing system},
author={Creasy, Robert J.},
journal={IBM Journal of Research and Development},
volume={25},
number={5},
pages={483--490},
year={1981},
publisher={IBM}
}
@article{duatonew,
title={A New Approach to rCUDA},
author={Duato, Jos{\'e} and Pena, Antonio J and Silla, Federico and Fern{\'a}ndez, Juan C and Mayo, Rafael and Quintana-Ort{\i}, Enrique S}
}
@book{holovaty2009definitive,
title={The Definitive Guide to Django: Web Development Done Right},
author={Holovaty, Adrian and Kaplan-Moss, Jacob},
year={2009},
publisher={Apress}
}
@techreport{pinzari2003introduction,
title={Introduction to NX technology},
author={Pinzari, Gian Filippo},
year={2003},
institution={NoMachine Technical Report 309}
}
@article{victoria2009creating,
title={Creating and Controlling KVM Guests using libvirt},
author={Victoria, B},
journal={University of Victoria},
year={2009}
}
@inproceedings{bolte2010non,
title={Non-intrusive virtualization management using libvirt},
author={Bolte, Matthias and Sievers, Michael and Birkenheuer, Georg and Nieh{\"o}rster, Oliver and Brinkmann, Andr{\'e}},
booktitle={Proceedings of the Conference on Design, Automation and Test in Europe},
pages={574--579},
year={2010},
organization={European Design and Automation Association}
}
@article{pfaff2009extending,
title={Extending networking into the virtualization layer},
author={Pfaff, Ben and Pettit, Justin and Koponen, Teemu and Amidon, Keith and Casado, Martin and Shenker, Scott},
journal={Proc. HotNets (October 2009)},
year={2009}
}
@article{hoskins2006sshfs,
title={Sshfs: super easy file access over ssh},
author={Hoskins, Matthew E},
journal={Linux Journal},
volume={2006},
number={146},
pages={4},
year={2006},
publisher={Belltown Media}
}
@article{szeredi2010fuse,
title={FUSE: Filesystem in userspace},
author={M. Szeredi},
journal={Accessed on},
year={2010}
}
@inproceedings{yang2012implementation,
title={On implementation of GPU virtualization using PCI pass-through},
author={Yang, Chao-Tung and Wang, Hsien-Yi and Ou, Wei-Shen and Liu, Yu-Tso and Hsu, Ching-Hsien},
booktitle={Cloud Computing Technology and Science (CloudCom), 2012 IEEE 4th International Conference on},
pages={711--716},
year={2012},
organization={IEEE}
}
@inproceedings{duato2011enabling,
title={Enabling CUDA acceleration within virtual machines using rCUDA},
author={Duato, Jos{\'e} and Pena, Antonio J and Silla, Federico and Fern{\'a}ndez, Juan C and Mayo, Rafael and Quintana-Orti, ES},
booktitle={High Performance Computing (HiPC), 2011 18th International Conference on},
pages={1--10},
year={2011},
organization={IEEE}
}
@inproceedings{callaghan2002nfs,
title={Nfs over rdma},
author={Callaghan, Brent and Lingutla-Raj, Theresa and Chiu, Alex and Staubach, Peter and Asad, Omer},
booktitle={Proceedings of ACM SIGCOMM Summer 2003 NICELI Workshop},
year={2002}
}
@article{vinoski2006advanced,
title={Advanced message queuing protocol},
author={Vinoski, Steve},
journal={Internet Computing, IEEE},
volume={10},
number={6},
pages={87--89},
year={2006},
publisher={IEEE}
}
% clmomu01.ind
%-----------------------------------------------------------------------
% CLMoMu01 1.0: LaTeX style files for books
% Sample index file for User's guide
% (c) Springer-Verlag HD
%-----------------------------------------------------------------------
\begin{theindex}
\item Absorption\idxquad 327
\item Absorption of radiation \idxquad 289--292,\, 299,\,300
\item Actinides \idxquad 244
\item Aharonov-Bohm effect\idxquad 142--146
\item Angular momentum\idxquad 101--112
\subitem algebraic treatment\idxquad 391--396
\item Angular momentum addition\idxquad 185--193
\item Angular momentum commutation relations\idxquad 101
\item Angular momentum quantization\idxquad 9--10,\,104--106
\item Angular momentum states\idxquad 107,\,321,\,391--396
\item Antiquark\idxquad 83
\item $\alpha$-rays\idxquad 101--103
\item Atomic theory\idxquad 8--10,\,219--249,\,327
\item Average value\newline ({\it see also\/} Expectation value)
15--16,\,25,\,34,\,37,\,357
\indexspace
\item Baker-Hausdorff formula\idxquad 23
\item Balmer formula\idxquad 8
\item Balmer series\idxquad 125
\item Baryon\idxquad 220,\,224
\item Basis\idxquad 98
\item Basis system\idxquad 164,\,376
\item Bell inequality\idxquad 379--381,\,382
\item Bessel functions\idxquad 201,\,313,\,337
\subitem spherical\idxquad 304--306,\, 309,\, 313--314,\,322
\item Bound state\idxquad 73--74,\,78--79,\,116--118,\,202,\, 267,\,
273,\,306,\,348,\,351
\item Boundary conditions\idxquad 59,\, 70
\item Bra\idxquad 159
\item Breit-Wigner formula\idxquad 80,\,84,\,332
\item Brillouin-Wigner perturbation theory\idxquad 203
\indexspace
\item Cathode rays\idxquad 8
\item Causality\idxquad 357--359
\item Center-of-mass frame\idxquad 232,\,274,\,338
\item Central potential\idxquad 113--135,\,303--314
\item Centrifugal potential\idxquad 115--116,\,323
\item Characteristic function\idxquad 33
\item Clebsch-Gordan coefficients\idxquad 191--193
\item Cold emission\idxquad 88
\item Combination principle, Ritz's\idxquad 124
\item Commutation relations\idxquad 27,\,44,\,353,\,391
\item Commutator\idxquad 21--22,\,27,\,44,\,344
\item Compatibility of measurements\idxquad 99
\item Complete orthonormal set\idxquad 31,\,40,\,160,\,360
\item Complete orthonormal system, {\it see}\newline
Complete orthonormal set
\item Complete set of observables, {\it see\/} Complete
set of operators
\indexspace
\item Eigenfunction\idxquad 34,\,46,\,344--346
\subitem radial\idxquad 321
\subsubitem calculation\idxquad 322--324
\item EPR argument\idxquad 377--378
\item Exchange term\idxquad 228,\,231,\,237,\,241,\,268,\,272
\indexspace
\item $f$-sum rule\idxquad 302
\item Fermi energy\idxquad 223
\indexspace
\item H$^+_2$ molecule\idxquad 26
\item Half-life\idxquad 65
\item Holzwarth energies\idxquad 68
\end{theindex}
This source diff could not be displayed because it is too large. You can view the blob instead.
<!doctype html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Better animations</title>
<style>
.container {
width: 400px;
-webkit-transition: height 700ms;
height: 0px;
overflow: hidden;
background-color: red;
}
.container.opened {
}
</style>
<script type="text/javascript" src="http://code.jquery.com/jquery-1.9.1.min.js"></script>
<script type="text/javascript">
window.onload=function(){
document.getElementById('toggle-css-btn').onclick=function(){
var el=$('#toggle-css');
if(!el.hasClass('opened')) {
el.css('height', el.find('.details')[0].offsetHeight||'1000px');
} else {
el.css('height', '0px');
}
$('#toggle-css').toggleClass('opened');
}
}
</script>
</head>
<body>
<div class="container" id="toggle-css">
<div class="details">Lorem ipsum dolor sit amet, consectetur adipiscing elit. Donec et consectetur augue. Nulla eu egestas massa. Sed convallis odio justo, ac vehicula sem. Nunc diam leo, consequat nec vulputate volutpat, vulputate quis enim. Praesent mattis egestas neque, at aliquam neque scelerisque non. Ut convallis ligula quis mi tincidunt id accumsan turpis tincidunt. Praesent quis lacus dolor, a varius magna. Aliquam tellus enim, convallis at varius a, pharetra eget dolor.
Aliquam sed leo quis ante fermentum viverra non at ante. Aliquam ante ligula, posuere in dictum egestas, commodo vel mi. Praesent dui nulla, accumsan euismod eleifend non, suscipit dapibus erat. Aliquam consequat felis ut sapien sodales ultricies non nec tellus. In ac odio ante. Nunc lectus urna, bibendum vitae sodales vel, volutpat id libero. Phasellus id turpis ligula, et tincidunt ante.
</div>
</div>
<button id="toggle-css-btn">Toggle, CSS3</button>
</body>
</html>
<!doctype html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Ellipsis test</title>
</head>
<body>
<div style="width: 40%; background-color: cyan;">
<div style="float: left; background-color: yellow; width: calc(100%-60px);">
<div style="background: red; float: left; text-overflow: ellipsis; width: 70%; min-width: 50px; overflow: hidden; white-space: nowrap;">Hosszú név, Hosszú név, Hosszú név, Hosszú név</div>
<div style="float: left; background-color: blue;">Részletek</div>
</div>
<div style="float: right; background-color: green;">jobb szél</div>
<div style="clear: both;"></div>
</div>
</body>
</html>
......@@ -6,7 +6,7 @@ from one.models import Instance
from django.template.loader import render_to_string
from one.tasks import SendMailTask
from django.utils.translation import ugettext_lazy as _
from cloud.settings import CLOUD_URL as url
from django.conf import settings
from django.utils import translation
class Job(HourlyJob):
......@@ -16,6 +16,8 @@ class Job(HourlyJob):
return (orig + datetime.timedelta(days=days, hours=hours)).replace(minute=0, second=0, microsecond=0)
def execute(self):
url = settings.CLOUD_URL
site = settings.SITE_NAME
now = datetime.datetime.utcnow().replace(tzinfo=utc)
d = {
'1m': self.calc(orig=now, days=30),
......@@ -28,26 +30,33 @@ class Job(HourlyJob):
# print i+':'+unicode(d[i])
# delete
for i in Instance.objects.filter(state__in=['ACTIVE', 'STOPPED'], time_of_delete__isnull=False):
for i in Instance.objects.filter(state__in=['ACTIVE', 'STOPPED'],
time_of_delete__isnull=False, waiting=False):
try:
translation.activate(i.owner.person_set.get().language)
except:
pass
# print u'%s delete: %s' % (i.name, i.time_of_delete)
delete = i.time_of_delete.replace(minute=0, second=0, microsecond=0)
if not settings.DELETE_VM:
continue
if i.time_of_delete < now:
# msg = render_to_string('mails/notification-delete-now.txt', { 'user': i.owner, 'instance': i, 'url': url } )
# SendMailTask.delay(to=i.owner.email, subject='[IK Cloud] %s' % i.name, msg=msg)
pass
msg = render_to_string('mails/notification-delete-now.txt',
{ 'user': i.owner, 'instance': i, 'url': url, 'site': site } )
SendMailTask.delay(to=i.owner.email, subject='[%s] %s' %
(site, i.name), msg=msg)
i.one_delete()
else:
for t in d:
if delete == d[t]:
msg = render_to_string('mails/notification-delete.txt', { 'user': i.owner, 'instance': i, 'url': url } )
SendMailTask.delay(to=i.owner.email, subject='[IK Cloud] %s' % i.name, msg=msg)
msg = render_to_string('mails/notification-delete.txt',
{ 'user': i.owner, 'instance': i, 'url': url, 'site': site } )
SendMailTask.delay(to=i.owner.email, subject='[%s] %s' %
(site, i.name), msg=msg)
# suspend
for i in Instance.objects.filter(state='ACTIVE', time_of_suspend__isnull=False):
for i in Instance.objects.filter(state='ACTIVE',
time_of_suspend__isnull=False, waiting=False):
try:
translation.activate(i.owner.person_set.get().language)
except:
......@@ -56,11 +65,15 @@ class Job(HourlyJob):
suspend = i.time_of_suspend.replace(minute=0, second=0, microsecond=0)
if i.time_of_suspend < now:
msg = render_to_string('mails/notification-suspend-now.txt', { 'user': i.owner, 'instance': i, 'url': url } )
SendMailTask.delay(to=i.owner.email, subject='[IK Cloud] %s' % i.name, msg=msg)
msg = render_to_string('mails/notification-suspend-now.txt',
{ 'user': i.owner, 'instance': i, 'url': url, 'site': site } )
SendMailTask.delay(to=i.owner.email, subject='[%s] %s' %
(site, i.name), msg=msg)
i.stop()
else:
for t in d:
if suspend == d[t]:
msg = render_to_string('mails/notification-suspend.txt', { 'user': i.owner, 'instance': i, 'url': url } )
SendMailTask.delay(to=i.owner.email, subject='[IK Cloud] %s' % i.name, msg=msg)
msg = render_to_string('mails/notification-suspend.txt',
{ 'user': i.owner, 'instance': i, 'url': url, 'site': site } )
SendMailTask.delay(to=i.owner.email, subject='[%s] %s' %
(site, i.name), msg=msg)
var toggleDetails;
$(function() {
toggleDetails = cloud.throttle(function() {
toggleDetails = function() {
if ($(this).parent('.entry').hasClass('opened')) {
$(this).parent('.entry').removeClass('opened');
$(this).next('.details').slideUp(700);
$(this).next('.details').css('height', '0px');
} else {
$(this).parent('.entry').addClass('opened');
$(this).next('.details').slideDown(700);
$(this).next('.details').css('height',
$(this).next('.details').find('.details-container')[0].offsetHeight+15+'px');
}
}
})
$('a[href=#]').click(function(e) {
e.preventDefault();
});
......
......@@ -273,13 +273,17 @@
z-index: 2;
position: relative;
}
.details {
height: auto;
}
}
&.opened #new-folder-form {
display: block;
}
.details {
border-top: 1px solid #888;
display: none;
height: 0px;
.vendor(transition, height 700ms);
overflow: hidden;
.container {
padding: 5px 5px;
.upload-zone {
......@@ -314,6 +318,9 @@
a {
text-decoration: underline;
}
.details-container {
border-top: 1px solid #888;
}
.name {
float: none;
background-image: url(/static/icons/computer.png);
......
from celery.task import Task, PeriodicTask
from celery.task import Task
import logging
import celery
import os
import sys
import time
from django.core.mail import send_mail
from django.conf import settings
from one.models import Instance
logger = logging.getLogger(__name__)
class SendMailTask(Task):
def run(self, to, subject, msg, sender=u'noreply@cloud.ik.bme.hu'):
send_mail(subject, msg, sender, [ to ], fail_silently=False)
logger.info("[django][one][tasks.py] %s->%s [%s]" % (sender, to, subject) )
def run(self, to, subject, msg, sender=None):
if sender is None:
if settings.SITE_NAME:
sender = '"%s" <%s>' % (settings.SITE_NAME.replace('"', ''),
settings.DEFAULT_FROM_EMAIL)
else:
sender = settings.DEFAULT_FROM_EMAIL
send_mail(subject, msg, sender, [to, ], fail_silently=False)
logger.info("[django][one][tasks] %s->%s %s" % (sender, to, subject))
class UpdateInstanceStateTask(Task):
def run(self, one_id):
def run(self, one_id, new_state):
print one_id
try:
inst = Instance.objects.get(one_id=one_id)
except:
print 'nincs ilyen'
return
inst.update_state()
inst.state = new_state
inst.waiting = False
inst.save()
if inst.template.state == 'SAVING':
inst.check_if_is_save_as_done()
print inst.state
# ezek csak azert vannak felveve, hogy szepen meg lehessen hivni oket
# ezeket a fejgepen futo celery futtatja
class CreateInstanceTask(Task):
def run(self, name, instance_type, disk_id, network_id, ctx):
pass
class DeleteInstanceTask(Task):
def run(self, one_id):
pass
class ChangeInstanceStateTask(Task):
def run(self, one_id, new_state):
pass
class SaveAsTask(Task):
def run(self, one_id, new_img):
pass
class UpdateDiskTask(Task):
def run(self):
pass
class UpdateNetworkTask(Task):
def run(self):
pass
......@@ -3,7 +3,7 @@
{% block body %}
{% blocktrans with vm=instance.name state=instance.state|lower date=instance.time_of_delete time=exp|timeuntil %}
{% blocktrans with vm=instance.name state=instance.state|lower date=instance.time_of_delete time=instance.time_of_delete|timeuntil %}
Your {{state}} virtual machine "{{vm}}" is going to be DELETED
at {{date}} (in {{time}}).
{% endblocktrans %}
......
......@@ -3,7 +3,7 @@
{% block body %}
{% blocktrans with vm=instance.name state=instance.state|lower date=instance.time_of_suspend time=exp|timeuntil url=url %}
{% blocktrans with vm=instance.name state=instance.state|lower date=instance.time_of_suspend time=instance.time_of_suspend|timeuntil url=url %}
Your {{state}} virtual machine "{{vm}}" is going to be STOPPED
at {{date}} (in {{time}}).
{% endblocktrans %}
......
......@@ -16,11 +16,10 @@ from django.template import RequestContext
from django.template.loader import render_to_string
from django.utils.decorators import method_decorator
from django.utils.translation import get_language as lang
from django.utils.translation import ugettext_lazy as _, ungettext_lazy
from django.utils.translation import ugettext_lazy as _
from django.views.decorators.http import *
from django.views.generic import *
from firewall.tasks import *
from cloud.settings import store_settings
from one.models import *
from school.models import *
import django.contrib.auth as auth
......@@ -28,6 +27,7 @@ import json
import logging
import subprocess
store_settings = settings.STORE_SETTINGS
logger = logging.getLogger(__name__)
def _list_instances(request):
......@@ -147,9 +147,19 @@ class AjaxTemplateEditWizard(View):
}))
def post(self, request, id, *args, **kwargs):
template = get_object_or_404(Template, id=id)
user_details = UserCloudDetails.objects.get(user=request.user)
if template.owner != request.user and not template.public and not request.user.is_superuser:
raise PermissionDenied()
template.instance_type_id = request.POST['size']
instance_type = get_object_or_404(InstanceType, id=request.POST['size'])
current_used_share_quota = user_details.get_weighted_share_count()
current_used_share_quota_without_template = current_used_share_quota - template.get_share_quota_usage_for(request.user)
new_quota_for_current_template = template.get_share_quota_usage_for_user_with_type(instance_type, request.user)
new_used_share_quota = current_used_share_quota_without_template + new_quota_for_current_template
allow_type_modify = True if new_used_share_quota <= user_details.share_quota else False
if not allow_type_modify:
messages.error(request, _('You do not have enough free share quota.'))
return redirect(home)
template.instance_type = instance_type
template.description = request.POST['description']
template.name = request.POST['name']
template.save()
......@@ -208,7 +218,11 @@ ajax_share_wizard = login_required(AjaxShareWizard.as_view())
class AjaxShareEditWizard(View):
def get(self, request, id, *args, **kwargs):
det = UserCloudDetails.objects.get(user=request.user)
if det.get_weighted_share_count() >= det.share_quota:
if det.get_weighted_share_count() > det.share_quota:
logger.warning('[one] User %s ha more used share quota, than its limit, how is that possible? (%d > %d)',
str(request.user),
det.get_weighted_share_count(),
det.share_quota)
return HttpResponse(unicode(_('You do not have any free share quota.')))
types = TYPES_L
for i, t in enumerate(types):
......@@ -228,16 +242,21 @@ class AjaxShareEditWizard(View):
stype = request.POST['type']
if not stype in TYPES.keys():
raise PermissionDenied()
il = request.POST['instance_limit']
if det.get_weighted_share_count() + int(il)*share.template.instance_type.credit > det.share_quota:
instance_limit = int(request.POST['instance_limit'])
current_used_share_quota = det.get_weighted_share_count()
current_used_share_quota_without_current_share = current_used_share_quota - share.get_used_quota()
new_quota_for_current_share = instance_limit * share.template.get_credits_per_instance()
new_used_share_quota = current_used_share_quota_without_current_share + new_quota_for_current_share
allow_stype_modify = True if new_used_share_quota <= det.share_quota else False
if not allow_stype_modify:
messages.error(request, _('You do not have enough free share quota.'))
return redirect('/')
share.name=request.POST['name']
share.description=request.POST['description']
share.type=stype
share.instance_limit=il
share.per_user_limit=request.POST['per_user_limit']
share.owner=request.user
return redirect(share.group)
share.name = request.POST['name']
share.description = request.POST['description']
share.type = stype
share.instance_limit = instance_limit
share.per_user_limit = request.POST['per_user_limit']
share.owner = request.user
share.save()
messages.success(request, _('Successfully edited share %s.') % share)
return redirect(share.group)
......@@ -300,7 +319,7 @@ def _check_quota(request, template, share):
@login_required
def vm_new(request, template=None, share=None, redir=True):
base = None
extra = None
extra = ''
if template:
base = get_object_or_404(Template, pk=template)
else:
......@@ -460,7 +479,7 @@ class VmDeleteView(View):
inst = get_object_or_404(Instance, id=iid, owner=request.user)
if inst.template.state != 'READY' and inst.template.owner == request.user:
inst.template.delete()
inst.delete()
inst.one_delete()
messages.success(request, _('Virtual machine is successfully deleted.'))
except:
messages.error(request, _('Failed to delete virtual machine.'))
......@@ -484,21 +503,12 @@ def vm_unshare(request, id, *args, **kwargs):
if not g.owners.filter(user=request.user).exists():
raise PermissionDenied()
try:
n = s.get_running()
m = s.get_running_or_stopped()
if n > 0:
messages.error(request, ungettext_lazy('There is a machine running of this share.',
'There are %(n)d machines running of this share.', n) %
{'n' : n})
elif m > 0:
messages.error(request, ungettext_lazy('There is a suspended machine of this share.',
'There are %(m)d suspended machines of this share.', m) %
{'m' : m})
if s.get_running_or_stopped() > 0:
messages.error(request, _('There are machines running of this share.'))
else:
s.delete()
messages.success(request, _('Share is successfully removed.'))
except Exception as e:
print e
except:
messages.error(request, _('Failed to remove share.'))
return redirect(g)
......@@ -533,7 +543,6 @@ def vm_renew(request, which, iid, *args, **kwargs):
try:
vm = get_object_or_404(Instance, id=iid, owner=request.user)
vm.renew()
messages.success(request, _('Virtual machine is successfully renewed.'))
except:
messages.error(request, _('Failed to renew virtual machine.'))
return redirect('/')
......
from django.test import TestCase
from models import create_user_profile, Person, Course, Semester
from models import create_user_profile, Person, Course, Semester, Group
from datetime import datetime, timedelta
class MockUser:
......@@ -55,11 +55,12 @@ class PersonTestCase(TestCase):
class CourseTestCase(TestCase):
def setUp(self):
now = datetime.now()
date = now.date()
delta = timedelta(weeks=7)
self.testperson1 = Person.objects.create(code="testperson1")
self.testperson2 = Person.objects.create(code="testperson2")
self.testsemester = Semester.objects.create(name="testsemester",
start=now-delta, end=now+delta)
start=date-delta, end=date+delta)
self.testcourse = Course.objects.create(code="testcode",
name="testname", short_name="tn")
self.testcourse.owners.add(self.testperson1, self.testperson2)
......@@ -72,3 +73,55 @@ class CourseTestCase(TestCase):
def test_owner_list(self):
owner_list = self.testcourse.owner_list()
self.assertIsNotNone(owner_list)
class SemesterTestCase(TestCase):
def setUp(self):
now = datetime.now()
date = now.date()
self.now = now
delta = timedelta(weeks=7)
self.last_semester = Semester.objects.create(name="testsem1",
start=date-3*delta, end=date-delta)
self.current_semester = Semester.objects.create(name="testsem2",
start=date-delta, end=date+delta)
self.next_semester = Semester.objects.create(name="testsem3",
start=date+delta, end=date+3*delta)
def test_is_on(self):
self.assertFalse(self.last_semester.is_on(self.now))
self.assertTrue(self.current_semester.is_on(self.now))
self.assertFalse(self.next_semester.is_on(self.now))
def test_get_current(self):
self.assertEqual(self.current_semester, Semester.get_current())
def test_unicode(self):
self.current_semester.__unicode__()
class GroupTestCase(TestCase):
def setUp(self):
date = datetime.now().date()
delta = timedelta(weeks=7)
semester = Semester.objects.create(name="testsem",
start=date-delta, end=date+delta)
self.testgroup = Group.objects.create(name="testgrp",
semester=semester)
def test_owner_list(self):
self.assertIsNotNone(self.testgroup.owner_list())
testowner1 = Person.objects.create(code="testprsn1")
self.testgroup.owners.add(testowner1)
self.assertIsNotNone(self.testgroup.owner_list())
testowner2 = Person.objects.create(code="testprsn2")
self.testgroup.owners.add(testowner2)
self.assertIsNotNone(self.testgroup.owner_list())
self.assertIn(", ", self.testgroup.owner_list())
def test_member_count(self):
self.assertEqual(0, self.testgroup.member_count())
testmember1 = Person.objects.create(code="testprsn3")
self.testgroup.members.add(testmember1)
self.assertEqual(1, self.testgroup.member_count())
testmember2 = Person.objects.create(code="testprsn4")
self.testgroup.members.add(testmember2)
self.assertEqual(2, self.testgroup.member_count())
from django.db import models
from django.http import Http404
import json, requests, time
from cloud.settings import store_settings as settings
import django.conf
settings = django.conf.settings.STORE_SETTINGS
# Create your models here.
#TODO Handle exceptions locally
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or sign in to comment