Commit 0d188bd6 by Őry Máté

Merge branch 'release-13.03.1' into releases

parents e0757a88 a5e7ec7a
......@@ -34,6 +34,10 @@ nosetests.xml
.project
.pydevproject
# Compiled CSS/JS resources
*.css
*.min.js
# Other
*.swp
*~
......
SHELL := /bin/bash
jsfiles += one/static/script/cloud.min.js
jsfiles += one/static/script/util.min.js
jsfiles += one/static/script/store.min.js
cssfiles += one/static/style/style.css
default: migrate collectstatic mo restart
default: migrate generatestatic collectstatic mo restart
pulldef: pull default
pull:
......@@ -14,6 +18,8 @@ po:
migrate:
./manage.py migrate
generatestatic: $(jsfiles) $(cssfiles)
collectstatic:
./manage.py collectstatic --noinput
......@@ -22,4 +28,10 @@ mo:
for i in */; do cd $$i; ls locale &>/dev/null && ../manage.py compilemessages || true; cd ..; done
restart:
sudo /etc/init.d/apache2 reload
sudo /etc/init.d/apache2 reload || sudo restart django
%.min.js: %.js
uglifyjs $< > $@
%.css: %.less
lessc one/static/style/style.less > one/static/style/style.css
from cloud.settings import DEBUG
def process_debug(req):
return {'DEBUG': DEBUG}
......@@ -5,7 +5,7 @@ DEBUG = True
TEMPLATE_DEBUG = DEBUG
ADMINS = (
('IK', 'cloud@iit.bme.hu'),
('IK', 'cloud@cloud.ik.bme.hu'),
)
MANAGERS = ADMINS
......@@ -73,6 +73,7 @@ STATICFILES_DIRS = (
# Always use forward slashes, even on Windows.
# Don't forget to use absolute paths, not relative paths.
'/opt/webadmin/cloud/one/static',
'/opt/webadmin/cloud/cloud/static',
)
# List of finder classes that know how to find static files in
......@@ -109,6 +110,17 @@ ROOT_URLCONF = 'cloud.urls'
# Python dotted path to the WSGI application used by Django's runserver.
WSGI_APPLICATION = 'cloud.wsgi.application'
TEMPLATE_CONTEXT_PROCESSORS = (
'django.contrib.auth.context_processors.auth',
'django.core.context_processors.debug',
'django.core.context_processors.i18n',
'django.core.context_processors.media',
'django.core.context_processors.static',
'django.core.context_processors.tz',
'django.contrib.messages.context_processors.messages',
'cloud.context_processors.process_debug',
)
TEMPLATE_DIRS = (
# Put strings here, like "/home/html/django_templates" or "C:/www/django/templates".
# Always use forward slashes, even on Windows.
......@@ -186,6 +198,8 @@ CELERY_ROUTES = {
'firewall.tasks.reload_firewall_task': {'queue': 'firewall'},
'firewall.tasks.reload_dhcp_task': {'queue': 'dhcp'},
'firewall.tasks.reload_blacklist_task': {'queue': 'firewall'},
'firewall.tasks.Periodic': {'queue': 'local'},
'one.tasks.SendMailTask': {'queue': 'local'},
}
store_settings = {
......@@ -200,7 +214,6 @@ store_settings = {
"store_public": "store.ik.bme.hu",
}
firewall_settings = {
"default_vlangroup": "publikus",
"reload_sleep": "10",
......@@ -210,6 +223,9 @@ firewall_settings = {
"dns_ttl": "300",
}
EMAIL_HOST='152.66.243.92' # giccero ipv4
CLOUD_URL='https://cloud.ik.bme.hu/'
try:
from cloud.local_settings import *
except:
......
<!DOCTYPE html>
<html lang="hu">
<head>
<title>IK Cloud</title>
<link href="https://fonts.googleapis.com/css?family=Titillium+Web&amp;subset=latin,latin-ext" rel="stylesheet" type="text/css" />
<link rel="icon" type="image/png" href="/static/favicon.png" />
<link href="/static/style/style.css" rel="stylesheet" type="text/css" />
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8" />
</head>
<body>
<div id="header">
<h1><a href="/">IK Cloud</a></h1>
</div>
<div id="content">
<div id="http-error">
<h1>Karbantartás – Maintenance</h1>
<p lang="hu">
Az oldal ideiglenesen nem érhető el karbantartás miatt. Elnézést kérünk a kellemetlenségekért.
</p>
<p lang="en">
The site is temporarily down for maintenance. We apologize for any inconvinience.
</p>
</div>
<div class="clear"></div>
</div>
<footer>
<a href="/sites/legal/">Impresszum</a> |
<a href="/sites/policy/">Szabályzat</a> |
<a href="/sites/help/">Súgó</a> |
<a href="/sites/support/">Támogatás</a> |
cloud <em>(kukac)</em> ik.bme.hu
</footer>
<script type="text/javascript">
var _gaq = _gaq || [];
_gaq.push(['_setAccount', 'UA-39125666-1']);
_gaq.push(['_trackPageview']);
(function() {
var ga = document.createElement('script'); ga.type = 'text/javascript'; ga.async = true;
ga.src = ('https:' == document.location.protocol ? 'https://ssl' : 'http://www') + '.google-analytics.com/ga.js';
var s = document.getElementsByTagName('script')[0]; s.parentNode.insertBefore(ga, s);
})();
</script>
</body>
</html>
{% extends "base.html" %}
{% load i18n %}
{% load staticfiles %}
{% get_current_language as LANGUAGE_CODE %}
{% block js %}
<script type="text/javascript" src="{% static "script/store.js" %}"></script>
<style>
.contentblock p{
margin: 15px;
text-align: justify;
}
.contentblock img{
margin: 0px auto;
display: block;
box-shadow: 0 0 30px rgba(0, 0, 0, 0.3);
border-radius: 5px;
text-align: center;
vertical-align: middle;
}
.boxes a:link,
a:visited {
color: black;
}
.boxes strong {
font-size: .9em;
}
</style>
{% endblock %}
{% block content %}
<div class="boxes">
<div class="contentblock" id="state">
<h2>A projektről</h2>
<div>
<p>Az <strong>IK Cloud</strong> a BME IK és IIT együttműködésében, a VIK
támogatásával hosszabb ideje folyó munka során jött létre.
A kutatás célja <strong>a cloud oktatási-kutatási célú felhasználásának</strong>
vonzóvá tétele.
</p>
<p>
A nagy kapacitású virtuális infrastruktúra azonban új lehetőséget is nyújt.
<strong>Igény szerint</strong> indíthatóak virtuális gépek:
gördülékennyé válik a tantermi és otthoni <strong>hallgatói munka,</strong>
a kutatási <strong>projektek dinamikus IT támogatása.</strong>
</p>
<p><img src="{% static "info/cloud-migration.png" %}" /></p>
<p>A rendszerünk segítségével <strong>kiváltható</strong> a tanszéken
működő öregedő szerverpark jelentős része.</p>
</div>
</div>
</div>
<div class="boxes">
<div class="contentblock" id="state">
<h2>Virtuális labor</h2>
<div>
<p><img src="{% static "info/cloud-lab.png" %}" /></p>
<p>Lehetőség van <strong>tantárgyra szabott környezet</strong> biztosítására
a tantermi mérések vagy az otthoni feladatok elvégzéséhez, vagy az
önkiszolgáló felületen pillanatok alatt indítható <strong>projektek, önálló
labor, szakdolgozat, diplomaterv, vagy TDK-munka</strong> segítéséhez
virtuális gép.</p>
<p style="text-align:center;"><a
href="{% url one.views.home %}">Próbálja ki a rendszert
most!</a></p>
</div>
</div>
<div class="contentblock" id="state" lang="en">
<h2>About the project</h2>
<div>
<p>The project aims to harness the power of cloud computing in
education and research. Our self service portal helps migrating
old servers, and on-demand launching appliances prepared by the
teacher.</p>
</p>
</div>
</div>
</div>
{% endblock %}
{% extends "base.html" %}
{% load i18n %}
{% load staticfiles %}
{% get_current_language as LANGUAGE_CODE %}
{% block content %}
<div class="irasmu">
<p>A súgó elkészültéig kérjük szíves türelmüket.</p>
<p>Addig is ajánljuk figyelmükbe a rendszer <a href="/info/">rövid ismertetőjét</a>, a használat módját részletező <a href="/sites/policy/">szabályzatot</a>, valamint a felület számos pontján megjelenő <img src="{% static "icons/information-frame.png" %}" alt="Súgó" /> ikonnal jelölt információdobozokat.</p>
<p>Amennyiben kérdése maradt, örömmel segítünk a <a href="/sites/support/">támogatás</a> oldalon leírt elérhetőségeinken.</p>
</div>
{% endblock %}
{% extends "base.html" %}
{% load i18n %}
{% get_current_language as LANGUAGE_CODE %}
{% block content %}
<div class="irasmu">
<p>Az IK Cloud a BME IK és IIT együttműködésében, a VIK támogatásával létrejött rendszer, amelyben az IIT oktatói és hallgatói szükség szerint vehetnek igénybe virtuális erőforrásokat.
</p>
<p>Az oldal üzemeltetője a BME Közigazgatási Informatikai Központ.</p>
<p>A rendszer fejlesztésében részt vettek:
Bach Dániel,
Dányi Bence,
Dudás Ádám,
Guba Sándor,
Őry Máté és
dr. Szeberényi Imre.</p>
<p>A rendszer HP hardveren, Ubuntu operációs rendszeren, KVM virtualizációval, Open vSwitch virtuális hálózaton, libvirt köztes réteggel, OpenNebula cloud menedzserrel, Django alapú webportállal működik.</p>
<p>Some icons by <a href="http://p.yusukekamiyamane.com/">Yusuke Kamiyamane</a>. Licensed under a <a href="http://creativecommons.org/licenses/by/3.0/">Creative Commons Attribution 3.0 License</a>.</p>
</div>
{% endblock %}
{% extends "base.html" %}
{% load i18n %}
{% get_current_language as LANGUAGE_CODE %}
{% block content %}
<div class="irasmu">
<p>Az IK Cloud a BME IK és IIT együttműködésében, a VIK támogatásával létrejött rendszer, amelyben az IIT oktatói és hallgatói szükség szerint vehetnek igénybe <strong>virtuális erőforrásokat</strong>.</p>
<p>Az IIT géptermeiben telepített kliensszoftver segítségével az oktató által előkészített és kiajánlott <strong>virtuális környezetet a hallgató</strong> a számára megszabott <strong>kvóta keretein belül</strong> igény szerint indíthatja.</p>
<p>A HSZK géptermeiben a kliensszoftver jelenleg nincs telepítve, de a virtuális gépek indítása, a fájlok elérése webböngészővel is teljes értékű; míg a gépekhez való csatlakozás kézzel elvégezhető.</p>
<p>Lehetőség van a gépteremben elkezdett munka otthoni folytatására is a korábban elindított környezetben. A rendszer segítségével az otthoni feladatot végző hallgató is elkerülheti az összetett szoftverkörnyezet telepítésével járó kellemetlenségeket, figyelmét a szakmai munkára irányíthatja.</p>
<p>A rendszer segítséget nyújt önálló labor, szakdolgozat, diplomaterv vagy tdk-munka készítésénél is: a munkához szükséges virtuális gépeket az önkiszolgáló rendszeren keresztül azonnal használatba lehet venni.</p>
<p>Az elindított virtuális gépekre az adott operációs rendszeren szokásos módon lehet távolról csatlakozni: Windows esetén RDP (távoli asztal), Linux esetén SSH, vagy grafikusan NoMachine NX segítségével. A kapcsolódást a géptermekben telepített kliensszoftver még kényelmesebbé teszi.</p>
<p>Az elindított gépeken a <strong>felhasználói adattár</strong> automatikusan csatolásra kerül. Minden munkát itt érdemes végezni, mivel az a gép leállítása után is elérhető marad.</p>
<p>A felhasználók a rendszert jelen önkiszolgáló felületen keresztül érhetik el, amelybe az egyetemi címtárszolgáltatás (eduID) segítségével léphetnek be. A továbblépéssel elfogadják a következőekben összefoglalt <strong>felhasználási feltételeket</strong>.</p>
<ul>
<li>A rendszer <strong>nem használható</strong> semmilyen jogszabályba, vagy <a href="http://net.bme.hu/regula/">egyetemi</a> <strong>szabályzatba ütköző tevékenységre</strong>.</li>
<li><strong>Kizárólag tanulmányi</strong> vagy <strong>kutatási tevékenységhez</strong> használható erőforrás.</li>
<li>Bár a rendszer használata térítésmentes, a <strong>felesleges gépek leállítása</strong> a felhasználó kötelessége.</li>
<li>Minden gép indítása <strong>határidő kijelölésével</strong> történik. A határidő lejártával <strong>a gépet megállítjuk</strong>. Amennyiben a felhasználó a megállítást követően (a törlési határidő leteltéig) nem kéri meghosszabbítását, a gépet és <strong>minden rajta lévő adatot törlünk!</strong></li>
<li>A felhasználó felelőssége a futtatott rendszer biztonságos üzemeltetése, a hosszabb időn át futó gépek frissítése.</li>
<li>A rendszert üzemeltető BME IK lehetőségeihez mérten mindent megtesz a szolgáltatásbiztos üzemért, az egyetemi infrastruktúra sajátosságai miatt előforduló üzemszünetekre azonban számítani kell. A BME IK az üzemeltetés kapcsán a folyamatos üzem sérüléséért vagy adatvesztésért <strong>minden felelősséget kizár</strong>. Ezeknek megfelelően szükség esetén a biztonsági mentés és a magas rendelkezésre állású környezet kialakítása a felhasználóra hárul.</li>
</ul>
<p>A szabályok betartása közös érdekünk. Reméljük, hogy a rendszerünk használata megkönnyíti munkájukat, melyhez sok sikert kívánunk!</p>
</div>
{% endblock %}
{% extends "base.html" %}
{% load i18n %}
{% get_current_language as LANGUAGE_CODE %}
{% block content %}
<div class="irasmu">
<p>A rendszer használatával kapcsolatos kérdéseket, általános észrevételeket a <tt>cloud <em>(kukac)</em>
ik.bme.hu</tt> e-mail címen várjuk.
Ugyancsak örömmel fogadjuk a rendszer használatával kapcsolatos beszámolókat.</p>
<p>A rendszerben talált hibákat (vagy azok gyanúját), valamint ötleteit, javaslatait kérjük,
<a href="https://giccero.cloud.ik.bme.hu/trac/cloud/newticket" rel="nofollow">
hibajegy felvételével</a> jelezze.
</p>
</div>
{% endblock %}
......@@ -5,107 +5,91 @@ admin.autodiscover()
import one.views
import firewall.views
#import store.views
# import store.views
js_info_dict = {
'packages': ('one', ),
}
urlpatterns = patterns('',
url(r'^admin/doc/', include('django.contrib.admindocs.urls')),
url(r'^admin/', include(admin.site.urls)),
url(r'^$', 'one.views.home', name='home'),
url(r'^login/$', 'school.views.login', name='login'),
url(r'^logout/$', 'school.views.logout', name='logout'),
url(r'^vm/new/(?P<template>\d+)/$', 'one.views.vm_new', name='vm_new'),
url(r'^ajax/vm/new/(?P<template>\d+)/$', 'one.views.vm_new_ajax',
name='vm_new_ajax'),
url(r'^vm/new/s(?P<share>\d+)/$', 'one.views.vm_new', name='vm_new'),
url(r'^vm/show/(?P<iid>\d+)/$', 'one.views.vm_show', name='vm_show'),
url(r'^vm/delete/(?P<iid>\d+)/$', 'one.views.vm_delete',
name='vm_delete'),
url(r'^vm/stop/(?P<iid>\d+)/$', 'one.views.vm_stop', name='vm_stop'),
url(r'^vm/unshare/(?P<id>\d+)/$', 'one.views.vm_unshare',
name='vm_unshare'),
url(r'^vm/resume/(?P<iid>\d+)/$', 'one.views.vm_resume',
name='vm_resume'),
url(r'^vm/power_off/(?P<iid>\d+)/$', 'one.views.vm_power_off',
name='vm_power_off'),
url(r'^vm/restart/(?P<iid>\d+)/$', 'one.views.vm_restart',
name='vm_restart'),
url(r'^admin/doc/', include('django.contrib.admindocs.urls'), ),
url(r'^admin/', include(admin.site.urls), ),
url(r'^login/$', 'school.views.login', name='login', ),
url(r'^logout/$', 'school.views.logout', name='logout', ),
url(r'^$', 'one.views.index', ),
url(r'^info/$', 'one.views.info', ),
url(r'^home/$', 'one.views.home', ),
url(r'^vm/new/(?P<template>\d+)/$', 'one.views.vm_new',
name='new_vm_from_template'),
url(r'^ajax/vm/new/(?P<template>\d+)/$', 'one.views.vm_new_ajax', ),
url(r'^vm/new/s(?P<share>\d+)/$', 'one.views.vm_new',
name='new_vm_form_share'),
url(r'^vm/show/(?P<iid>\d+)/$', 'one.views.vm_show', ),
url(r'^vm/delete/(?P<iid>\d+)/$', 'one.views.vm_delete', ),
url(r'^vm/stop/(?P<iid>\d+)/$', 'one.views.vm_stop', ),
url(r'^vm/unshare/(?P<id>\d+)/$', 'one.views.vm_unshare', ),
url(r'^vm/resume/(?P<iid>\d+)/$', 'one.views.vm_resume', ),
url(r'^vm/power_off/(?P<iid>\d+)/$', 'one.views.vm_power_off', ),
url(r'^vm/restart/(?P<iid>\d+)/$', 'one.views.vm_restart', ),
url(r'^vm/renew/(?P<which>(suspend|delete))/(?P<iid>\d+)/$',
'one.views.vm_renew', name='vm_renew'),
url(r'^vm/port_add/(?P<iid>\d+)/$', 'one.views.vm_port_add',
name='vm_port_add'),
'one.views.vm_renew', ),
url(r'^vm/port_add/(?P<iid>\d+)/$', 'one.views.vm_port_add', ),
url(r'^vm/port_del/(?P<iid>\d+)/(?P<proto>tcp|udp)/(?P<public>\d+)/$',
'one.views.vm_port_del', name='vm_port_del'),
url(r'^vm/saveas/(?P<vmid>\d+)$', 'one.views.vm_saveas',
name='vm_saveas'),
url(r'^vm/credentials/(?P<iid>\d+)$', 'one.views.vm_credentials',
name='vm_credentials'),
url(r'^reload/$', 'firewall.views.reload_firewall',
name='reload_firewall'),
url(r'^fwapi/$', 'firewall.views.firewall_api',
name='firewall_api'),
url(r'^store/$', 'store.views.index', name='store_index'),
url(r'^store/gui/$', 'store.views.gui', name='store_gui'),
url(r'^store/top/$', 'store.views.toplist', name='store_top'),
url(r'^ajax/store/top/$', 'store.views.ajax_toplist',
name='axat_store_top'),
url(r'^ajax/templateWizard$', 'one.views.ajax_template_wizard',
name='ajax_template_wizard'),
url(r'^ajax/share/(?P<id>\d+)/$', 'one.views.ajax_share_wizard',
name='ajax_share_wizard'),
'one.views.vm_port_del', ),
url(r'^ajax/shareEdit/(?P<id>\d+)/$', 'one.views.ajax_share_edit_wizard',
name='ajax_share_edit_wizard'),
url(r'^vm/saveas/(?P<vmid>\d+)$', 'one.views.vm_saveas', ),
url(r'^vm/credentials/(?P<iid>\d+)$', 'one.views.vm_credentials', ),
url(r'^ajax/templateWizard/$', 'one.views.ajax_template_wizard', ),
url(r'^ajax/templateEditWizard/(?P<id>\d+)/$', 'one.views.ajax_template_edit_wizard', ),
url(r'^ajax/share/(?P<id>\d+)/$', 'one.views.ajax_share_wizard', ),
url(r'^ajax/share/(?P<id>\d+)/(?P<gid>\d+)$',
'one.views.ajax_share_wizard', name='ajax_share_wizard'),
url(r'^ajax/template/delete/$', 'one.views.ajax_template_delete',
name='ajax_template_delete'),
url(r'^ajax/template_name_unique/(?P<name>.*)$',
'one.views.ajax_template_name_unique',
name='ajax_template_name_unique'),
url(r'^ajax/store/list$', 'store.views.ajax_listfolder',
name='store_ajax_listfolder'),
url(r'^ajax/store/download$', 'store.views.ajax_download',
name='store_ajax_download'),
url(r'^ajax/store/upload$', 'store.views.ajax_upload',
name='store_ajax_upload'),
url(r'^ajax/store/delete$', 'store.views.ajax_delete',
name='store_ajax_delete'),
url(r'^ajax/store/newFolder$', 'store.views.ajax_new_folder',
name='store_ajax_new_folder'),
url(r'^ajax/store/quota$', 'store.views.ajax_quota',
name='store_ajax_quota'),
url(r'^ajax/store/rename$', 'store.views.ajax_rename',
name='store_ajax_rename'),
'one.views.ajax_share_wizard', ),
url(r'^ajax/vm/status/(?P<iid>\d+)$',
'one.views.vm_ajax_instance_status',
name='vm_ajax_instance_status'),
'one.views.vm_ajax_instance_status', ),
url(r'^ajax/vm/rename/(?P<iid>\d+)/$',
'one.views.vm_ajax_rename',
name='vm_ajax_rename'),
url(r'^language/(?P<lang>[-A-Za-z]+)/$', 'school.views.language',
name='language'),
url(r'^jsi18n/$', 'django.views.i18n.javascript_catalog', js_info_dict),
url(r'^b/(?P<token>.*)/$', 'one.views.boot_token', name='boot_token'),
'one.views.vm_ajax_rename', ),
url(r'^key/add/$', 'one.views.key_add', ),
url(r'^ajax/key/delete/$', 'one.views.key_ajax_delete', ),
url(r'^ajax/key/reset/$', 'one.views.key_ajax_reset', ),
url(r'^ajax/template/delete/$', 'one.views.ajax_template_delete', ),
url(r'^ajax/template_name_unique/$',
'one.views.ajax_template_name_unique', ),
url(r'^reload/$', 'firewall.views.reload_firewall', ),
url(r'^fwapi/$', 'firewall.views.firewall_api', ),
url(r'^store/$', 'store.views.index', ),
url(r'^store/gui/$', 'store.views.gui', ),
url(r'^store/top/$', 'store.views.toplist', ),
url(r'^ajax/store/top/$', 'store.views.ajax_toplist', ),
url(r'^ajax/store/list$', 'store.views.ajax_listfolder', ),
url(r'^ajax/store/download$', 'store.views.ajax_download', ),
url(r'^ajax/store/upload$', 'store.views.ajax_upload', ),
url(r'^ajax/store/delete$', 'store.views.ajax_delete', ),
url(r'^ajax/store/newFolder$', 'store.views.ajax_new_folder', ),
url(r'^ajax/store/quota$', 'store.views.ajax_quota', ),
url(r'^ajax/store/rename$', 'store.views.ajax_rename', ),
url(r'^language/(?P<lang>[-A-Za-z]+)/$', 'school.views.language', ),
url(r'^jsi18n/$', 'django.views.i18n.javascript_catalog', js_info_dict, ),
url(r'^b/(?P<token>.*)/$', 'one.views.boot_token', ),
url(r'^group/show/(?P<gid>\d+)/$', 'school.views.group_show',
name='group_show'),
url(r'^group/new/$', 'school.views.group_new', name='group_new'),
url(r'^group/new/$', 'school.views.group_new', ),
url(r'^ajax/group/(?P<gid>\d+)/add/$',
'school.views.group_ajax_add_new_member',
name='group_ajax_add_new_member'),
'school.views.group_ajax_add_new_member', ),
url(r'^ajax/group/(?P<gid>\d+)/addOwner/$',
'school.views.group_ajax_add_new_owner',
name='group_ajax_add_new_owner'),
'school.views.group_ajax_add_new_owner', ),
url(r'^ajax/group/(?P<gid>\d+)/remove/$',
'school.views.group_ajax_remove_member',
name='group_ajax_remove_member'),
url(r'^ajax/group/delete/$', 'school.views.group_ajax_delete',
name='group_ajax_delete'),
url(r'^ajax/group/autocomplete/$', 'school.views.group_ajax_owner_autocomplete',
name='group_ajax_autocomplete'),
url(r'^key/add/$', 'one.views.key_add', name='key_add'),
url(r'^ajax/key/delete/$', 'one.views.key_ajax_delete',
name='key_ajax_delete'),
url(r'^ajax/key/reset/$', 'one.views.key_ajax_reset',
name='key_ajax_reset'),
'school.views.group_ajax_remove_member', ),
url(r'^ajax/group/delete/$', 'school.views.group_ajax_delete', ),
url(r'^ajax/group/autocomplete/$',
'school.views.group_ajax_owner_autocomplete', ),
url(r'^stat/$', 'one.views.stat'),
url(r'^sites/(?P<site>[a-zA-Z0-9]+)/$', 'one.views.sites'),
url(r'^accounts/(?P<site>profile)/$', 'one.views.sites'),
)
......@@ -13,7 +13,7 @@ class RecordInline(contrib.admin.TabularInline):
class HostAdmin(admin.ModelAdmin):
list_display = ('hostname', 'vlan', 'ipv4', 'ipv6', 'pub_ipv4', 'mac',
'shared_ip', 'owner', 'description', 'reverse', 'groups_l')
'shared_ip', 'owner', 'description', 'reverse', 'list_groups')
ordering = ('hostname', )
list_filter = ('owner', 'vlan', 'groups')
search_fields = ('hostname', 'description', 'ipv4', 'ipv6', 'mac')
......@@ -21,7 +21,7 @@ class HostAdmin(admin.ModelAdmin):
inlines = (RuleInline, RecordInline)
@staticmethod
def groups_l(instance):
def list_groups(instance):
"""Returns instance's groups' names as a comma-separated list."""
names = [group.name for group in instance.groups.all()]
return u', '.join(names)
......@@ -45,34 +45,36 @@ class RuleAdmin(admin.ModelAdmin):
def color_desc(self, instance):
"""Returns a colorful description of the instance."""
para = '</span>'
if instance.dport:
para = 'dport=%s %s' % (instance.dport, para)
if instance.sport:
para = 'sport=%s %s' % (instance.sport, para)
if instance.proto:
para = 'proto=%s %s' % (instance.proto, para)
para = u'<span style="color: #00FF00;">' + para
return (
u'<span style="color: #FF0000;">[%s]</span> ' % instance.r_type +
(u'%s<span style="color: #0000FF;"> ▸ </span>%s' %
((instance.foreign_network.name, instance.r_type)
if instance.direction == '1' else
(instance.r_type, instance.foreign_network.name))) +
' ' + para + ' ' + instance.description)
return (u'<span style="color: #FF0000;">[%(type)s]</span> '
u'%(src)s<span style="color: #0000FF;"> ▸ </span>%(dst)s '
u'%(para)s %(desc)s') % {
'type': instance.r_type,
'src': (instance.foreign_network.name
if instance.direction == '1' else instance.r_type),
'dst': (instance.r_type if instance.direction == '1'
else instance.foreign_network.name),
'para': (u'<span style="color: #00FF00;">' +
(('proto=%s ' % instance.proto)
if instance.proto else '') +
(('sport=%s ' % instance.sport)
if instance.sport else '') +
(('dport=%s ' % instance.dport)
if instance.dport else '') +
'</span>'),
'desc': instance.description}
color_desc.allow_tags = True
def vlan_l(self, instance):
@staticmethod
def vlan_l(instance):
"""Returns instance's VLANs' names as a comma-separated list."""
retval = []
for vlan in instance.foreign_network.vlans.all():
retval.append(vlan.name)
return u', '.join(retval)
names = [vlan.name for vlan in instance.foreign_network.vlans.all()]
return u', '.join(names)
def used_in(self, instance):
@staticmethod
def used_in(instance):
for field in [instance.vlan, instance.vlangroup, instance.host,
instance.hostgroup, instance.firewall]:
if field is not None:
if field:
return unicode(field) + ' ' + field._meta.object_name
......@@ -92,15 +94,15 @@ class DomainAdmin(admin.ModelAdmin):
class RecordAdmin(admin.ModelAdmin):
list_display = ('name_', 'type', 'address_', 'ttl', 'host', 'owner')
def address_(self, instance):
@staticmethod
def address_(instance):
a = instance.get_data()
if a:
return a['address']
return a['address'] if a else None
def name_(self, instance):
@staticmethod
def name_(instance):
a = instance.get_data()
if a:
return a['name']
return a['name'] if a else None
class BlacklistAdmin(admin.ModelAdmin):
list_display = ('ipv4', 'reason', 'created_at', 'modified_at')
......
......@@ -2,6 +2,7 @@ from django.core.exceptions import ValidationError
from django.forms import fields
from django.db import models
from django.utils.translation import ugettext_lazy as _
from django.utils.ipv6 import is_valid_ipv6_address
from south.modelsinspector import add_introspection_rules
import re
......@@ -35,26 +36,46 @@ class MACAddressField(models.Field):
add_introspection_rules([], ["firewall\.fields\.MACAddressField"])
def val_alfanum(value):
"""Check whether the parameter is a valid alphanumeric value."""
if alfanum_re.search(value) is None:
raise ValidationError(
_(u'%s - only letters, numbers, underscores and hyphens are '
'allowed!') % value)
"""Validate whether the parameter is a valid alphanumeric value."""
if not alfanum_re.match(value):
raise ValidationError(_(u'%s - only letters, numbers, underscores '
'and hyphens are allowed!') % value)
def is_valid_domain(value):
"""Check whether the parameter is a valid domain name."""
return domain_re.match(value) is not None
def val_domain(value):
"""Check wheter the parameter is a valid domin."""
if domain_re.search(value) is None:
raise ValidationError(_(u'%s - invalid domain') % value)
"""Validate whether the parameter is a valid domin name."""
if not is_valid_domain(value):
raise ValidationError(_(u'%s - invalid domain name') % value)
def is_valid_reverse_domain(value):
"""Check whether the parameter is a valid reverse domain name."""
return reverse_domain_re.match(value) is not None
def val_reverse_domain(value):
"""Check whether the parameter is a valid reverse domain."""
if not reverse_domain_re.search(value):
raise ValidationError(u'%s - reverse domain' % value)
"""Validate whether the parameter is a valid reverse domain name."""
if not is_valid_reverse_domain(value):
raise ValidationError(u'%s - invalid reverse domain name' % value)
def is_valid_ipv4_address(value):
"""Check whether the parameter is a valid IPv4 address."""
return ipv4_re.match(value) is not None
def val_ipv4(value):
"""Validate whether the parameter is a valid IPv4 address."""
if not is_valid_ipv4_address(value):
raise ValidationError(_(u'%s - not an IPv4 address') % value)
def val_ipv6(value):
"""Validate whether the parameter is a valid IPv6 address."""
if not is_valid_ipv6_address(value):
raise ValidationError(_(u'%s - not an IPv6 address') % value)
def ipv4_2_ipv6(ipv4):
"""Convert IPv4 address string to IPv6 address string."""
val_ipv4(ipv4)
m = ipv4_re.match(ipv4)
if m is None:
raise ValidationError(_(u'%s - not an IPv4 address') % ipv4)
return ("2001:738:2001:4031:%s:%s:%s:0" %
(m.group(1), m.group(2), m.group(3)))
......@@ -10,7 +10,7 @@ from datetime import datetime, timedelta
from django.db.models import Q
class firewall:
class Firewall:
IPV6=False
RULES = None
RULES_NAT = []
......@@ -36,14 +36,15 @@ class firewall:
def iptables(self, s):
"""Append rule."""
"""Append rule to filter table."""
self.RULES.append(s)
def iptablesnat(self, s):
"""Append rule to NAT table."""
self.RULES_NAT.append(s)
def host2vlan(self, host, rule):
if rule.foreign_network is None:
if not rule.foreign_network:
return
if self.IPV6 and host.ipv6:
......@@ -76,7 +77,7 @@ class firewall:
def fw2vlan(self, rule):
if rule.foreign_network is None:
if not rule.foreign_network:
return
dport_sport = self.dportsport(rule)
......@@ -92,7 +93,7 @@ class firewall:
'LOG_ACC' if rule.accept else 'LOG_DROP'))
def vlan2vlan(self, l_vlan, rule):
if rule.foreign_network is None:
if not rule.foreign_network:
return
dport_sport = self.dportsport(rule)
......
# -*- coding: utf-8 -*-
import datetime
from south.db import db
from south.v2 import SchemaMigration
from django.db import models
class Migration(SchemaMigration):
def forwards(self, orm):
# Adding field 'Blacklist.host'
db.add_column('firewall_blacklist', 'host',
self.gf('django.db.models.fields.related.ForeignKey')(to=orm['firewall.Host'], null=True, blank=True),
keep_default=False)
def backwards(self, orm):
# Deleting field 'Blacklist.host'
db.delete_column('firewall_blacklist', 'host_id')
models = {
'auth.group': {
'Meta': {'object_name': 'Group'},
'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}),
'name': ('django.db.models.fields.CharField', [], {'unique': 'True', 'max_length': '80'}),
'permissions': ('django.db.models.fields.related.ManyToManyField', [], {'to': "orm['auth.Permission']", 'symmetrical': 'False', 'blank': 'True'})
},
'auth.permission': {
'Meta': {'ordering': "('content_type__app_label', 'content_type__model', 'codename')", 'unique_together': "(('content_type', 'codename'),)", 'object_name': 'Permission'},
'codename': ('django.db.models.fields.CharField', [], {'max_length': '100'}),
'content_type': ('django.db.models.fields.related.ForeignKey', [], {'to': "orm['contenttypes.ContentType']"}),
'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}),
'name': ('django.db.models.fields.CharField', [], {'max_length': '50'})
},
'auth.user': {
'Meta': {'object_name': 'User'},
'date_joined': ('django.db.models.fields.DateTimeField', [], {'default': 'datetime.datetime.now'}),
'email': ('django.db.models.fields.EmailField', [], {'max_length': '75', 'blank': 'True'}),
'first_name': ('django.db.models.fields.CharField', [], {'max_length': '30', 'blank': 'True'}),
'groups': ('django.db.models.fields.related.ManyToManyField', [], {'to': "orm['auth.Group']", 'symmetrical': 'False', 'blank': 'True'}),
'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}),
'is_active': ('django.db.models.fields.BooleanField', [], {'default': 'True'}),
'is_staff': ('django.db.models.fields.BooleanField', [], {'default': 'False'}),
'is_superuser': ('django.db.models.fields.BooleanField', [], {'default': 'False'}),
'last_login': ('django.db.models.fields.DateTimeField', [], {'default': 'datetime.datetime.now'}),
'last_name': ('django.db.models.fields.CharField', [], {'max_length': '30', 'blank': 'True'}),
'password': ('django.db.models.fields.CharField', [], {'max_length': '128'}),
'user_permissions': ('django.db.models.fields.related.ManyToManyField', [], {'to': "orm['auth.Permission']", 'symmetrical': 'False', 'blank': 'True'}),
'username': ('django.db.models.fields.CharField', [], {'unique': 'True', 'max_length': '30'})
},
'contenttypes.contenttype': {
'Meta': {'ordering': "('name',)", 'unique_together': "(('app_label', 'model'),)", 'object_name': 'ContentType', 'db_table': "'django_content_type'"},
'app_label': ('django.db.models.fields.CharField', [], {'max_length': '100'}),
'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}),
'model': ('django.db.models.fields.CharField', [], {'max_length': '100'}),
'name': ('django.db.models.fields.CharField', [], {'max_length': '100'})
},
'firewall.blacklist': {
'Meta': {'object_name': 'Blacklist'},
'created_at': ('django.db.models.fields.DateTimeField', [], {'auto_now_add': 'True', 'blank': 'True'}),
'host': ('django.db.models.fields.related.ForeignKey', [], {'to': "orm['firewall.Host']", 'null': 'True', 'blank': 'True'}),
'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}),
'ipv4': ('django.db.models.fields.GenericIPAddressField', [], {'unique': 'True', 'max_length': '39'}),
'modified_at': ('django.db.models.fields.DateTimeField', [], {'auto_now': 'True', 'blank': 'True'}),
'reason': ('django.db.models.fields.TextField', [], {'blank': 'True'}),
'snort_message': ('django.db.models.fields.TextField', [], {'blank': 'True'}),
'type': ('django.db.models.fields.CharField', [], {'default': "'tempban'", 'max_length': '10'})
},
'firewall.domain': {
'Meta': {'object_name': 'Domain'},
'created_at': ('django.db.models.fields.DateTimeField', [], {'auto_now_add': 'True', 'blank': 'True'}),
'description': ('django.db.models.fields.TextField', [], {'blank': 'True'}),
'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}),
'modified_at': ('django.db.models.fields.DateTimeField', [], {'auto_now': 'True', 'blank': 'True'}),
'name': ('django.db.models.fields.CharField', [], {'max_length': '40'}),
'owner': ('django.db.models.fields.related.ForeignKey', [], {'to': "orm['auth.User']"}),
'ttl': ('django.db.models.fields.IntegerField', [], {'default': '600'})
},
'firewall.firewall': {
'Meta': {'object_name': 'Firewall'},
'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}),
'name': ('django.db.models.fields.CharField', [], {'unique': 'True', 'max_length': '20'})
},
'firewall.group': {
'Meta': {'object_name': 'Group'},
'created_at': ('django.db.models.fields.DateTimeField', [], {'auto_now_add': 'True', 'blank': 'True'}),
'description': ('django.db.models.fields.TextField', [], {'blank': 'True'}),
'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}),
'modified_at': ('django.db.models.fields.DateTimeField', [], {'auto_now': 'True', 'blank': 'True'}),
'name': ('django.db.models.fields.CharField', [], {'unique': 'True', 'max_length': '20'}),
'owner': ('django.db.models.fields.related.ForeignKey', [], {'to': "orm['auth.User']", 'null': 'True', 'blank': 'True'})
},
'firewall.host': {
'Meta': {'object_name': 'Host'},
'comment': ('django.db.models.fields.TextField', [], {'blank': 'True'}),
'created_at': ('django.db.models.fields.DateTimeField', [], {'auto_now_add': 'True', 'blank': 'True'}),
'description': ('django.db.models.fields.TextField', [], {'blank': 'True'}),
'groups': ('django.db.models.fields.related.ManyToManyField', [], {'symmetrical': 'False', 'to': "orm['firewall.Group']", 'null': 'True', 'blank': 'True'}),
'hostname': ('django.db.models.fields.CharField', [], {'unique': 'True', 'max_length': '40'}),
'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}),
'ipv4': ('django.db.models.fields.GenericIPAddressField', [], {'unique': 'True', 'max_length': '39'}),
'ipv6': ('django.db.models.fields.GenericIPAddressField', [], {'max_length': '39', 'unique': 'True', 'null': 'True', 'blank': 'True'}),
'location': ('django.db.models.fields.TextField', [], {'blank': 'True'}),
'mac': ('firewall.fields.MACAddressField', [], {'unique': 'True', 'max_length': '17'}),
'modified_at': ('django.db.models.fields.DateTimeField', [], {'auto_now': 'True', 'blank': 'True'}),
'owner': ('django.db.models.fields.related.ForeignKey', [], {'to': "orm['auth.User']"}),
'pub_ipv4': ('django.db.models.fields.GenericIPAddressField', [], {'max_length': '39', 'null': 'True', 'blank': 'True'}),
'reverse': ('django.db.models.fields.CharField', [], {'max_length': '40', 'null': 'True', 'blank': 'True'}),
'shared_ip': ('django.db.models.fields.BooleanField', [], {'default': 'False'}),
'vlan': ('django.db.models.fields.related.ForeignKey', [], {'to': "orm['firewall.Vlan']"})
},
'firewall.record': {
'Meta': {'object_name': 'Record'},
'address': ('django.db.models.fields.CharField', [], {'max_length': '40', 'null': 'True', 'blank': 'True'}),
'created_at': ('django.db.models.fields.DateTimeField', [], {'auto_now_add': 'True', 'blank': 'True'}),
'description': ('django.db.models.fields.TextField', [], {'blank': 'True'}),
'domain': ('django.db.models.fields.related.ForeignKey', [], {'to': "orm['firewall.Domain']"}),
'host': ('django.db.models.fields.related.ForeignKey', [], {'to': "orm['firewall.Host']", 'null': 'True', 'blank': 'True'}),
'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}),
'modified_at': ('django.db.models.fields.DateTimeField', [], {'auto_now': 'True', 'blank': 'True'}),
'name': ('django.db.models.fields.CharField', [], {'max_length': '40', 'null': 'True', 'blank': 'True'}),
'owner': ('django.db.models.fields.related.ForeignKey', [], {'to': "orm['auth.User']"}),
'ttl': ('django.db.models.fields.IntegerField', [], {'default': '600'}),
'type': ('django.db.models.fields.CharField', [], {'max_length': '6'})
},
'firewall.rule': {
'Meta': {'object_name': 'Rule'},
'accept': ('django.db.models.fields.BooleanField', [], {'default': 'False'}),
'created_at': ('django.db.models.fields.DateTimeField', [], {'auto_now_add': 'True', 'blank': 'True'}),
'description': ('django.db.models.fields.TextField', [], {'blank': 'True'}),
'direction': ('django.db.models.fields.CharField', [], {'max_length': '1'}),
'dport': ('django.db.models.fields.IntegerField', [], {'null': 'True', 'blank': 'True'}),
'extra': ('django.db.models.fields.TextField', [], {'blank': 'True'}),
'firewall': ('django.db.models.fields.related.ForeignKey', [], {'blank': 'True', 'related_name': "'rules'", 'null': 'True', 'to': "orm['firewall.Firewall']"}),
'foreign_network': ('django.db.models.fields.related.ForeignKey', [], {'related_name': "'ForeignRules'", 'to': "orm['firewall.VlanGroup']"}),
'host': ('django.db.models.fields.related.ForeignKey', [], {'blank': 'True', 'related_name': "'rules'", 'null': 'True', 'to': "orm['firewall.Host']"}),
'hostgroup': ('django.db.models.fields.related.ForeignKey', [], {'blank': 'True', 'related_name': "'rules'", 'null': 'True', 'to': "orm['firewall.Group']"}),
'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}),
'modified_at': ('django.db.models.fields.DateTimeField', [], {'auto_now': 'True', 'blank': 'True'}),
'nat': ('django.db.models.fields.BooleanField', [], {'default': 'False'}),
'nat_dport': ('django.db.models.fields.IntegerField', [], {'null': 'True', 'blank': 'True'}),
'owner': ('django.db.models.fields.related.ForeignKey', [], {'to': "orm['auth.User']", 'null': 'True', 'blank': 'True'}),
'proto': ('django.db.models.fields.CharField', [], {'max_length': '10', 'null': 'True', 'blank': 'True'}),
'r_type': ('django.db.models.fields.CharField', [], {'max_length': '10'}),
'sport': ('django.db.models.fields.IntegerField', [], {'null': 'True', 'blank': 'True'}),
'vlan': ('django.db.models.fields.related.ForeignKey', [], {'blank': 'True', 'related_name': "'rules'", 'null': 'True', 'to': "orm['firewall.Vlan']"}),
'vlangroup': ('django.db.models.fields.related.ForeignKey', [], {'blank': 'True', 'related_name': "'rules'", 'null': 'True', 'to': "orm['firewall.VlanGroup']"})
},
'firewall.vlan': {
'Meta': {'object_name': 'Vlan'},
'comment': ('django.db.models.fields.TextField', [], {'blank': 'True'}),
'created_at': ('django.db.models.fields.DateTimeField', [], {'auto_now_add': 'True', 'blank': 'True'}),
'description': ('django.db.models.fields.TextField', [], {'blank': 'True'}),
'dhcp_pool': ('django.db.models.fields.TextField', [], {'blank': 'True'}),
'domain': ('django.db.models.fields.related.ForeignKey', [], {'to': "orm['firewall.Domain']"}),
'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}),
'interface': ('django.db.models.fields.CharField', [], {'unique': 'True', 'max_length': '20'}),
'ipv4': ('django.db.models.fields.GenericIPAddressField', [], {'unique': 'True', 'max_length': '39'}),
'ipv6': ('django.db.models.fields.GenericIPAddressField', [], {'unique': 'True', 'max_length': '39'}),
'modified_at': ('django.db.models.fields.DateTimeField', [], {'auto_now': 'True', 'blank': 'True'}),
'name': ('django.db.models.fields.CharField', [], {'unique': 'True', 'max_length': '20'}),
'net4': ('django.db.models.fields.GenericIPAddressField', [], {'unique': 'True', 'max_length': '39'}),
'net6': ('django.db.models.fields.GenericIPAddressField', [], {'unique': 'True', 'max_length': '39'}),
'owner': ('django.db.models.fields.related.ForeignKey', [], {'to': "orm['auth.User']", 'null': 'True', 'blank': 'True'}),
'prefix4': ('django.db.models.fields.IntegerField', [], {'default': '16'}),
'prefix6': ('django.db.models.fields.IntegerField', [], {'default': '80'}),
'reverse_domain': ('django.db.models.fields.TextField', [], {}),
'snat_ip': ('django.db.models.fields.GenericIPAddressField', [], {'max_length': '39', 'null': 'True', 'blank': 'True'}),
'snat_to': ('django.db.models.fields.related.ManyToManyField', [], {'symmetrical': 'False', 'to': "orm['firewall.Vlan']", 'null': 'True', 'blank': 'True'}),
'vid': ('django.db.models.fields.IntegerField', [], {'unique': 'True'})
},
'firewall.vlangroup': {
'Meta': {'object_name': 'VlanGroup'},
'created_at': ('django.db.models.fields.DateTimeField', [], {'auto_now_add': 'True', 'blank': 'True'}),
'description': ('django.db.models.fields.TextField', [], {'blank': 'True'}),
'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}),
'modified_at': ('django.db.models.fields.DateTimeField', [], {'auto_now': 'True', 'blank': 'True'}),
'name': ('django.db.models.fields.CharField', [], {'unique': 'True', 'max_length': '20'}),
'owner': ('django.db.models.fields.related.ForeignKey', [], {'to': "orm['auth.User']", 'null': 'True', 'blank': 'True'}),
'vlans': ('django.db.models.fields.related.ManyToManyField', [], {'symmetrical': 'False', 'to': "orm['firewall.Vlan']", 'null': 'True', 'blank': 'True'})
}
}
complete_apps = ['firewall']
\ No newline at end of file
......@@ -8,7 +8,6 @@ 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
from django.utils.ipv6 import is_valid_ipv6_address
from django.db.models.signals import post_save
import re
......@@ -54,27 +53,23 @@ class Rule(models.Model):
return self.desc()
def clean(self):
count = 0
for field in [self.vlan, self.vlangroup, self.host, self.hostgroup,
self.firewall]:
if field is None:
count = count + 1
if count != 4:
raise ValidationError('jaj')
fields = [self.vlan, self.vlangroup, self.host, self.hostgroup,
self.firewall]
selected_fields = [field for field in fields if field]
if len(selected_fields) > 1:
raise ValidationError(_('Only one field can be selected.'))
def desc(self):
para = u""
if(self.dport):
para = "dport=%s %s" % (self.dport, para)
if(self.sport):
para = "sport=%s %s" % (self.sport, para)
if(self.proto):
para = "proto=%s %s" % (self.proto, para)
return (u'[' + self.r_type + u'] ' +
(unicode(self.foreign_network) + u' ▸ ' + self.r_type
if self.direction == '1' else self.r_type + u' ▸ ' +
unicode(self.foreign_network)) + u' ' + para + u' ' +
self.description)
return u'[%(type)s] %(src)s ▸ %(dst)s %(para)s %(desc)s' % {
'type': self.r_type,
'src': (unicode(self.foreign_network) if self.direction == '1'
else self.r_type),
'dst': (self.r_type if self.direction == '1'
else unicode(self.foreign_network)),
'para': ((("proto=%s " % self.proto) if self.proto else '') +
(("sport=%s " % self.sport) if self.sport else '') +
(("dport=%s " % self.dport) if self.dport else '')),
'desc': self.description}
class Vlan(models.Model):
vid = models.IntegerField(unique=True)
......@@ -169,7 +164,7 @@ class Host(models.Model):
"address as your own IPv4."))
self.full_clean()
super(Host, self).save(*args, **kwargs)
if id is None:
if not id:
Record(domain=self.vlan.domain, host=self, type='A',
owner=self.owner).save()
if self.ipv6:
......@@ -179,8 +174,9 @@ class Host(models.Model):
def enable_net(self):
self.groups.add(Group.objects.get(name="netezhet"))
def add_port(self, proto, public, private):
proto = "tcp" if (proto == "tcp") else "udp"
def add_port(self, proto, public, private = 0):
proto = "tcp" if proto == "tcp" else "udp"
if self.shared_ip:
if public < 1024:
raise ValidationError(_("Only ports above 1024 can be used."))
for host in Host.objects.filter(pub_ipv4=self.pub_ipv4):
......@@ -191,22 +187,27 @@ class Host(models.Model):
proto=proto, nat=True, accept=True, r_type="host",
nat_dport=private, host=self, foreign_network=VlanGroup.
objects.get(name=settings["default_vlangroup"]))
else:
if self.rules.filter(proto=proto, dport=public):
raise ValidationError(_("Port %s %s is already in use.") %
(proto, public))
rule = Rule(direction='1', owner=self.owner, dport=public,
proto=proto, nat=False, accept=True, r_type="host",
host=self, foreign_network=VlanGroup.objects
.get(name=settings["default_vlangroup"]))
rule.full_clean()
rule.save()
def del_port(self, proto, public):
self.rules.filter(owner=self.owner, proto=proto, nat=True,
self.rules.filter(owner=self.owner, proto=proto, host=self,
dport=public).delete()
def list_ports(self):
retval = []
for rule in self.rules.filter(owner=self.owner, nat=True):
retval.append({'proto': rule.proto, 'public': rule.dport,
'private': rule.nat_dport})
return retval
def del_rules(self):
self.rules.filter(owner=self.owner).delete()
return [{'proto': rule.proto,
'public': rule.dport,
'private': rule.nat_dport} for rule in
self.rules.filter(owner=self.owner)]
def get_fqdn(self):
return self.hostname + u'.' + unicode(self.vlan.domain)
......@@ -249,79 +250,95 @@ class Record(models.Model):
def desc(self):
a = self.get_data()
if a:
return a['name'] + u' ' + a['type'] + u' ' + a['address']
return '(empty)'
return (u' '.join([a['name'], a['type'], a['address']])
if a else _('(empty)'))
def save(self, *args, **kwargs):
self.full_clean()
super(Record, self).save(*args, **kwargs)
def clean(self):
if self.name and self.name.endswith(u'.'):
raise ValidationError(_("Domain can't be terminated with a dot."))
if self.host and self.type in ['CNAME', 'A', 'AAAA']:
if self.type == 'CNAME':
if not self.name or self.address:
raise ValidationError(_("Only the 'name' field should "
"be filled with a CNAME record if a host is "
"set."))
elif self.name or self.address:
raise ValidationError(_("'name' and 'address' can't be "
"specified with an A or AAAA record if a host is "
"set."))
else:
if self.name:
self.name = self.name.rstrip(".") # remove trailing dots
if self.host:
if self.type in ['A', 'AAAA']:
if self.address:
raise ValidationError(_("Can't specify address for "
"A or AAAA records if host is set!"))
if self.name:
raise ValidationError(_("Can't specify name for "
"A or AAAA records if host is set!"))
elif self.type == 'CNAME':
if not self.name:
raise ValidationError(_("Name must be specified for "
"CNAME records if host is set!"))
if self.address:
raise ValidationError(_("Can't specify address for "
"CNAME records if host is set!"))
else: # if self.host is None
if not self.address:
raise ValidationError(_("'address' field must be filled."))
raise ValidationError(_("Address must be specified!"))
if self.type == 'A':
if not ipv4_re.match(self.address):
raise ValidationError(_("Not a valid IPv4 address."))
elif self.type in ['CNAME', 'NS', 'PTR', 'TXT']:
if not domain_re.match(self.address):
raise ValidationError(_("Not a valid domain."))
val_ipv4(self.address)
elif self.type == 'AAAA':
if not is_valid_ipv6_address(self.address):
raise ValidationError(_("Not a valid IPv6 address."))
val_ipv6(self.address)
elif self.type in ['CNAME', 'NS', 'PTR', 'TXT']:
val_domain(self.address)
elif self.type == 'MX':
mx = self.address.split(':', 1)
if not (len(mx) == 2 and mx[0].isdigit() and
domain_re.match(mx[1])):
raise ValidationError(_("Invalid address. "
"Valid format: <priority>:<hostname>"))
raise ValidationError(_("Bad address format. "
"Should be: <priority>:<hostname>"))
else:
raise ValidationError(_("Unknown record."))
raise ValidationError(_("Unknown record type."))
def get_data(self):
retval = { 'name': self.name, 'type': self.type, 'ttl': self.ttl,
'address': self.address }
if self.host and self.type in ['CNAME', 'A', 'AAAA']:
def __get_name(self):
if self.host and self.type != 'MX':
if self.type in ['A', 'AAAA']:
return self.host.get_fqdn()
elif self.type == 'CNAME':
return self.name + '.' + unicode(self.domain)
else:
return self.name
else: # if self.host is None
if self.name:
return self.name + '.' + unicode(self.domain)
else:
return unicode(self.domain)
def __get_address(self):
if self.host:
if self.type == 'A':
retval['address'] = (self.host.pub_ipv4
return (self.host.pub_ipv4
if self.host.pub_ipv4 and not self.host.shared_ip
else self.host.ipv4)
retval['name'] = self.host.get_fqdn()
elif self.type == 'AAAA':
if not self.host.ipv6:
return None
retval['address'] = self.host.ipv6
retval['name'] = self.host.get_fqdn()
return self.host.ipv6
elif self.type == 'CNAME':
retval['address'] = self.host.get_fqdn()
retval['name'] = self.name + u'.' + unicode(self.domain)
else:
if not self.name:
retval['name'] = unicode(self.domain)
else:
retval['name'] = self.name + u'.' + unicode(self.domain)
if not (retval['address'] and retval['name']):
return self.host.get_fqdn()
# otherwise:
return self.address
def get_data(self):
name = self.__get_name()
address = self.__get_address()
if self.host and self.type == 'AAAA' and not self.host.ipv6:
return None
return retval
elif not address or not name:
return None
else:
return {'name': name,
'type': self.type,
'ttl': self.ttl,
'address': address}
class Blacklist(models.Model):
CHOICES_type = (('permban', 'permanent ban'), ('tempban', 'temporary ban'), ('whitelist', 'whitelist'))
CHOICES_type = (('permban', 'permanent ban'), ('tempban', 'temporary ban'), ('whitelist', 'whitelist'), ('tempwhite', 'tempwhite'))
ipv4 = models.GenericIPAddressField(protocol='ipv4', unique=True)
host = models.ForeignKey('Host', blank=True, null=True)
reason = models.TextField(blank=True)
snort_message = models.TextField(blank=True)
type = models.CharField(max_length=10, choices=CHOICES_type, default='tempban')
......
......@@ -19,44 +19,47 @@ def reload_dhcp_task(data):
def reload_blacklist_task(data):
pass
class Periodic(PeriodicTask):
run_every = timedelta(seconds=10)
def run(self, **kwargs):
if cache.get('dns_lock'):
cache.delete("dns_lock")
reload_dns_task.delay(dns())
print "dns ujratoltese kesz"
if cache.get('dhcp_lock'):
cache.delete("dhcp_lock")
reload_dhcp_task.delay(dhcp())
print "dhcp ujratoltese kesz"
if cache.get('firewall_lock'):
cache.delete("firewall_lock")
ipv4 = Firewall().get()
ipv6 = Firewall(True).get()
reload_firewall_task.delay(ipv4, ipv6)
print "firewall ujratoltese kesz"
if cache.get('blacklist_lock'):
cache.delete("blacklist_lock")
reload_blacklist_task.delay(list(ipset()))
print "blacklist ujratoltese kesz"
class ReloadTask(Task):
def run(self, type='Host'):
sleep=False
if type in ["Host", "Records", "Domain", "Vlan"]:
lock = lambda: cache.add("dns_lock", "true", 9)
if lock():
if not sleep:
sleep = True
time.sleep(10)
reload_dns_task.delay(dns())
cache.add("dns_lock", "true", 30)
if type == "Host":
lock = lambda: cache.add("dhcp_lock", "true", 9)
if lock():
if not sleep:
sleep = True
time.sleep(10)
reload_dhcp_task.delay(dhcp())
cache.add("dhcp_lock", "true", 30)
if type in ["Host", "Rule", "Firewall"]:
lock = lambda: cache.add("firewall_lock", "true", 9)
if lock():
if not sleep:
sleep = True
time.sleep(10)
ipv4 = firewall().get()
ipv6 = firewall(True).get()
reload_firewall_task.delay(ipv4, ipv6)
cache.add("firewall_lock", "true", 30)
if type == "Blacklist":
lock = lambda: cache.add("blacklist_lock", "true", 9)
if lock():
if not sleep:
sleep = True
time.sleep(10)
reload_blacklist_task.delay(list(ipset()))
cache.add("blacklist_lock", "true", 30)
print type
......@@ -16,21 +16,19 @@ class MockGroups:
def all(self):
return self.groups
class HostAdminNoGroupTestCase(TestCase):
def runTest(self):
class HostAdminTestCase(TestCase):
def test_no_groups(self):
instance = MockInstance([])
l = HostAdmin.groups_l(instance)
l = HostAdmin.list_groups(instance)
self.assertEqual(l, "")
class HostAdminSingleGroupTestCase(TestCase):
def runTest(self):
def test_sigle_group(self):
instance = MockInstance([MockGroup("alma")])
l = HostAdmin.groups_l(instance)
l = HostAdmin.list_groups(instance)
self.assertEqual(l, "alma")
class HostAdminMultipleGroupsTestCase(TestCase):
def runTest(self):
def test_multiple_groups(self):
instance = MockInstance([MockGroup("alma"),
MockGroup("korte"), MockGroup("szilva")])
l = HostAdmin.groups_l(instance)
l = HostAdmin.list_groups(instance)
self.assertEqual(l, "alma, korte, szilva")
from django.shortcuts import render_to_response
from django.http import HttpResponse
from django.shortcuts import render_to_response
from firewall.models import *
from firewall.fw import *
from django.views.decorators.csrf import csrf_exempt
......@@ -9,23 +8,27 @@ 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 json
import sys
import datetime
from django.utils.timezone import utc
from one.tasks import SendMailTask
def reload_firewall(request):
if request.user.is_authenticated():
if request.user.is_superuser:
html = ((_("Dear %s, you've signed in as administrator!") %
request.user.username) + "<br />" +
_("Reloading in 10 seconds..."))
html = (_("Dear %s, you've signed in as administrator!<br />"
"Reloading in 10 seconds...") % request.user.username)
ReloadTask.delay()
else:
html = (_("Dear %s, you've signed in!")
% request.user.username)
html = (_("Dear %s, you've signed in!") % request.user.username)
else:
html = _("Dear anonymous, you've not signed in yet!")
return HttpResponse(html)
......@@ -41,16 +44,29 @@ def firewall_api(request):
if command == "blacklist":
obj, created = Blacklist.objects.get_or_create(ipv4=data["ip"])
if created:
obj.reason=data["reason"]
obj.snort_message=data["snort_message"]
if created:
try:
obj.host = models.Host.objects.get(ipv4=data["ip"])
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} )
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
print obj.modified_at + datetime.timedelta(minutes=5)
print datetime.datetime.utcnow().replace(tzinfo=utc)
if obj.type == 'tempwhite' and obj.modified_at + datetime.timedelta(minutes=1) < datetime.datetime.utcnow().replace(tzinfo=utc):
obj.type = 'tempban'
obj.save()
return HttpResponse(unicode(_("OK")));
return HttpResponse(unicode(_("OK")))
if not (data["vlan"] == "vm-net" or data["vlan"] == "war"):
raise Exception(_("Only vm-net and war can be used."))
data["hostname"] = re.sub(r' ','_', data["hostname"])
data["hostname"] = re.sub(r' ', '_', data["hostname"])
if command == "create":
data["owner"] = "opennebula"
......@@ -78,14 +94,13 @@ def firewall_api(request):
host = models.Host.objects.get(hostname=data["hostname"],
owner=owner)
host.del_rules()
host.delete()
else:
raise Exception(_("Unknown command."))
except (ValidationError, IntegrityError, AttributeError, Exception) as e:
return HttpResponse(_("Something went wrong!\n%s\n") % e);
return HttpResponse(_("Something went wrong!\n%s\n") % e)
except:
return HttpResponse(_("Something went wrong!\n"));
return HttpResponse(_("Something went wrong!\n"))
return HttpResponse(unicode(_("OK")));
return HttpResponse(unicode(_("OK")))
......@@ -10,4 +10,4 @@ sed -i 's/^<volume user=.*//' /etc/security/pam_mount.conf.xml
rm -rf ~cloud/{.bash_history,.ssh/id_rsa}
rm -rf ~root/{.bash_history}
rm -rf /etc/ssh/ssh_host_*
rm -rf /usr/NX/home/nx/.ssh/known_hosts
......@@ -3,6 +3,12 @@
echo "En vagyok a $0 !"
hostname "$HOSTNAME"
echo "$HOSTNAME" > /etc/hostname
if [ "$DISTRO" == "ubuntu" ]; then
echo "$HOSTNAME" > /etc/hostname
fi
if [ "$DISTRO" == "redhat" ]; then
echo -e -n "NETWORKING=yes\nHOSTNAME=$HOSTNAME\n" > /etc/sysconfig/network
fi
sed "s/\(127\.0\.1\.1\).*/\1\t$HOSTNAME/" -i /etc/hosts
......@@ -13,6 +13,7 @@ echo ok "$ipv4 $ipv6 $gw4 $gw6"
/etc/init.d/network-manager stop
ifdown eth0 || ifconfig eth0 0 down
if [ "$DISTRO" == "ubuntu" ]; then
cat > /etc/network/interfaces << EOF
auto lo
iface lo inet loopback
......@@ -30,4 +31,28 @@ EOF
ifup eth0
fi
if [ "$DISTRO" == "redhat" ]; then
cat > /etc/sysconfig/network-scripts/ifcfg-eth0 << EOF
DEVICE="eth0"
BOOTPROTO="none"
IPV6INIT="yes"
NM_CONTROLLED="no"
ONBOOT="yes"
TYPE="Ethernet"
DNS1="152.66.243.60"
PEERDNS="yes"
IPADDR="$ipv4"
NETMASK="255.255.0.0"
GATEWAY=$gw4
IPV6ADDR="$ipv6/80"
IPV6_DEFAULTGW="$gw6"
EOF
ifup eth0
fi
......@@ -5,8 +5,14 @@ echo "En vagyok a $0 !"
mkdir -p "$HOME/.ssh"
echo "$SSHPRIV" > $HOME/.ssh/id_rsa
chmod 600 "$HOME/.ssh/id_rsa"
echo "$SSHPUB" >> "$HOME/.ssh/authorized_keys"
mkdir "$HOME/sshfs"
chown "$USER:$USER" -R "$HOME"
sed -i 's/^<volume user=.*//' /etc/security/pam_mount.conf.xml
sed -i "s/^\(<\/pam_mount>.*\)/<volume user=\"$USER\" fstype=\"fuse\" path=\"sshfs#${NEPTUN}@${SERVER}:home\" mountpoint=\"~\/sshfs\" options=\"nonempty,reconnect,StrictHostKeyChecking=no\" \/>\n\1/" /etc/security/pam_mount.conf.xml
sed -i 's/^sshfs.*//' /etc/fstab
cat >> /etc/fstab <<END
sshfs#${NEPTUN}@${SERVER}:home $HOME/sshfs fuse defaults,idmap=user,reconnect,_netdev,uid=1000,gid=1000,allow_other,StrictHostKeyChecking=no,IdentityFile=$HOME/.ssh/id_rsa 0 0
END
mount "$HOME/sshfs"
......@@ -2,6 +2,7 @@
echo "En vagyok a $0 !"
wget -q -O /dev/null "$BOOTURL"
( while ! wget -T 2 -t 1 -q --no-check-certificate -O /dev/null "$BOOTURL" ; do sleep 5; done ) &
disown $!
......@@ -4,6 +4,15 @@ export BASEDIR=$(dirname $0)
export USER="cloud"
export HOME=$(awk -F: -v u=$USER '$1==u{print $6}' /etc/passwd)
if [ -f /etc/lsb-release ]; then
export DISTRO=ubuntu
fi
if [ -f /etc/redhat-release ]; then
export DISTRO=redhat
fi
echo $DISTRO
mkdir -p "$BASEDIR/mnt"
cd "$BASEDIR"
......
......@@ -16,40 +16,5 @@
"email": "",
"date_joined": "2013-01-16T12:36:01Z"
}
},
{
"pk": 9,
"model": "one.template",
"fields": {
"name": "Ubuntu 12.04 desktop",
"created_at": "2013-01-31T10:11:08Z",
"access_type": "nx",
"instance_type": 3,
"owner": 1,
"disk": 1,
"network": 2
}
},
{
"pk": 10,
"model": "one.template",
"fields": {
"name": "Windows 7",
"created_at": "2013-01-31T10:11:21Z",
"access_type": "rdp",
"instance_type": 2,
"owner": 1,
"disk": 1,
"network": 2
}
},
{
"pk": 2,
"model": "one.network",
"fields": {
"name": "VM-NET",
"nat": true,
"public": false
}
}
]
......@@ -5,15 +5,15 @@ for i in cloudstore toplist django
do
sudo stop $i || true
done
set -x
cd /opt/webadmin/cloud
./manage.py syncdb --noinput
./manage.py migrate
./manage.py loaddata miscellaneous/dump.json
./manage.py loaddata miscellaneous/devenv/dev.json
./manage.py update
./manage.py loaddata miscellaneous/devenv/dev.json
set +x
sudo apt-get install rabbitmq-server gettext
sudo rabbitmqctl delete_user guest || true
sudo rabbitmqctl add_user nyuszi teszt || true
sudo rabbitmqctl add_vhost django || true
sudo rabbitmqctl set_permissions -p django nyuszi '.*' '.*' '.*' || true
sudo cp /opt/webadmin/cloud/miscellaneous/devenv/boot_url.py /opt/
#Set up store server
rm -rf /var/www/*
......@@ -44,6 +44,18 @@ do
sudo start $i
done
set -x
cd /opt/webadmin/cloud
./manage.py syncdb --noinput
./manage.py migrate
./manage.py loaddata miscellaneous/dump.json
./manage.py loaddata miscellaneous/devenv/dev.json
./manage.py update
./manage.py loaddata miscellaneous/devenv/dev.json
set +x
cd /opt/webadmin/cloud/miscellaneous/devenv
sudo cp vimrc.local /etc/vim/vimrc.local
......@@ -52,16 +64,11 @@ sudo cp vimrc.local /etc/vim/vimrc.local
cd /opt/webadmin/cloud
./manage.py changepassword test
git config --global alias.prettylog 'log --graph --all --decorate --date-order --pretty="%C(yellow)%h%Cred%d%Creset - %C(cyan)%an %Creset: %s %Cgreen(%cr)"'
git config --global alias.prettylog 'log --graph --all --decorate --date-order --pretty="%C(yellow)%h%Cred%d%Creset - %C(cyan)%an %Creset: %s %Cgreen(%ar)"'
git config --global alias.civ 'commit --interactive --verbose'
git config --global color.ui true
git config --global core.editor vim
true
sudo apt-get install rabbitmq-server
sudo rabbitmqctl delete_user guest
sudo rabbitmqctl add_user nyuszi teszt
sudo rabbitmqctl add_vhost django
sudo rabbitmqctl set_permissions -p django nyuszi '.*' '.*' '.*'
......@@ -7,4 +7,6 @@ set et
set sw=4
set ai
set smarttab
set textwidth=76
set colorcolumn=76
......@@ -138,12 +138,12 @@
"model": "auth.user",
"fields": {
"username": "test",
"first_name": "Teszt",
"last_name": "Elek",
"first_name": "",
"last_name": "",
"is_active": true,
"is_superuser": true,
"is_staff": true,
"last_login": "2013-02-15T23:25:57Z",
"last_login": "2013-03-01T18:37:22Z",
"groups": [],
"user_permissions": [],
"email": "",
......@@ -341,6 +341,227 @@
},
{
"pk": 1,
"model": "one.userclouddetails",
"fields": {
"share_quota": 0,
"ssh_key": 1,
"disk_quota": 2048,
"instance_quota": 20,
"ssh_private_key": "-----xxx PRIVATE KEY-----",
"smb_password": "kamu",
"user": 1
}
},
{
"pk": 2,
"model": "one.userclouddetails",
"fields": {
"share_quota": 0,
"ssh_key": 2,
"disk_quota": 2048,
"instance_quota": 20,
"ssh_private_key": "-----xxx PRIVATE KEY-----",
"smb_password": "kamu",
"user": 2
}
},
{
"pk": 3,
"model": "one.userclouddetails",
"fields": {
"share_quota": 0,
"ssh_key": 3,
"disk_quota": 2048,
"instance_quota": 20,
"ssh_private_key": "-----xxx PRIVATE KEY-----",
"smb_password": "kamu",
"user": 3
}
},
{
"pk": 4,
"model": "one.userclouddetails",
"fields": {
"share_quota": 0,
"ssh_key": 4,
"disk_quota": 2048,
"instance_quota": 20,
"ssh_private_key": "-----xxx PRIVATE KEY-----",
"smb_password": "kamu",
"user": 4
}
},
{
"pk": 5,
"model": "one.userclouddetails",
"fields": {
"share_quota": 0,
"ssh_key": 5,
"disk_quota": 2048,
"instance_quota": 20,
"ssh_private_key": "-----xxx PRIVATE KEY-----",
"smb_password": "kamu",
"user": 5
}
},
{
"pk": 6,
"model": "one.userclouddetails",
"fields": {
"share_quota": 0,
"ssh_key": 6,
"disk_quota": 2048,
"instance_quota": 20,
"ssh_private_key": "-----xxx PRIVATE KEY-----",
"smb_password": "kamu",
"user": 6
}
},
{
"pk": 7,
"model": "one.userclouddetails",
"fields": {
"share_quota": 100,
"ssh_key": 7,
"disk_quota": 2048,
"instance_quota": 20,
"ssh_private_key": "-----xxx PRIVATE KEY-----",
"smb_password": "kamu",
"user": 7
}
},
{
"pk": 8,
"model": "one.userclouddetails",
"fields": {
"share_quota": 0,
"ssh_key": 8,
"disk_quota": 2048,
"instance_quota": 20,
"ssh_private_key": "-----xxx PRIVATE KEY-----",
"smb_password": "kamu",
"user": 12
}
},
{
"pk": 9,
"model": "one.userclouddetails",
"fields": {
"share_quota": 0,
"ssh_key": 9,
"disk_quota": 2048,
"instance_quota": 20,
"ssh_private_key": "-----xxx PRIVATE KEY-----",
"smb_password": "kamu",
"user": 13
}
},
{
"pk": 10,
"model": "one.userclouddetails",
"fields": {
"share_quota": 0,
"ssh_key": 10,
"disk_quota": 2048,
"instance_quota": 20,
"ssh_private_key": "-----xxx PRIVATE KEY-----",
"smb_password": "kamu",
"user": 14
}
},
{
"pk": 11,
"model": "one.userclouddetails",
"fields": {
"share_quota": 0,
"ssh_key": 11,
"disk_quota": 2048,
"instance_quota": 20,
"ssh_private_key": "-----xxx PRIVATE KEY-----",
"smb_password": "kamu",
"user": 15
}
},
{
"pk": 12,
"model": "one.userclouddetails",
"fields": {
"share_quota": 0,
"ssh_key": 12,
"disk_quota": 2048,
"instance_quota": 20,
"ssh_private_key": "-----xxx PRIVATE KEY-----",
"smb_password": "kamu",
"user": 16
}
},
{
"pk": 13,
"model": "one.userclouddetails",
"fields": {
"share_quota": 0,
"ssh_key": 13,
"disk_quota": 2048,
"instance_quota": 20,
"ssh_private_key": "-----xxx PRIVATE KEY-----",
"smb_password": "kamu",
"user": 17
}
},
{
"pk": 14,
"model": "one.userclouddetails",
"fields": {
"share_quota": 0,
"ssh_key": 14,
"disk_quota": 2048,
"instance_quota": 20,
"ssh_private_key": "-----xxx PRIVATE KEY-----",
"smb_password": "kamu",
"user": 18
}
},
{
"pk": 15,
"model": "one.userclouddetails",
"fields": {
"share_quota": 0,
"ssh_key": 15,
"disk_quota": 2048,
"instance_quota": 20,
"ssh_private_key": "-----xxx PRIVATE KEY-----",
"smb_password": "kamu",
"user": 20
}
},
{
"pk": 16,
"model": "one.userclouddetails",
"fields": {
"share_quota": 0,
"ssh_key": 16,
"disk_quota": 2048,
"instance_quota": 20,
"ssh_private_key": "-----xxx PRIVATE KEY-----",
"smb_password": "kamu",
"user": 21
}
},
{
"pk": 17,
"model": "one.userclouddetails",
"fields": {
"share_quota": 0,
"ssh_key": 17,
"disk_quota": 2048,
"instance_quota": 20,
"ssh_private_key": "-----xxx PRIVATE KEY-----",
"smb_password": "kamu",
"user": 22
}
},
{
"pk": 1,
"model": "one.sshkey",
"fields": {
"user": 1,
......@@ -556,193 +777,47 @@
}
},
{
"pk": 11,
"model": "one.share",
"fields": {
"group": 1,
"name": "Ubuntu 12s.04 desktop",
"created_at": "2013-02-11T14:35:46Z",
"instance_limit": 10,
"template": 17,
"owner": 7,
"per_user_limit": 1,
"type": "LAB",
"description": ""
}
},
{
"pk": 13,
"model": "one.share",
"fields": {
"group": 1,
"name": "Ubuntu 12s.04 desktop",
"created_at": "2013-02-12T10:05:08Z",
"instance_limit": 2,
"template": 17,
"owner": 7,
"per_user_limit": 4,
"type": "LAB",
"description": ""
}
},
{
"pk": 15,
"model": "one.share",
"fields": {
"group": 2,
"name": "Ubuntu 12s.04 desktop",
"created_at": "2013-02-12T20:36:46Z",
"instance_limit": 10,
"template": 17,
"owner": 7,
"per_user_limit": 1,
"type": "LAB",
"description": ""
}
},
{
"pk": 16,
"model": "one.share",
"fields": {
"group": 2,
"name": "Windows 7",
"created_at": "2013-02-12T20:38:33Z",
"instance_limit": 10,
"template": 10,
"owner": 7,
"per_user_limit": 1,
"type": "LAB",
"description": "Ez j\u00f3 cuccos"
}
},
{
"pk": 17,
"pk": 2,
"model": "one.share",
"fields": {
"group": 2,
"name": "Windows 7",
"created_at": "2013-02-12T20:38:36Z",
"name": "Ubuntu 12.04 Min",
"created_at": "2013-03-01T17:03:01Z",
"instance_limit": 10,
"template": 10,
"template": 11,
"owner": 7,
"per_user_limit": 1,
"per_user_limit": 10,
"type": "LAB",
"description": "Ez j\u00f3 cuccos"
}
},
{
"pk": 1,
"model": "one.disk",
"fields": {
"name": "Copy of ttylinux - kvm"
}
},
{
"pk": 2,
"model": "one.disk",
"fields": {
"name": "template-10"
}
},
{
"pk": 3,
"model": "one.disk",
"fields": {
"name": "template-11-298"
"description": "This is the basic test image for the developer environment."
}
},
{
"pk": 4,
"model": "one.disk",
"fields": {
"name": "template-12-300"
"name": "MinimalISO-Ubuntu"
}
},
{
"pk": 5,
"pk": 3,
"model": "one.disk",
"fields": {
"name": "template-13-301"
"name": "ttylinux-iperf"
}
},
{
"pk": 6,
"model": "one.disk",
"fields": {
"name": "template-14-303"
"name": "Ubuntu install"
}
},
{
"pk": 7,
"model": "one.disk",
"fields": {
"name": "template-15-308"
}
},
{
"pk": 8,
"model": "one.disk",
"fields": {
"name": "template-16-309"
}
},
{
"pk": 9,
"model": "one.disk",
"fields": {
"name": "template-17-310"
}
},
{
"pk": 10,
"model": "one.disk",
"fields": {
"name": "template-19-318"
}
},
{
"pk": 11,
"model": "one.disk",
"fields": {
"name": "template-21-321"
}
},
{
"pk": 12,
"model": "one.disk",
"fields": {
"name": "template-29-326"
}
},
{
"pk": 13,
"model": "one.disk",
"fields": {
"name": "template-31-330"
}
},
{
"pk": 14,
"model": "one.disk",
"fields": {
"name": "template-32-331"
}
},
{
"pk": 2,
"model": "one.network",
"fields": {
"name": "VM-NET",
"nat": true,
"public": false
}
},
{
"pk": 1,
"pk": 3,
"model": "one.network",
"fields": {
"name": "wifi",
"nat": true,
"name": "vm-net",
"nat": false,
"public": false
}
},
......@@ -777,522 +852,304 @@
}
},
{
"pk": 9,
"model": "one.template",
"fields": {
"name": "Ubuntu 12.04 desktop",
"created_at": "2013-01-31T10:11:08Z",
"description": "",
"system": "",
"access_type": "nx",
"instance_type": 3,
"state": "NEW",
"owner": 1,
"disk": 1,
"public": true,
"network": 2
}
},
{
"pk": 10,
"model": "one.template",
"fields": {
"name": "Windows 7",
"created_at": "2013-01-31T10:11:21Z",
"description": "Ez j\u00f3 cuccos",
"system": "Windows 7 Entersp\u00e1jzi 64 bites",
"access_type": "rdp",
"instance_type": 2,
"state": "READY",
"owner": 1,
"disk": 1,
"public": true,
"network": 2
}
},
{
"pk": 17,
"model": "one.template",
"fields": {
"name": "Ubuntu 12s.04 desktop",
"created_at": "2013-02-10T21:45:05Z",
"description": "",
"system": "",
"access_type": "nx",
"instance_type": 2,
"state": "READY",
"owner": 7,
"disk": 9,
"public": false,
"network": 2
}
},
{
"pk": 19,
"model": "one.template",
"fields": {
"name": "Ubuntu 12.04 desktop a",
"created_at": "2013-02-12T14:45:50Z",
"description": "h",
"system": "",
"access_type": "nx",
"instance_type": 2,
"state": "READY",
"owner": 7,
"disk": 10,
"public": false,
"network": 2
}
},
{
"pk": 21,
"model": "one.template",
"fields": {
"name": "Windows 7asdasd",
"created_at": "2013-02-12T20:31:13Z",
"description": "Ez j\u00f3 cuccos \u00e9s nagy l\u00f3fasz",
"system": "Windows 7 Entersp\u00e1jzi 64 bites",
"access_type": "rdp",
"instance_type": 1,
"state": "READY",
"owner": 7,
"disk": 11,
"public": false,
"network": 2
}
},
{
"pk": 29,
"pk": 11,
"model": "one.template",
"fields": {
"name": "Ubuntu 12.04 desktop 22",
"created_at": "2013-02-12T23:59:54Z",
"description": "",
"system": "",
"access_type": "nx",
"name": "Ubuntu 12.04 Min",
"created_at": "2013-03-01T16:24:14Z",
"description": "This is the basic test image for the developer environment.",
"system": "Ubuntu 12.04",
"access_type": "ssh",
"instance_type": 3,
"state": "READY",
"owner": 7,
"disk": 12,
"public": false,
"network": 2
}
},
{
"pk": 32,
"model": "one.template",
"fields": {
"name": "Windows 7asdasd 30",
"created_at": "2013-02-13T00:40:52Z",
"description": "Ez j\u00f3 cuccos \u00e9s nagy l\u00f3fasz",
"system": "Windows 7 Entersp\u00e1jzi 64 bites",
"access_type": "rdp",
"instance_type": 1,
"state": "READY",
"owner": 7,
"disk": 14,
"public": false,
"network": 2
"disk": 6,
"public": true,
"network": 3
}
},
{
"pk": 307,
"pk": 1,
"model": "one.instance",
"fields": {
"name": "test Windows 7 (50)",
"time_of_suspend": null,
"ip": "10.9.1.14",
"created_at": "2013-02-10T21:31:53Z",
"name": "test Ubuntu 12.04 Min (43)",
"time_of_suspend": "2013-03-01T21:24:43Z",
"ip": "192.168.1.11",
"created_at": "2013-03-01T16:25:31Z",
"share": null,
"waiting": false,
"firewall_host": null,
"active_since": null,
"active_since": "2013-03-01T16:24:53Z",
"state": "DONE",
"template": 10,
"template": 11,
"owner": 7,
"time_of_delete": null,
"one_id": 50,
"pw": "VqKJq3hFLV"
"time_of_delete": "2013-03-16T16:24:43Z",
"one_id": 43,
"pw": "CbD7ExQZQz"
}
},
{
"pk": 310,
"pk": 2,
"model": "one.instance",
"fields": {
"name": "test Ubuntu 12s.04 desktop (53)",
"time_of_suspend": null,
"ip": "10.9.1.15",
"created_at": "2013-02-10T21:45:05Z",
"name": "test Ubuntu 12.04 Min (44)",
"time_of_suspend": "2013-03-01T21:28:39Z",
"ip": "192.168.1.10",
"created_at": "2013-03-01T16:28:39Z",
"share": null,
"waiting": false,
"firewall_host": null,
"firewall_host": 872,
"active_since": null,
"state": "DONE",
"template": 17,
"template": 11,
"owner": 7,
"time_of_delete": null,
"one_id": 53,
"pw": "WdwrHAxtPj"
"time_of_delete": "2013-03-16T16:28:39Z",
"one_id": 44,
"pw": "b2GdusYand"
}
},
{
"pk": 312,
"pk": 5,
"model": "one.instance",
"fields": {
"name": "test Windows 7 (55)",
"time_of_suspend": null,
"ip": "10.9.1.15",
"created_at": "2013-02-11T13:06:54Z",
"name": "test Ubuntu 12.04 Min (47)",
"time_of_suspend": "2013-03-01T21:44:30Z",
"ip": "192.168.1.11",
"created_at": "2013-03-01T16:54:49Z",
"share": null,
"waiting": false,
"firewall_host": null,
"active_since": null,
"active_since": "2013-03-01T16:44:53Z",
"state": "DONE",
"template": 10,
"template": 11,
"owner": 7,
"time_of_delete": null,
"one_id": 55,
"pw": "2cDZdDjkP8"
"time_of_delete": "2013-03-16T16:44:30Z",
"one_id": 47,
"pw": "rpRaZwaQDD"
}
},
{
"pk": 314,
"pk": 6,
"model": "one.instance",
"fields": {
"name": "test Ubuntu 12s.04 desktop (57)",
"time_of_suspend": "2013-02-12T15:00:35Z",
"ip": "10.9.1.16",
"created_at": "2013-02-12T19:36:54Z",
"share": 11,
"name": "test Ubuntu 12.04 Min (48)",
"time_of_suspend": "2013-03-01T21:45:48Z",
"ip": "192.168.1.12",
"created_at": "2013-03-01T16:54:52Z",
"share": null,
"waiting": false,
"firewall_host": null,
"active_since": null,
"active_since": "2013-03-01T16:45:52Z",
"state": "DONE",
"template": 17,
"template": 11,
"owner": 7,
"time_of_delete": "2013-02-27T10:00:35Z",
"one_id": 57,
"pw": "YLNvyFBMNa"
"time_of_delete": "2013-03-16T16:45:48Z",
"one_id": 48,
"pw": "VuWps4bkuW"
}
},
{
"pk": 315,
"model": "one.instance",
"pk": 1,
"model": "school.person",
"fields": {
"name": "test Ubuntu 12s.04 desktop (58)",
"time_of_suspend": "2013-02-12T15:01:35Z",
"ip": "10.9.1.17",
"created_at": "2013-02-12T21:57:50Z",
"share": 11,
"waiting": false,
"firewall_host": null,
"active_since": null,
"state": "DONE",
"template": 17,
"owner": 7,
"time_of_delete": "2013-02-27T10:01:35Z",
"one_id": 58,
"pw": "mfQk6wxMJB"
"code": "root",
"user": null,
"language": "hu"
}
},
{
"pk": 316,
"model": "one.instance",
"pk": 2,
"model": "school.person",
"fields": {
"name": "test Ubuntu 12s.04 desktop (59)",
"time_of_suspend": "2013-02-12T15:05:22Z",
"ip": "10.9.1.18",
"created_at": "2013-02-12T22:33:18Z",
"share": 13,
"waiting": false,
"firewall_host": null,
"active_since": null,
"state": "DONE",
"template": 17,
"owner": 7,
"time_of_delete": "2013-02-27T10:05:22Z",
"one_id": 59,
"pw": "fdrrRxm33W"
"code": "bd",
"user": null,
"language": "hu"
}
},
{
"pk": 3,
"model": "school.person",
"fields": {
"code": "mate",
"user": null,
"language": "hu"
}
},
{
"pk": 4,
"model": "school.person",
"fields": {
"code": "tarokkk",
"user": null,
"language": "hu"
}
},
{
"pk": 5,
"model": "school.person",
"fields": {
"code": "opennebula",
"user": null,
"language": "hu"
}
},
{
"pk": 6,
"model": "school.person",
"fields": {
"code": "lennon",
"user": null,
"language": "hu"
}
},
{
"pk": 317,
"model": "one.instance",
"pk": 7,
"model": "school.person",
"fields": {
"name": "test Ubuntu 12s.04 desktop (60)",
"time_of_suspend": "2013-02-13T01:14:28Z",
"ip": "10.9.1.19",
"created_at": "2013-02-12T20:43:59Z",
"share": 13,
"waiting": false,
"firewall_host": null,
"active_since": null,
"state": "DONE",
"template": 17,
"owner": 7,
"time_of_delete": "2013-02-27T20:14:42Z",
"one_id": 60,
"pw": "WZ6pQatURa"
"code": "test",
"user": 7,
"language": "hu"
}
},
{
"pk": 318,
"model": "one.instance",
"pk": 8,
"model": "school.person",
"fields": {
"name": "test Ubuntu 12.04 desktop a (61)",
"time_of_suspend": "2013-02-12T19:45:50Z",
"ip": "10.9.1.20",
"created_at": "2013-02-12T23:25:17Z",
"share": null,
"waiting": false,
"firewall_host": null,
"active_since": null,
"state": "DONE",
"template": 19,
"owner": 7,
"time_of_delete": "2013-02-27T14:45:50Z",
"one_id": 61,
"pw": "zpYJBjErtQ"
"code": "JI1M92",
"user": null,
"language": "hu"
}
},
{
"pk": 320,
"model": "one.instance",
"pk": 9,
"model": "school.person",
"fields": {
"name": "test Ubuntu 12s.04 desktop (63)",
"time_of_suspend": "2013-02-13T01:30:46Z",
"ip": "10.9.1.22",
"created_at": "2013-02-12T23:36:02Z",
"share": null,
"waiting": false,
"firewall_host": null,
"active_since": null,
"state": "DONE",
"template": 17,
"owner": 7,
"time_of_delete": "2013-02-27T20:30:46Z",
"one_id": 63,
"pw": "wZRvZZXbxd"
"code": "TFDAZ6",
"user": null,
"language": "hu"
}
},
{
"pk": 321,
"model": "one.instance",
"pk": 10,
"model": "school.person",
"fields": {
"name": "test Windows 7asdasd (64)",
"time_of_suspend": "2013-02-13T01:31:13Z",
"ip": "10.9.1.23",
"created_at": "2013-02-12T23:33:09Z",
"share": null,
"waiting": false,
"firewall_host": null,
"active_since": null,
"state": "DONE",
"template": 21,
"owner": 7,
"time_of_delete": "2013-02-27T20:31:13Z",
"one_id": 64,
"pw": "6y6Mbh779P"
"code": "K7YLW5",
"user": null,
"language": "hu"
}
},
{
"pk": 324,
"model": "one.instance",
"pk": 11,
"model": "school.person",
"fields": {
"name": "test Windows 7 (67)",
"time_of_suspend": "2013-02-13T01:44:44Z",
"ip": "10.9.1.26",
"created_at": "2013-02-12T22:33:49Z",
"share": null,
"waiting": false,
"firewall_host": null,
"active_since": null,
"state": "DONE",
"template": 10,
"owner": 7,
"time_of_delete": "2013-02-27T20:44:44Z",
"one_id": 67,
"pw": "YjQxeHaNkh"
"code": "UYD1S5",
"user": null,
"language": "hu"
}
},
{
"pk": 326,
"model": "one.instance",
"pk": 12,
"model": "school.person",
"fields": {
"name": "test Ubuntu 12.04 desktop 22 (69)",
"time_of_suspend": "2013-02-13T04:59:54Z",
"ip": "10.9.1.27",
"created_at": "2013-02-12T23:59:54Z",
"share": null,
"waiting": false,
"firewall_host": null,
"active_since": null,
"state": "DONE",
"template": 29,
"owner": 7,
"time_of_delete": "2013-02-27T23:59:54Z",
"one_id": 69,
"pw": "yXuM8pSNCZ"
"code": "FFRUNU",
"user": null,
"language": "hu"
}
},
{
"pk": 328,
"model": "one.instance",
"pk": 13,
"model": "school.person",
"fields": {
"name": "test Ubuntu 12s.04 desktop (71)",
"time_of_suspend": "2013-02-13T05:14:35Z",
"ip": "10.9.1.27",
"created_at": "2013-02-13T00:15:24Z",
"share": 11,
"waiting": false,
"firewall_host": null,
"active_since": null,
"state": "DONE",
"template": 17,
"owner": 7,
"time_of_delete": "2013-02-28T00:14:35Z",
"one_id": 71,
"pw": "KmP82kfFp6"
"code": "HUT3L3",
"user": null,
"language": "hu"
}
},
{
"pk": 329,
"model": "one.instance",
"pk": 14,
"model": "school.person",
"fields": {
"name": "test Ubuntu 12.04 desktop a (72)",
"time_of_suspend": "2013-02-13T05:18:34Z",
"ip": "10.9.1.27",
"created_at": "2013-02-13T00:18:59Z",
"share": null,
"waiting": false,
"firewall_host": null,
"active_since": null,
"state": "DONE",
"template": 19,
"owner": 7,
"time_of_delete": "2013-02-28T00:18:34Z",
"one_id": 72,
"pw": "99czHqQFp6"
"code": "ORL3EA",
"user": null,
"language": "hu"
}
},
{
"pk": 331,
"model": "one.instance",
"pk": 15,
"model": "school.person",
"fields": {
"name": "test Windows 7asdasd 30 (74)",
"time_of_suspend": "2013-02-13T05:40:52Z",
"ip": "10.9.1.27",
"created_at": "2013-02-13T00:40:52Z",
"share": null,
"waiting": false,
"firewall_host": null,
"active_since": "2013-02-13T00:42:18Z",
"state": "DONE",
"template": 32,
"owner": 7,
"time_of_delete": "2013-02-28T00:40:52Z",
"one_id": 74,
"pw": "2YPTmTzHsR"
"code": "B6AFNQ",
"user": null,
"language": "hu"
}
},
{
"pk": 332,
"model": "one.instance",
"pk": 16,
"model": "school.person",
"fields": {
"name": "test Ubuntu 12s.04 desktop (75)",
"time_of_suspend": "2013-02-13T05:42:34Z",
"ip": "10.9.1.27",
"created_at": "2013-02-13T00:42:34Z",
"share": 11,
"waiting": false,
"firewall_host": null,
"active_since": null,
"state": "DONE",
"template": 17,
"owner": 7,
"time_of_delete": "2013-02-28T00:42:34Z",
"one_id": 75,
"pw": "RZfD72Jgmn"
"code": "UKWBFI",
"user": null,
"language": "hu"
}
},
{
"pk": 333,
"model": "one.instance",
"pk": 17,
"model": "school.person",
"fields": {
"name": "test Ubuntu 12s.04 desktop (76)",
"time_of_suspend": "2013-02-13T05:54:47Z",
"ip": "10.9.1.28",
"created_at": "2013-02-13T00:54:47Z",
"share": null,
"waiting": false,
"firewall_host": 843,
"active_since": null,
"state": "DONE",
"template": 17,
"owner": 7,
"time_of_delete": "2013-02-28T00:54:47Z",
"one_id": 76,
"pw": "HnYSzsMxZX"
"code": "K2JL24",
"user": null,
"language": "hu"
}
},
{
"pk": 347,
"model": "one.instance",
"pk": 1,
"model": "school.semester",
"fields": {
"name": "test Ubuntu 12s.04 desktop (79)",
"time_of_suspend": null,
"ip": "10.9.1.31",
"created_at": "2013-02-15T23:35:45Z",
"share": 11,
"waiting": false,
"firewall_host": null,
"active_since": null,
"state": "DONE",
"template": 17,
"owner": 7,
"time_of_delete": null,
"one_id": 79,
"pw": "6CaERLLwLg"
"start": "2013-02-01",
"end": "2013-06-01",
"name": "asd"
}
},
{
"pk": 372,
"model": "one.instance",
"pk": 1,
"model": "school.group",
"fields": {
"name": "test Ubuntu 12s.04 desktop (104)",
"time_of_suspend": "2013-02-19T23:34:19Z",
"ip": "10.9.1.14",
"created_at": "2013-02-19T18:34:19Z",
"share": 11,
"waiting": false,
"firewall_host": 877,
"active_since": null,
"state": "ACTIVE",
"template": 17,
"owner": 7,
"time_of_delete": "2013-03-06T18:34:19Z",
"one_id": 104,
"pw": "U4XAAEhDRT"
"course": null,
"semester": 1,
"owners": [],
"name": "asd",
"members": []
}
},
{
"pk": 374,
"model": "one.instance",
"pk": 2,
"model": "school.group",
"fields": {
"name": "test Ubuntu 12s.04 desktop (105)",
"time_of_suspend": "2013-02-19T23:43:17Z",
"ip": "10.9.1.15",
"created_at": "2013-02-19T18:43:17Z",
"share": 13,
"waiting": false,
"firewall_host": 878,
"active_since": null,
"state": "PENDING",
"template": 17,
"owner": 7,
"time_of_delete": "2013-03-06T18:43:17Z",
"one_id": 105,
"pw": "55W5neEvpx"
"course": null,
"semester": 1,
"owners": [
7
],
"name": "asd",
"members": [
1,
2,
3,
4,
5,
6,
7,
8,
9,
10,
11,
12,
13,
14,
15,
16,
17
]
}
},
{
......@@ -2371,57 +2228,7 @@
}
},
{
"pk": 1262,
"model": "firewall.rule",
"fields": {
"r_type": "host",
"direction": "1",
"vlan": null,
"description": "",
"proto": "tcp",
"firewall": null,
"created_at": "2013-02-13T00:54:47Z",
"extra": "",
"modified_at": "2013-02-13T00:54:47Z",
"owner": 7,
"accept": true,
"dport": 22284,
"host": 843,
"nat_dport": 22,
"hostgroup": null,
"nat": true,
"foreign_network": 2,
"sport": null,
"vlangroup": null
}
},
{
"pk": 1263,
"model": "firewall.rule",
"fields": {
"r_type": "host",
"direction": "1",
"vlan": null,
"description": "",
"proto": "tcp",
"firewall": null,
"created_at": "2013-02-19T18:40:00Z",
"extra": "",
"modified_at": "2013-02-19T18:40:00Z",
"owner": 7,
"accept": true,
"dport": 22270,
"host": 877,
"nat_dport": 22,
"hostgroup": null,
"nat": true,
"foreign_network": 2,
"sport": null,
"vlangroup": null
}
},
{
"pk": 1264,
"pk": 1217,
"model": "firewall.rule",
"fields": {
"r_type": "host",
......@@ -2430,16 +2237,16 @@
"description": "",
"proto": "tcp",
"firewall": null,
"created_at": "2013-02-19T18:43:17Z",
"created_at": "2013-03-01T16:28:39Z",
"extra": "",
"modified_at": "2013-02-19T18:43:17Z",
"modified_at": "2013-03-01T16:28:39Z",
"owner": 7,
"accept": true,
"dport": 22271,
"host": 878,
"nat_dport": 22,
"dport": 22,
"host": 872,
"nat_dport": null,
"hostgroup": null,
"nat": true,
"nat": false,
"foreign_network": 2,
"sport": null,
"vlangroup": null
......@@ -4703,29 +4510,6 @@
}
},
{
"pk": 843,
"model": "firewall.host",
"fields": {
"comment": "",
"vlan": 10,
"reverse": null,
"created_at": "2013-02-13T00:54:47Z",
"hostname": "id-333_user-test",
"modified_at": "2013-02-13T00:54:47Z",
"location": "",
"pub_ipv4": "152.66.243.62",
"mac": "02:00:0a:09:01:1c",
"shared_ip": true,
"ipv4": "10.9.1.28",
"groups": [
4
],
"ipv6": "2001:738:2001:4031:9:1:28:0",
"owner": 7,
"description": ""
}
},
{
"pk": 846,
"model": "firewall.host",
"fields": {
......@@ -4909,7 +4693,7 @@
"shared_ip": true,
"ipv4": "10.9.1.111",
"groups": [],
"ipv6": "21001:738:2001:4031:9:1:11:0",
"ipv6": "2001:738:2001:4031:9:1:111:0",
"owner": 7,
"description": ""
}
......@@ -4936,47 +4720,24 @@
}
},
{
"pk": 877,
"model": "firewall.host",
"fields": {
"comment": "",
"vlan": 10,
"reverse": null,
"created_at": "2013-02-19T18:34:19Z",
"hostname": "id-372_user-test",
"modified_at": "2013-02-19T18:34:19Z",
"location": "",
"pub_ipv4": "152.66.243.62",
"mac": "02:00:0a:09:01:0e",
"shared_ip": true,
"ipv4": "10.9.1.14",
"groups": [
4
],
"ipv6": "2001:738:2001:4031:9:1:14:0",
"owner": 7,
"description": ""
}
},
{
"pk": 878,
"pk": 872,
"model": "firewall.host",
"fields": {
"comment": "",
"vlan": 10,
"reverse": null,
"created_at": "2013-02-19T18:43:17Z",
"hostname": "id-374_user-test",
"modified_at": "2013-02-19T18:43:17Z",
"created_at": "2013-03-01T16:28:39Z",
"hostname": "cloud-2",
"modified_at": "2013-03-01T16:28:39Z",
"location": "",
"pub_ipv4": "152.66.243.62",
"mac": "02:00:0a:09:01:0f",
"shared_ip": true,
"ipv4": "10.9.1.15",
"pub_ipv4": null,
"mac": "02:00:c0:a8:01:0a",
"shared_ip": false,
"ipv4": "192.168.1.10",
"groups": [
4
],
"ipv6": "2001:738:2001:4031:9:1:15:0",
"ipv6": "2001:738:2001:4031:168:1:10:0",
"owner": 7,
"description": ""
}
......@@ -6357,79 +6118,15 @@
}
},
{
"pk": 175,
"model": "firewall.record",
"fields": {
"domain": 8,
"name": null,
"created_at": "2013-02-13T00:54:47Z",
"address": null,
"modified_at": "2013-02-13T00:54:47Z",
"host": 843,
"ttl": 600,
"owner": 7,
"type": "A",
"description": ""
}
},
{
"pk": 176,
"model": "firewall.record",
"fields": {
"domain": 8,
"name": null,
"created_at": "2013-02-13T00:54:47Z",
"address": null,
"modified_at": "2013-02-13T00:54:47Z",
"host": 843,
"ttl": 600,
"owner": 7,
"type": "AAAA",
"description": ""
}
},
{
"pk": 177,
"model": "firewall.record",
"fields": {
"domain": 8,
"name": null,
"created_at": "2013-02-19T18:40:00Z",
"address": null,
"modified_at": "2013-02-19T18:40:00Z",
"host": 877,
"ttl": 600,
"owner": 7,
"type": "A",
"description": ""
}
},
{
"pk": 178,
"model": "firewall.record",
"fields": {
"domain": 8,
"name": null,
"created_at": "2013-02-19T18:40:00Z",
"address": null,
"modified_at": "2013-02-19T18:40:00Z",
"host": 877,
"ttl": 600,
"owner": 7,
"type": "AAAA",
"description": ""
}
},
{
"pk": 179,
"pk": 105,
"model": "firewall.record",
"fields": {
"domain": 8,
"name": null,
"created_at": "2013-02-19T18:43:17Z",
"created_at": "2013-03-01T16:28:39Z",
"address": null,
"modified_at": "2013-02-19T18:43:17Z",
"host": 878,
"modified_at": "2013-03-01T16:28:39Z",
"host": 872,
"ttl": 600,
"owner": 7,
"type": "A",
......@@ -6437,15 +6134,15 @@
}
},
{
"pk": 180,
"pk": 106,
"model": "firewall.record",
"fields": {
"domain": 8,
"name": null,
"created_at": "2013-02-19T18:43:17Z",
"created_at": "2013-03-01T16:28:39Z",
"address": null,
"modified_at": "2013-02-19T18:43:17Z",
"host": 878,
"modified_at": "2013-03-01T16:28:39Z",
"host": 872,
"ttl": 600,
"owner": 7,
"type": "AAAA",
......@@ -6939,6 +6636,15 @@
}
},
{
"pk": 55,
"model": "south.migrationhistory",
"fields": {
"applied": "2013-02-25T18:31:52Z",
"app_name": "firewall",
"migration": "0028_auto__del_field_vlan_domain"
}
},
{
"pk": 56,
"model": "south.migrationhistory",
"fields": {
......@@ -7011,6 +6717,15 @@
}
},
{
"pk": 64,
"model": "south.migrationhistory",
"fields": {
"applied": "2013-03-01T16:20:57Z",
"app_name": "firewall",
"migration": "0031_auto__add_field_blacklist_snort_message__add_field_blacklist_type"
}
},
{
"pk": 7,
"model": "django.queue",
"fields": {
......
#!/bin/bash
/opt/webadmin/cloud/manage.py dumpdata -e admin -e one.userclouddetails -e school -e auth.permission -e contenttypes -e sessions -e djcelery --format=json --indent=2|grep -v '"password":'|sed -e 's/^.*"smb_password":.*$/"smb_password": "kamu",/' -e 's/BEGIN RSA PRIVATE.*END RSA/xxx/' >/opt/webadmin/cloud/miscellaneous/dump.json
/opt/webadmin/cloud/manage.py dumpdata -e admin -e auth.permission -e contenttypes -e sessions -e djcelery --format=json --indent=2|grep -v '"password":'|sed -e 's/^.*"smb_password":.*$/"smb_password": "kamu",/' -e 's/BEGIN RSA PRIVATE.*END RSA/xxx/' >/opt/webadmin/cloud/miscellaneous/dump.json
......@@ -6,11 +6,19 @@ import os
import sys
import gtk
import gobject
from multiprocessing import Manager, Process
import threading
import signal
import time
class RDP:
def __init__(self, uri):
gobject.threads_init()
self.scheme, self.username, self.password, self.host, self.port = uri.split(':',4)
self.manager = Manager()
self.global_vars = self.manager.Namespace()
self.global_vars.pid = 0
self.box = gtk.MessageDialog(parent=None, flags=gtk.DIALOG_MODAL, type=gtk.MESSAGE_INFO, buttons=gtk.BUTTONS_CANCEL, message_format="Connecting to RDP...")
def dialog_box(self,text):
# Window = gtk.Window()
# Window.set_size_request(250, 100)
......@@ -19,12 +27,27 @@ class RDP:
# window.set_title("Message dialogs")
md = gtk.MessageDialog(parent=None, type=gtk.MESSAGE_INFO, buttons=gtk.BUTTONS_CLOSE, message_format=text)
md.run()
print "After run"
md.destroy()
def connect(self):
#rdp:cloud:qYSv3eQJYY:152.66.243.62:23037
if self.scheme == "rdp":
self.connect_rdp()
#print self.global_vars.pid
p = threading.Thread(target=self.connect_rdp, args=[self.global_vars])
p.start()
while self.global_vars.pid == 0:
time.sleep(1)
#print "Rdesktop pid: "+str(self.global_vars.pid)
#print self.box
return_value = self.box.run()
#print "Box return value: "+str(return_value)
if return_value != -5:
#p.terminate()
if self.global_vars.pid > 0:
os.kill(self.global_vars.pid, signal.SIGKILL)
#print "Join"
p.join()
elif self.scheme == "nx":
self.connect_nx()
elif self.scheme == "sshterm":
......@@ -49,15 +72,13 @@ class RDP:
except:
self.dialog_box("Unable to connect to host: "+self.host+" at port "+self.port)
def connect_rdp(self):
def connect_rdp(self,global_vars):
rdp_command = ["rdesktop", "-khu", "-E", "-P", "-0", "-f", "-u", self.username, "-p", self.password, self.host+":"+self.port]
try:
proc = subprocess.check_call(rdp_command, stdout = subprocess.PIPE)
except subprocess.CalledProcessError as e:
if e.returncode != 1:
print e
print e.returncode
self.dialog_box("Unable to connect to host: "+self.host+" at port "+self.port)
proc = subprocess.Popen(rdp_command, stdout = subprocess.PIPE)
global_vars.pid = proc.pid
proc.wait()
self.box.response(-5)
global_vars.pid = 0
def connect_nx(self):
#Generate temproary config
......
from setuptools import setup, find_packages
setup(
name = "CloudGUI",
version = "0.1",
version = "0.2",
packages = ['cloudgui',],
scripts = ['cloud','rdp',],
)
#!/usr/bin/python
import xmltodict
import xml.dom.minidom as minidom
import sys
import json
import math
xml = sys.stdin.read()
data = minidom.parseString(xml)
node = data.documentElement
hosts = data.getElementsByTagName("HOST")
#CPU stat
cpu_usage = 0
used_cpu = 0
cpu_max = 0
#Memory stat
mem_usage = 0
used_mem = 0
mem_max = 0
#Running VMs
running_vms = 0
for host in hosts:
share = host.getElementsByTagName("HOST_SHARE")[0]
cpu_max += int(share.getElementsByTagName("MAX_CPU")[0].childNodes[0].data)
used_cpu += int(share.getElementsByTagName("USED_CPU")[0].childNodes[0].data)
cpu_usage += int(share.getElementsByTagName("CPU_USAGE")[0].childNodes[0].data)
mem_usage += int(share.getElementsByTagName("MEM_USAGE")[0].childNodes[0].data)
used_mem += int(share.getElementsByTagName("USED_MEM")[0].childNodes[0].data)
mem_max += int(share.getElementsByTagName("MAX_MEM")[0].childNodes[0].data)
running_vms += int(share.getElementsByTagName("RUNNING_VMS")[0].childNodes[0].data)
if cpu_usage < used_cpu:
alloc_cpu = 0
free_cpu = (cpu_max - used_cpu)
else:
alloc_cpu = (cpu_usage - used_cpu)
free_cpu = (cpu_max - alloc_cpu - used_cpu)
#Round memory values
mem_usage = mem_usage / 1024
used_mem = used_mem / 1024
mem_max = mem_max / 1024
if mem_max < (1024*5):
dimension = "MB"
else:
mem_usage = mem_usage / 1024
used_mem = used_mem / 1024
mem_max = mem_max / 1024
dimension = "GB"
mem_usage = round(mem_usage, 2)
used_mem = round(used_mem, 2)
mem_max = round(mem_max, 2)
if mem_usage < used_mem:
alloc_mem = 0
free_mem = (mem_max - used_mem)
else:
alloc_mem = (mem_usage - used_mem)
free_mem = (mem_max - alloc_mem - used_mem)
used_mem = used_mem
cpu_dict = {'FREE_CPU' : free_cpu, 'ALLOC_CPU' : alloc_cpu , 'USED_CPU' :
used_cpu}
mem_dict = {'FREE_MEM' : free_mem, 'ALLOC_MEM' : alloc_mem , 'USED_MEM' :
used_mem}
print json.dumps({ 'CPU' : cpu_dict, 'MEM' : mem_dict, 'VMS' : running_vms,
'DIMENSION' : dimension})
#!/bin/bash
export HOME='/var/www'
export LANG='en_US.UTF-8'
export LANGUAGE='en_US:en'
export LOGNAME='www-data'
export MAIL='/var/mail/www-data'
export PATH='/usr/local/bin:/usr/bin:/bin:/usr/local/games:/usr/games'
export PWD='/var/www'
export SHELL='/bin/sh'
export TERM='screen'
export USER='www-data'
#export ONE_LOCATION='/var/lib/opennebula'
export PATH="$PATH:$ONE_LOCATION/bin"
sudo -u oneadmin -i onehost list -x | /opt/webadmin/cloud/miscellaneous/stat/stat_dom.py
<HOST_POOL>
<HOST>
<ID>2</ID>
<NAME>mega6</NAME>
<STATE>2</STATE>
<IM_MAD>im_kvm</IM_MAD>
<VM_MAD>vmm_kvm</VM_MAD>
<VN_MAD>ovswitch</VN_MAD>
<LAST_MON_TIME>1362046632</LAST_MON_TIME>
<CLUSTER_ID>100</CLUSTER_ID>
<CLUSTER>mega</CLUSTER>
<HOST_SHARE>
<DISK_USAGE>0</DISK_USAGE>
<MEM_USAGE>12582912</MEM_USAGE>
<CPU_USAGE>470</CPU_USAGE>
<MAX_DISK>0</MAX_DISK>
<MAX_MEM>32937584</MAX_MEM>
<MAX_CPU>1600</MAX_CPU>
<FREE_DISK>0</FREE_DISK>
<FREE_MEM>22752516</FREE_MEM>
<FREE_CPU>1580</FREE_CPU>
<USED_DISK>0</USED_DISK>
<USED_MEM>10185068</USED_MEM>
<USED_CPU>19</USED_CPU>
<RUNNING_VMS>9</RUNNING_VMS>
</HOST_SHARE>
<VMS>
<ID>421</ID>
<ID>532</ID>
<ID>549</ID>
<ID>678</ID>
<ID>714</ID>
<ID>1243</ID>
<ID>1251</ID>
<ID>1260</ID>
<ID>1268</ID>
</VMS>
<TEMPLATE>
<ARCH><![CDATA[x86_64]]></ARCH>
<CPUSPEED><![CDATA[2266]]></CPUSPEED>
<ERROR>
<MESSAGE><![CDATA[Error monitoring host 2 : MONITOR FAILURE 2 -
]]></MESSAGE>
<TIMESTAMP><![CDATA[Fri Feb 8 22:17:17 2013]]></TIMESTAMP>
</ERROR>
<FREECPU><![CDATA[1580.8]]></FREECPU>
<FREEMEMORY><![CDATA[22752516]]></FREEMEMORY>
<HOSTNAME><![CDATA[mega6]]></HOSTNAME>
<HYPERVISOR><![CDATA[kvm]]></HYPERVISOR>
<MODELNAME><![CDATA[Intel(R) Xeon(R) CPU E5520 @ 2.27GHz]]></MODELNAME>
<NETRX><![CDATA[215302575491]]></NETRX>
<NETTX><![CDATA[1574216791392]]></NETTX>
<TOTALCPU><![CDATA[1600]]></TOTALCPU>
<TOTALMEMORY><![CDATA[32937584]]></TOTALMEMORY>
<USEDCPU><![CDATA[19.2]]></USEDCPU>
<USEDMEMORY><![CDATA[10185068]]></USEDMEMORY>
</TEMPLATE>
</HOST>
<HOST>
<ID>3</ID>
<NAME>blade1</NAME>
<STATE>4</STATE>
<IM_MAD>im_kvm</IM_MAD>
<VM_MAD>vmm_kvm</VM_MAD>
<VN_MAD>ovswitch</VN_MAD>
<LAST_MON_TIME>1358424142</LAST_MON_TIME>
<CLUSTER_ID>101</CLUSTER_ID>
<CLUSTER>blade</CLUSTER>
<HOST_SHARE>
<DISK_USAGE>0</DISK_USAGE>
<MEM_USAGE>0</MEM_USAGE>
<CPU_USAGE>0</CPU_USAGE>
<MAX_DISK>0</MAX_DISK>
<MAX_MEM>16433792</MAX_MEM>
<MAX_CPU>800</MAX_CPU>
<FREE_DISK>0</FREE_DISK>
<FREE_MEM>16040424</FREE_MEM>
<FREE_CPU>800</FREE_CPU>
<USED_DISK>0</USED_DISK>
<USED_MEM>393368</USED_MEM>
<USED_CPU>0</USED_CPU>
<RUNNING_VMS>0</RUNNING_VMS>
</HOST_SHARE>
<VMS/>
<TEMPLATE>
<ARCH><![CDATA[x86_64]]></ARCH>
<CPUSPEED><![CDATA[2333]]></CPUSPEED>
<ERROR>
<MESSAGE><![CDATA[Error monitoring host 3 : MONITOR FAILURE 3 -
]]></MESSAGE>
<TIMESTAMP><![CDATA[Fri Dec 28 10:28:37 2012]]></TIMESTAMP>
</ERROR>
<FREECPU><![CDATA[800.0]]></FREECPU>
<FREEMEMORY><![CDATA[16040424]]></FREEMEMORY>
<HOSTNAME><![CDATA[blade1]]></HOSTNAME>
<HYPERVISOR><![CDATA[kvm]]></HYPERVISOR>
<MODELNAME><![CDATA[Intel(R) Xeon(R) CPU E5345 @ 2.33GHz]]></MODELNAME>
<NETRX><![CDATA[2032199762]]></NETRX>
<NETTX><![CDATA[519158530]]></NETTX>
<TOTALCPU><![CDATA[800]]></TOTALCPU>
<TOTALMEMORY><![CDATA[16433792]]></TOTALMEMORY>
<USEDCPU><![CDATA[0.0]]></USEDCPU>
<USEDMEMORY><![CDATA[393368]]></USEDMEMORY>
</TEMPLATE>
</HOST>
<HOST>
<ID>9</ID>
<NAME>blade2</NAME>
<STATE>4</STATE>
<IM_MAD>im_kvm</IM_MAD>
<VM_MAD>vmm_kvm</VM_MAD>
<VN_MAD>ovswitch</VN_MAD>
<LAST_MON_TIME>1358424142</LAST_MON_TIME>
<CLUSTER_ID>101</CLUSTER_ID>
<CLUSTER>blade</CLUSTER>
<HOST_SHARE>
<DISK_USAGE>0</DISK_USAGE>
<MEM_USAGE>0</MEM_USAGE>
<CPU_USAGE>0</CPU_USAGE>
<MAX_DISK>0</MAX_DISK>
<MAX_MEM>10240668</MAX_MEM>
<MAX_CPU>200</MAX_CPU>
<FREE_DISK>0</FREE_DISK>
<FREE_MEM>9983120</FREE_MEM>
<FREE_CPU>200</FREE_CPU>
<USED_DISK>0</USED_DISK>
<USED_MEM>257548</USED_MEM>
<USED_CPU>0</USED_CPU>
<RUNNING_VMS>0</RUNNING_VMS>
</HOST_SHARE>
<VMS/>
<TEMPLATE>
<ARCH><![CDATA[x86_64]]></ARCH>
<CPUSPEED><![CDATA[3333]]></CPUSPEED>
<ERROR>
<MESSAGE><![CDATA[Error monitoring host 9 : MONITOR FAILURE 9 -
]]></MESSAGE>
<TIMESTAMP><![CDATA[Fri Dec 28 10:28:37 2012]]></TIMESTAMP>
</ERROR>
<FREECPU><![CDATA[200.0]]></FREECPU>
<FREEMEMORY><![CDATA[9983120]]></FREEMEMORY>
<HOSTNAME><![CDATA[blade2]]></HOSTNAME>
<HYPERVISOR><![CDATA[kvm]]></HYPERVISOR>
<MODELNAME><![CDATA[Intel(R) Xeon(R) CPU X5260 @ 3.33GHz]]></MODELNAME>
<NETRX><![CDATA[2252084768]]></NETRX>
<NETTX><![CDATA[10595986496]]></NETTX>
<TOTALCPU><![CDATA[200]]></TOTALCPU>
<TOTALMEMORY><![CDATA[10240668]]></TOTALMEMORY>
<USEDCPU><![CDATA[0.0]]></USEDCPU>
<USEDMEMORY><![CDATA[257548]]></USEDMEMORY>
</TEMPLATE>
</HOST>
<HOST>
<ID>10</ID>
<NAME>blade3</NAME>
<STATE>4</STATE>
<IM_MAD>im_kvm</IM_MAD>
<VM_MAD>vmm_kvm</VM_MAD>
<VN_MAD>ovswitch</VN_MAD>
<LAST_MON_TIME>1358424142</LAST_MON_TIME>
<CLUSTER_ID>101</CLUSTER_ID>
<CLUSTER>blade</CLUSTER>
<HOST_SHARE>
<DISK_USAGE>0</DISK_USAGE>
<MEM_USAGE>0</MEM_USAGE>
<CPU_USAGE>0</CPU_USAGE>
<MAX_DISK>0</MAX_DISK>
<MAX_MEM>16433792</MAX_MEM>
<MAX_CPU>800</MAX_CPU>
<FREE_DISK>0</FREE_DISK>
<FREE_MEM>12401604</FREE_MEM>
<FREE_CPU>796</FREE_CPU>
<USED_DISK>0</USED_DISK>
<USED_MEM>4032188</USED_MEM>
<USED_CPU>4</USED_CPU>
<RUNNING_VMS>0</RUNNING_VMS>
</HOST_SHARE>
<VMS/>
<TEMPLATE>
<ARCH><![CDATA[x86_64]]></ARCH>
<CPUSPEED><![CDATA[2333]]></CPUSPEED>
<ERROR>
<MESSAGE><![CDATA[Error monitoring host 10 : MONITOR FAILURE 10 -
]]></MESSAGE>
<TIMESTAMP><![CDATA[Fri Dec 28 22:10:28 2012]]></TIMESTAMP>
</ERROR>
<FREECPU><![CDATA[796.0]]></FREECPU>
<FREEMEMORY><![CDATA[12401604]]></FREEMEMORY>
<HOSTNAME><![CDATA[blade3]]></HOSTNAME>
<HYPERVISOR><![CDATA[kvm]]></HYPERVISOR>
<MODELNAME><![CDATA[Intel(R) Xeon(R) CPU E5345 @ 2.33GHz]]></MODELNAME>
<NETRX><![CDATA[95424749266]]></NETRX>
<NETTX><![CDATA[284788515663]]></NETTX>
<TOTALCPU><![CDATA[800]]></TOTALCPU>
<TOTALMEMORY><![CDATA[16433792]]></TOTALMEMORY>
<USEDCPU><![CDATA[4.0]]></USEDCPU>
<USEDMEMORY><![CDATA[4032188]]></USEDMEMORY>
</TEMPLATE>
</HOST>
<HOST>
<ID>11</ID>
<NAME>mega5</NAME>
<STATE>2</STATE>
<IM_MAD>im_kvm</IM_MAD>
<VM_MAD>vmm_kvm</VM_MAD>
<VN_MAD>ovswitch</VN_MAD>
<LAST_MON_TIME>1362046208</LAST_MON_TIME>
<CLUSTER_ID>100</CLUSTER_ID>
<CLUSTER>mega</CLUSTER>
<HOST_SHARE>
<DISK_USAGE>0</DISK_USAGE>
<MEM_USAGE>17825792</MEM_USAGE>
<CPU_USAGE>950</CPU_USAGE>
<MAX_DISK>0</MAX_DISK>
<MAX_MEM>32937648</MAX_MEM>
<MAX_CPU>1600</MAX_CPU>
<FREE_DISK>0</FREE_DISK>
<FREE_MEM>17099428</FREE_MEM>
<FREE_CPU>1392</FREE_CPU>
<USED_DISK>0</USED_DISK>
<USED_MEM>15838220</USED_MEM>
<USED_CPU>208</USED_CPU>
<RUNNING_VMS>9</RUNNING_VMS>
</HOST_SHARE>
<VMS>
<ID>432</ID>
<ID>540</ID>
<ID>541</ID>
<ID>667</ID>
<ID>690</ID>
<ID>760</ID>
<ID>799</ID>
<ID>1227</ID>
<ID>1263</ID>
</VMS>
<TEMPLATE>
<ARCH><![CDATA[x86_64]]></ARCH>
<CPUSPEED><![CDATA[2266]]></CPUSPEED>
<ERROR>
<MESSAGE><![CDATA[Error monitoring host 11 : MONITOR FAILURE 11 -
]]></MESSAGE>
<TIMESTAMP><![CDATA[Fri Feb 8 22:13:44 2013]]></TIMESTAMP>
</ERROR>
<FREECPU><![CDATA[1392.0]]></FREECPU>
<FREEMEMORY><![CDATA[17099428]]></FREEMEMORY>
<HOSTNAME><![CDATA[mega5]]></HOSTNAME>
<HYPERVISOR><![CDATA[kvm]]></HYPERVISOR>
<MODELNAME><![CDATA[Intel(R) Xeon(R) CPU E5520 @ 2.27GHz]]></MODELNAME>
<NETRX><![CDATA[63650381314]]></NETRX>
<NETTX><![CDATA[33549680144]]></NETTX>
<TOTALCPU><![CDATA[1600]]></TOTALCPU>
<TOTALMEMORY><![CDATA[32937648]]></TOTALMEMORY>
<USEDCPU><![CDATA[208.0]]></USEDCPU>
<USEDMEMORY><![CDATA[15838220]]></USEDMEMORY>
</TEMPLATE>
</HOST>
<HOST>
<ID>12</ID>
<NAME>mega4</NAME>
<STATE>2</STATE>
<IM_MAD>im_kvm</IM_MAD>
<VM_MAD>vmm_kvm</VM_MAD>
<VN_MAD>ovswitch</VN_MAD>
<LAST_MON_TIME>1362046491</LAST_MON_TIME>
<CLUSTER_ID>100</CLUSTER_ID>
<CLUSTER>mega</CLUSTER>
<HOST_SHARE>
<DISK_USAGE>0</DISK_USAGE>
<MEM_USAGE>15728640</MEM_USAGE>
<CPU_USAGE>660</CPU_USAGE>
<MAX_DISK>0</MAX_DISK>
<MAX_MEM>49454996</MAX_MEM>
<MAX_CPU>2400</MAX_CPU>
<FREE_DISK>0</FREE_DISK>
<FREE_MEM>38047512</FREE_MEM>
<FREE_CPU>2395</FREE_CPU>
<USED_DISK>0</USED_DISK>
<USED_MEM>11407484</USED_MEM>
<USED_CPU>4</USED_CPU>
<RUNNING_VMS>10</RUNNING_VMS>
</HOST_SHARE>
<VMS>
<ID>460</ID>
<ID>538</ID>
<ID>539</ID>
<ID>543</ID>
<ID>607</ID>
<ID>877</ID>
<ID>1200</ID>
<ID>1255</ID>
<ID>1262</ID>
<ID>1269</ID>
</VMS>
<TEMPLATE>
<ARCH><![CDATA[x86_64]]></ARCH>
<CPUSPEED><![CDATA[1600]]></CPUSPEED>
<ERROR>
<MESSAGE><![CDATA[Error monitoring host 12 : MONITOR FAILURE 12 -
]]></MESSAGE>
<TIMESTAMP><![CDATA[Fri Feb 8 22:17:17 2013]]></TIMESTAMP>
</ERROR>
<FREECPU><![CDATA[2395.2]]></FREECPU>
<FREEMEMORY><![CDATA[38047512]]></FREEMEMORY>
<HOSTNAME><![CDATA[mega4]]></HOSTNAME>
<HYPERVISOR><![CDATA[kvm]]></HYPERVISOR>
<MODELNAME><![CDATA[Intel(R) Xeon(R) CPU X5675 @ 3.07GHz]]></MODELNAME>
<NETRX><![CDATA[154783474539]]></NETRX>
<NETTX><![CDATA[112244748012]]></NETTX>
<TOTALCPU><![CDATA[2400]]></TOTALCPU>
<TOTALMEMORY><![CDATA[49454996]]></TOTALMEMORY>
<USEDCPU><![CDATA[4.80000000000018]]></USEDCPU>
<USEDMEMORY><![CDATA[11407484]]></USEDMEMORY>
</TEMPLATE>
</HOST>
<HOST>
<ID>13</ID>
<NAME>mega3</NAME>
<STATE>2</STATE>
<IM_MAD>im_kvm</IM_MAD>
<VM_MAD>vmm_kvm</VM_MAD>
<VN_MAD>ovswitch</VN_MAD>
<LAST_MON_TIME>1362046405</LAST_MON_TIME>
<CLUSTER_ID>100</CLUSTER_ID>
<CLUSTER>mega</CLUSTER>
<HOST_SHARE>
<DISK_USAGE>0</DISK_USAGE>
<MEM_USAGE>28835840</MEM_USAGE>
<CPU_USAGE>890</CPU_USAGE>
<MAX_DISK>0</MAX_DISK>
<MAX_MEM>49454996</MAX_MEM>
<MAX_CPU>2400</MAX_CPU>
<FREE_DISK>0</FREE_DISK>
<FREE_MEM>27997516</FREE_MEM>
<FREE_CPU>2395</FREE_CPU>
<USED_DISK>0</USED_DISK>
<USED_MEM>21457480</USED_MEM>
<USED_CPU>4</USED_CPU>
<RUNNING_VMS>10</RUNNING_VMS>
</HOST_SHARE>
<VMS>
<ID>403</ID>
<ID>412</ID>
<ID>440</ID>
<ID>458</ID>
<ID>459</ID>
<ID>550</ID>
<ID>591</ID>
<ID>609</ID>
<ID>759</ID>
<ID>908</ID>
</VMS>
<TEMPLATE>
<ARCH><![CDATA[x86_64]]></ARCH>
<CPUSPEED><![CDATA[1600]]></CPUSPEED>
<ERROR>
<MESSAGE><![CDATA[Error monitoring host 13 : MONITOR FAILURE 13 -
]]></MESSAGE>
<TIMESTAMP><![CDATA[Fri Feb 8 22:15:24 2013]]></TIMESTAMP>
</ERROR>
<FREECPU><![CDATA[2395.2]]></FREECPU>
<FREEMEMORY><![CDATA[27997516]]></FREEMEMORY>
<HOSTNAME><![CDATA[mega3]]></HOSTNAME>
<HYPERVISOR><![CDATA[kvm]]></HYPERVISOR>
<MODELNAME><![CDATA[Intel(R) Xeon(R) CPU X5675 @ 3.07GHz]]></MODELNAME>
<NETRX><![CDATA[179556365753]]></NETRX>
<NETTX><![CDATA[84194722741]]></NETTX>
<TOTALCPU><![CDATA[2400]]></TOTALCPU>
<TOTALMEMORY><![CDATA[49454996]]></TOTALMEMORY>
<USEDCPU><![CDATA[4.80000000000018]]></USEDCPU>
<USEDMEMORY><![CDATA[21457480]]></USEDMEMORY>
</TEMPLATE>
</HOST>
<HOST>
<ID>15</ID>
<NAME>mega1</NAME>
<STATE>2</STATE>
<IM_MAD>im_kvm</IM_MAD>
<VM_MAD>vmm_kvm</VM_MAD>
<VN_MAD>ovswitch</VN_MAD>
<LAST_MON_TIME>1362046705</LAST_MON_TIME>
<CLUSTER_ID>100</CLUSTER_ID>
<CLUSTER>mega</CLUSTER>
<HOST_SHARE>
<DISK_USAGE>0</DISK_USAGE>
<MEM_USAGE>36700160</MEM_USAGE>
<CPU_USAGE>1085</CPU_USAGE>
<MAX_DISK>0</MAX_DISK>
<MAX_MEM>49520964</MAX_MEM>
<MAX_CPU>2400</MAX_CPU>
<FREE_DISK>0</FREE_DISK>
<FREE_MEM>18859800</FREE_MEM>
<FREE_CPU>2371</FREE_CPU>
<USED_DISK>0</USED_DISK>
<USED_MEM>30661164</USED_MEM>
<USED_CPU>28</USED_CPU>
<RUNNING_VMS>12</RUNNING_VMS>
</HOST_SHARE>
<VMS>
<ID>408</ID>
<ID>534</ID>
<ID>535</ID>
<ID>536</ID>
<ID>537</ID>
<ID>542</ID>
<ID>626</ID>
<ID>685</ID>
<ID>696</ID>
<ID>708</ID>
<ID>880</ID>
<ID>1201</ID>
</VMS>
<TEMPLATE>
<ARCH><![CDATA[x86_64]]></ARCH>
<CPUSPEED><![CDATA[1600]]></CPUSPEED>
<ERROR>
<MESSAGE><![CDATA[Error monitoring host 15 : MONITOR FAILURE 15 -
]]></MESSAGE>
<TIMESTAMP><![CDATA[Fri Feb 8 22:20:20 2013]]></TIMESTAMP>
</ERROR>
<FREECPU><![CDATA[2371.2]]></FREECPU>
<FREEMEMORY><![CDATA[18859800]]></FREEMEMORY>
<HOSTNAME><![CDATA[mega1]]></HOSTNAME>
<HYPERVISOR><![CDATA[kvm]]></HYPERVISOR>
<MODELNAME><![CDATA[Intel(R) Xeon(R) CPU X5670 @ 2.93GHz]]></MODELNAME>
<NETRX><![CDATA[46593679744]]></NETRX>
<NETTX><![CDATA[36440944329]]></NETTX>
<TOTALCPU><![CDATA[2400]]></TOTALCPU>
<TOTALMEMORY><![CDATA[49520964]]></TOTALMEMORY>
<USEDCPU><![CDATA[28.8000000000002]]></USEDCPU>
<USEDMEMORY><![CDATA[30661164]]></USEDMEMORY>
</TEMPLATE>
</HOST>
<HOST>
<ID>16</ID>
<NAME>mega2</NAME>
<STATE>2</STATE>
<IM_MAD>im_kvm</IM_MAD>
<VM_MAD>vmm_kvm</VM_MAD>
<VN_MAD>ovswitch</VN_MAD>
<LAST_MON_TIME>1362046476</LAST_MON_TIME>
<CLUSTER_ID>100</CLUSTER_ID>
<CLUSTER>mega</CLUSTER>
<HOST_SHARE>
<DISK_USAGE>0</DISK_USAGE>
<MEM_USAGE>16777216</MEM_USAGE>
<CPU_USAGE>550</CPU_USAGE>
<MAX_DISK>0</MAX_DISK>
<MAX_MEM>49455072</MAX_MEM>
<MAX_CPU>2400</MAX_CPU>
<FREE_DISK>0</FREE_DISK>
<FREE_MEM>39782788</FREE_MEM>
<FREE_CPU>2376</FREE_CPU>
<USED_DISK>0</USED_DISK>
<USED_MEM>9672284</USED_MEM>
<USED_CPU>24</USED_CPU>
<RUNNING_VMS>9</RUNNING_VMS>
</HOST_SHARE>
<VMS>
<ID>1189</ID>
<ID>1195</ID>
<ID>1198</ID>
<ID>1229</ID>
<ID>1244</ID>
<ID>1256</ID>
<ID>1257</ID>
<ID>1259</ID>
<ID>1261</ID>
</VMS>
<TEMPLATE>
<ARCH><![CDATA[x86_64]]></ARCH>
<CPUSPEED><![CDATA[1600]]></CPUSPEED>
<ERROR>
<MESSAGE><![CDATA[Error monitoring host 16 : MONITOR FAILURE 16 -
]]></MESSAGE>
<TIMESTAMP><![CDATA[Fri Feb 8 22:15:24 2013]]></TIMESTAMP>
</ERROR>
<FREECPU><![CDATA[2376.0]]></FREECPU>
<FREEMEMORY><![CDATA[39782788]]></FREEMEMORY>
<HOSTNAME><![CDATA[mega2]]></HOSTNAME>
<HYPERVISOR><![CDATA[kvm]]></HYPERVISOR>
<MODELNAME><![CDATA[Intel(R) Xeon(R) CPU X5670 @ 2.93GHz]]></MODELNAME>
<NETRX><![CDATA[12341402713]]></NETRX>
<NETTX><![CDATA[4465978862]]></NETTX>
<TOTALCPU><![CDATA[2400]]></TOTALCPU>
<TOTALMEMORY><![CDATA[49455072]]></TOTALMEMORY>
<USEDCPU><![CDATA[24.0]]></USEDCPU>
<USEDMEMORY><![CDATA[9672284]]></USEDMEMORY>
</TEMPLATE>
</HOST>
</HOST_POOL>
......@@ -8,6 +8,7 @@ import uuid
import subprocess
import ConfigParser
from pwd import getpwnam
import multiprocessing
# Get configuration file
config = ConfigParser.ConfigParser()
......@@ -100,23 +101,13 @@ def cmd_download(request, neptun, home_path):
if not dl_path.startswith(home_path):
abort(400, 'Invalid download path.')
dl_hash = str(uuid.uuid4())
if( os.path.isfile(dl_path) ):
os.symlink(dl_path, ROOT_WWW_FOLDER+'/'+dl_hash)
# Debug
# redirect('http://store.cloud.ik.bme.hu:8080/dl/'+dl_hash)
dl_pub = os.path.join(ROOT_WWW_FOLDER, dl_hash)
if os.path.isfile(dl_path):
os.symlink(dl_path, dl_pub)
return json.dumps({'LINK' : SITE_URL+'/dl/'+dl_hash})
else:
try:
os.makedirs(TEMP_DIR+'/'+neptun, 0700)
except:
pass
folder_name = os.path.basename(dl_path)
temp_path = TEMP_DIR+'/'+neptun+'/'+folder_name+'.zip'
with open(os.devnull, "w") as fnull:
# zip -rqDj vmi.zip /home/tarokkk/vpn-ik
result = subprocess.call(['/usr/bin/zip', '-rqDj', temp_path, dl_path], stdout = fnull, stderr = fnull)
os.symlink(temp_path, ROOT_WWW_FOLDER+'/'+dl_hash)
return json.dumps({'LINK' : SITE_URL+'/dl/'+dl_hash})
shutil.make_archive(dl_pub, 'zip', dl_path)
return json.dumps({'LINK' : SITE_URL+'/dl/'+dl_hash+'.zip'})
COMMANDS['DOWNLOAD'] = cmd_download
# UPLOAD
......@@ -127,7 +118,10 @@ def cmd_upload(request, neptun, home_path):
abort(400, 'Invalid upload path.')
if os.path.exists(up_path) == True and os.path.isdir(up_path):
up_hash = str(uuid.uuid4())
os.symlink(up_path, ROOT_WWW_FOLDER+'/'+up_hash)
link = ROOT_WWW_FOLDER + '/' + up_hash
os.symlink(up_path, link)
passwd = getpwnam(neptun)
os.lchown(link, passwd.pw_uid, passwd.pw_gid)
return json.dumps({ 'LINK' : SITE_URL+'/ul/'+up_hash})
else:
abort(400, 'Upload directory not exists!')
......@@ -285,40 +279,48 @@ def upload_allow(hash_num):
response.set_header('Access-Control-Allow-Headers', 'Content-Type, Content-Range, Content-Disposition, Content-Description')
return 'ok'
def _upload_save(uid, gid, input, path):
os.setegid(gid)
os.seteuid(uid)
try:
with open(path, 'wb', 0600) as output:
while True:
chunk = input.read(256*1024)
if not chunk:
break
output.write(chunk)
finally:
input.close()
@route('/ul/<hash_num>', method='POST')
def upload(hash_num):
if not os.path.exists(ROOT_WWW_FOLDER+'/'+hash_num):
link = ROOT_WWW_FOLDER+'/'+hash_num
if not os.path.exists(link):
abort (404, 'Token not found!')
try:
file_data = request.files.data
file_name = file_data.filename
except:
if os.path.exists(ROOT_WWW_FOLDER+'/'+hash_num):
os.remove(ROOT_WWW_FOLDER+'/'+hash_num)
if os.path.exists(link):
os.remove(link)
abort(400, 'No file was specified!')
up_path = os.path.realpath(ROOT_WWW_FOLDER+'/'+hash_num+'/'+file_name)
up_path = os.path.realpath(link + '/' + file_name)
if os.path.exists(up_path):
abort(400, 'File already exists')
# Check if upload path valid
if not up_path.startswith('/home'):
abort(400, 'Invalid path.')
os.remove(ROOT_WWW_FOLDER+'/'+hash_num)
# Get the real upload path
# Delete the hash link
# Get the username from path for proper ownership
username=up_path.split('/', 3)[2]
# os.setegid(getpwnam(username).pw_gid)
# os.seteuid(getpwnam(username).pw_uid)
# TODO setuid subcommand
# Check if file exist (root can overwrite anything not safe)
with open(up_path , 'wb') as f:
datalength = 0
for chunk in fbuffer(file_data.file, chunk_size=1048576):
f.write(chunk)
datalength += len(chunk)
os.chown(up_path, getpwnam(username).pw_uid, getpwnam(username).pw_gid)
os.chmod(up_path, 0644)
linkstat = os.stat(link)
os.remove(link)
p = multiprocessing.Process(target=_upload_save,
args=(linkstat.st_uid, linkstat.st_gid, file_data.file, up_path, ))
try:
p.start()
p.join()
finally:
p.terminate()
if p.exitcode:
abort(400, 'Write failed.')
try:
redirect_address = request.headers.get('Referer')
except:
......@@ -327,19 +329,11 @@ def upload(hash_num):
response.set_header('Access-Control-Allow-Methods', 'POST, GET, OPTIONS')
response.set_header('Access-Control-Allow-Headers', 'Content-Type, Content-Range, Content-Disposition, Content-Description')
redirect(redirect_address)
#return 'Upload finished: '+file_name+' - '+str(datalength)+' Byte'
# Return hard quota from quota
def hard_quota(quota):
return str(int(int(quota)*1.25))
# Define filebuffer for big uploads
def fbuffer(f, chunk_size=4096):
while True:
chunk = f.read(chunk_size)
if not chunk: break
yield chunk
# Update users .ssh/authorized_keys
def updateSSHAuthorizedKeys(username, key_list):
user_uid=getpwnam(username).pw_uid
......
......@@ -23,17 +23,30 @@ class DetailsInline(contrib.admin.StackedInline):
can_delete = False
class MyUserAdmin(contrib.auth.admin.UserAdmin):
list_display = ('username', 'full_name', 'email', 'date_joined', 'instance_count')
list_display = ('username', 'full_name', 'email', 'date_joined', 'instance_count', 'course_groups')
list_filter = ('is_superuser', 'is_active', 'groups', 'person__course_groups', )
try:
inlines = inlines + (PersonInline, SshKeyInline, DetailsInline)
except NameError:
inlines = (PersonInline, SshKeyInline, DetailsInline)
def instance_count(self, obj):
return obj.instance_set.count()
return _("%(sum)d (%(active)d active)") % { 'sum': obj.instance_set.count(),
'active' :obj.instance_set.filter(state='ACTIVE').count(), }
def course_groups(self, obj):
try:
return ", ".join(obj.person_set.all()[0].course_groups.all())
except:
return None
def full_name(self, obj):
return u"%s %s" % (obj.last_name, obj.first_name)
full_name.admin_order_field = 'last_name'
ordering = ["-date_joined"]
contrib.admin.site.unregister(contrib.auth.models.User)
......
# -*- coding: utf-8 -*-
from django_extensions.management.jobs import HourlyJob
import datetime
from django.utils.timezone import utc
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.utils import translation
class Job(HourlyJob):
help = "Suspend/delete expired Instances."
def calc(self, orig, days=0, hours=0):
return (orig + datetime.timedelta(days=days, hours=hours)).replace(minute=0, second=0, microsecond=0)
def execute(self):
# executing empty sample job TODO
now = datetime.datetime.utcnow().replace(tzinfo=utc)
d = {
'1m': self.calc(orig=now, days=30),
'2w': self.calc(orig=now, days=14),
'1w': self.calc(orig=now, days=7),
'1d': self.calc(orig=now, days=1),
'1h': self.calc(orig=now, hours=1),
}
# for i in d:
# print i+':'+unicode(d[i])
# delete
for i in Instance.objects.filter(state__in=['ACTIVE', 'STOPPED'], time_of_delete__isnull=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)
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
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)
# suspend
for i in Instance.objects.filter(state='ACTIVE', time_of_suspend__isnull=False):
try:
translation.activate(i.owner.person_set.get().language)
except:
pass
# print u'%s suspend: %s' % (i.name, i.time_of_suspend)
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)
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)
......@@ -2,9 +2,11 @@ from one.models import *
from django_extensions.management.jobs import HourlyJob
class Job(HourlyJob):
help = "Update Disks and Networks from OpenNebula."
help = "Update Disks, Networks and Instances from OpenNebula."
def execute(self):
Disk.update()
Network.update()
for i in Instance.objects.filter(state__in=['ACTIVE', 'STOPPED'], time_of_delete__isnull=False):
i.update_state()
pass
......@@ -7,8 +7,8 @@ msgid ""
msgstr ""
"Project-Id-Version: \n"
"Report-Msgid-Bugs-To: \n"
"POT-Creation-Date: 2013-02-21 18:06+0100\n"
"PO-Revision-Date: 2013-02-21 18:07+0100\n"
"POT-Creation-Date: 2013-03-07 18:16+0100\n"
"PO-Revision-Date: 2013-03-07 17:40+0100\n"
"Last-Translator: \n"
"Language-Team: Hungarian <cloud@ik.bme.hu>\n"
"Language: hu\n"
......@@ -18,27 +18,32 @@ msgstr ""
"Plural-Forms: nplurals=2; plural=(n != 1)\n"
"X-Generator: Lokalize 1.4\n"
#: admin.py:11 models.py:317 models.py:364
#: admin.py:11 models.py:318 models.py:365
msgid "owner"
msgstr "tulajdonos"
#: admin.py:45
#: admin.py:35
#, python-format
msgid "%(sum)d (%(active)d active)"
msgstr "%(sum)d (%(active)d aktív)"
#: admin.py:58
msgid "Update status"
msgstr "Állapot frissítése"
#: admin.py:51
#: admin.py:64
msgid "Submit VM"
msgstr "VM beküldése"
#: admin.py:57
#: admin.py:70
msgid "Delete VM"
msgstr "VM törlése"
#: admin.py:63
#: admin.py:76
msgid "Suspend VM"
msgstr "VM felfüggesztése"
#: admin.py:69
#: admin.py:82
msgid "Resume VM"
msgstr "VM folytatása"
......@@ -105,8 +110,8 @@ msgid ""
"and store login (2048+ bit RSA preferred). Example: <code>ssh-rsa AAAAB..."
"QtQ== john</code>."
msgstr ""
"<a href=\"/info/ssh/\">SSH nyilvános kulcs OpenSSH formátumban</a> az SSH "
"bejelentkezéshez – ajánlás: 2048+ bites RSA. Példa: <code><code>ssh-rsa "
"<a href=\"/info/ssh/\">SSH nyilvános kulcs OpenSSH formátumban</a> az SSH\n"
"bejelentkezéshez – ajánlás: 2048+ bites RSA. Példa: <code><code>ssh-rsa\n"
"AAAAB...QtQ== jozsi</a>."
#: models.py:154
......@@ -121,11 +126,11 @@ msgstr "új"
msgid "perparing"
msgstr "előkészítés"
#: models.py:159 models.py:303
#: models.py:159 models.py:304
msgid "saving"
msgstr "mentés"
#: models.py:159 models.py:304
#: models.py:159 models.py:305
msgid "ready"
msgstr "kész"
......@@ -153,16 +158,16 @@ msgstr "szerver"
msgid "For long-term server use."
msgstr "Hosszú távú, szerver-felhasználáshoz."
#: models.py:175 models.py:218 models.py:252 models.py:291 models.py:308
#: models.py:359
#: models.py:175 models.py:218 models.py:253 models.py:292 models.py:309
#: models.py:360
msgid "name"
msgstr "név"
#: models.py:176 models.py:325
#: models.py:176 models.py:326
msgid "description"
msgstr "leírás"
#: models.py:180 models.py:320 models.py:367
#: models.py:180 models.py:321 models.py:368
msgid "created at"
msgstr "létrehozás ideje"
......@@ -182,236 +187,245 @@ msgstr "felhasználónkénti korlát"
msgid "Maximal count of instances launchable by a single user."
msgstr "Egy felhasználó által indítható példányok száma."
#: models.py:253
#: models.py:254
msgid "NAT"
msgstr "NAT"
#: models.py:254
#: models.py:255
msgid "If network address translation is done."
msgstr "Hálózati címfordítás történik-e."
#: models.py:255 models.py:323
#: models.py:256 models.py:324
msgid "public"
msgstr "publikus"
#: models.py:256
#: models.py:257
msgid "If internet gateway is available."
msgstr "Van-e elérheti internetes útválasztás."
#: models.py:292
#: models.py:293
msgid "CPU cores."
msgstr "CPU magok száma."
#: models.py:293
#: models.py:294
msgid "Mebibytes of memory."
msgstr "Memória mérete mebibyte-ban."
#: models.py:294
#: models.py:295
msgid "credits"
msgstr "kredit"
#: models.py:295
#: models.py:296
msgid "Price of instance."
msgstr "Példány értéke."
#: models.py:303
#: models.py:304
msgid "new"
msgstr "új"
#: models.py:311
#: models.py:312
msgid "access method"
msgstr "elérési mód"
#: models.py:312
#: models.py:313
msgid "disk"
msgstr "lemez"
#: models.py:314
#: models.py:315
msgid "instance type"
msgstr "példánytípus"
#: models.py:315
#: models.py:316
msgid "network"
msgstr "hálózat"
#: models.py:324
#: models.py:325
msgid "If other users can derive templates of this one."
msgstr "Más felhasználók készíthetnek-e ez alapján új sablonokat."
#: models.py:326
#: models.py:327
msgid "operating system"
msgstr "operációs rendszer"
#: models.py:327
#: models.py:328
#, python-format
msgid "Name of operating system in format like \"%s\"."
msgstr "Operációs rendszer neve a következő formában: „%s”."
#: models.py:331 models.py:362
#: models.py:332 models.py:363
msgid "template"
msgstr "sablon"
#: models.py:332
#: models.py:333
msgid "templates"
msgstr "sablonok"
#: models.py:361
#: models.py:362
msgid "IP address"
msgstr "IP cím"
#: models.py:369
#: models.py:370
msgid "deployable"
msgstr "beküldhető"
#: models.py:370
#: models.py:371
msgid "pending"
msgstr "várakozó"
#: models.py:371
#: models.py:372
msgid "done"
msgstr "kész"
#: models.py:372
#: models.py:373
msgid "active"
msgstr "aktív"
#: models.py:373
#: models.py:374
msgid "unknown"
msgstr "ismeretlen"
#: models.py:374
#: models.py:375
msgid "suspended"
msgstr "felfüggesztett"
#: models.py:375
#: models.py:376
msgid "failed"
msgstr "hiba"
#: models.py:378
#: models.py:379
msgid "active since"
msgstr "aktívvá válás ideje"
#: models.py:379
#: models.py:380
msgid "Time stamp of successful boot report."
msgstr "A sikeres indulás jelentésének időpontja."
#: models.py:381
#: models.py:382
msgid "host in firewall"
msgstr "gép a tűzfalban"
#: models.py:382
#: models.py:383
msgid "password"
msgstr "jelszó"
#: models.py:383
#: models.py:384
msgid "Original password of instance"
msgstr "A példány eredeti jelszava."
#: models.py:385
#: models.py:386
msgid "OpenNebula ID"
msgstr "OpenNebula ID"
#: models.py:387
#: models.py:388
msgid "share"
msgstr "megosztás"
#: models.py:389 templates/box/vm/entry.html:57
#: models.py:390 templates/box/vm/entry.html:58
msgid "time of suspend"
msgstr "felfüggesztés ideje"
#: models.py:391 templates/box/vm/entry.html:67
#: models.py:392 templates/box/vm/entry.html:68
msgid "time of delete"
msgstr "törlés ideje"
#: models.py:395
#: models.py:396
msgid "instance"
msgstr "példány"
#: models.py:396
#: models.py:397
msgid "instances"
msgstr "példányok"
#: views.py:68
#: models.py:416
msgid "None"
msgstr "Nincs"
#: views.py:84
msgid "Invalid template ID."
msgstr "Nincs ilyen sablon."
#: views.py:71
#: views.py:87
msgid "There are running instances of this template."
msgstr "A sablonnak még vannak futó példányai."
#: views.py:73
#: views.py:89
msgid "Template is still shared."
msgstr "A sablon még meg van osztva."
#: views.py:75
#: views.py:91
msgid "You don't have permission to delete this template."
msgstr "Nincs joga törölni a sablont."
#: views.py:78
#: views.py:94
msgid "Template successfully deleted."
msgstr "A sablon törlése sikeres."
#: views.py:80
#: views.py:96
msgid "Unexpected error happened."
msgstr "Váratlan hiba történt."
#: views.py:94
#: views.py:114
msgid "Could not get Virtual Machine credentials."
msgstr "Nem találhatóak a virutális gép adatai."
#: views.py:95 views.py:434
#: views.py:115 views.py:531
msgid "Failed to power off virtual machine."
msgstr "A virtuális gép kikapcsolása sikertelen."
#: views.py:123
#: views.py:164 views.py:211
msgid "You do not have any free share quota."
msgstr "Nincs szabad kvótája."
#: views.py:157
#: views.py:198 views.py:232
msgid "You do not have enough free share quota."
msgstr "Nincs elég szabad kvótája."
#: views.py:162
#: views.py:203
#, python-format
msgid "Successfully shared %s."
msgstr "„%s” megosztása sikeres."
#: views.py:176
#: views.py:241
#, python-format
msgid "Successfully edited share %s."
msgstr "„%s” megosztás szerkesztése sikeres."
#: views.py:253
msgid "Template is being saved..."
msgstr "A sablon mentése folyamatban van…"
#: views.py:207
#: views.py:284
msgid ""
"You do not have any free quota. You can not launch this until you stop an "
"other instance."
msgstr ""
"Nincs szabad kvótája. Addig nem tud gépet indítani, amíg le nem állít egyet."
#: views.py:211
#: views.py:288
msgid ""
"The share does not have any free quota. You can not launch this until "
"someone stops an instance."
msgstr ""
"Ennek a megosztásnak elfogyott a kvótája. Nem tudja addig elindítani, amíg "
"Ennek a megosztásnak elfogyott a kvótája. Nem tudja addig elindítani, amíg\n"
"valaki le nem állít egy példányt."
#: views.py:214
#: views.py:291
msgid ""
"You do not have any free quota for this share. You can not launch this until "
"you stop an other instance."
msgstr ""
"Nincs szabad kvótája ehhez a megosztáshoz. Nem tudja addig elindítani, amíg "
"Nincs szabad kvótája ehhez a megosztáshoz. Nem tudja addig elindítani, amíg\n"
"nem állít le egy másik példányt."
#: views.py:217
#: views.py:294
msgid "You are not a member of the share group."
msgstr "Nem tagja a megosztás csoportjának."
#: views.py:238
#: views.py:315
msgid "Can not create template."
msgstr "Sablon létrehozása sikertelen."
#: views.py:243
#: views.py:320
msgid ""
"You have no permission to try this instance without a share. Launch a new "
"instance through a share."
......@@ -419,336 +433,399 @@ msgstr ""
"Nincs joga a sablon kipróbálására megosztás nélkül. Próbálja egy megosztáson "
"keresztül."
#: views.py:256
#: views.py:335
msgid "Failed to create virtual machine."
msgstr "A virtuális gép indítása sikertelen."
#: views.py:332
#: views.py:425
msgid "Port number is in a restricted domain (22000 to 24000)."
msgstr "A megadott port foglalt tartományba esik (22000-től 24000-ig)."
#: views.py:335
#: views.py:432
#, python-format
msgid "Port %d successfully added."
msgstr "%d számú port hozzáadása sikeres."
#: views.py:337
#: views.py:434
msgid "Adding port failed."
msgstr "Port hozzáadása sikertelen."
#: views.py:353
#: views.py:450
#, python-format
msgid "Port %d successfully removed."
msgstr "%d számú port eltávolítása sikeres."
msgid "Port %s successfully removed."
msgstr "%s számú port eltávolítása sikeres."
#: views.py:355
#: views.py:452
msgid "Removing port failed."
msgstr "Port eltávolítása sikertelen."
#: views.py:365
#: views.py:462
msgid "Virtual machine is successfully deleted."
msgstr "A virtuális gép törlése sikeres."
#: views.py:367
#: views.py:464
msgid "Failed to delete virtual machine."
msgstr "A virtuális gép törlése sikertelen."
#: views.py:389
#: views.py:486
msgid "There are machines running of this share."
msgstr "A sablonnak még vannak futó példányai."
#: views.py:392
#: views.py:489
msgid "Share is successfully removed."
msgstr "Megosztás eltávolítása sikeres."
#: views.py:394
#: views.py:491
msgid "Failed to remove share."
msgstr "Megosztás törlése sikertelen."
#: views.py:402
#: views.py:499
msgid "Virtual machine is successfully stopped."
msgstr "A virtuális gép sikeresen leállt."
#: views.py:404
#: views.py:501
msgid "Failed to stop virtual machine."
msgstr "A virtuális gép leállítása sikertelen."
#: views.py:412
#: views.py:509
msgid "Virtual machine is successfully resumed."
msgstr "A virtuális gép sikeresen folytatva."
#: views.py:414
#: views.py:511
msgid "Failed to resume virtual machine."
msgstr "A virtuális gép visszatöltése sikertelen."
#: views.py:422
#: views.py:519
msgid "Virtual machine is successfully renewed."
msgstr "A virtuális gép sikeresen meghosszabbítva."
#: views.py:424
#: views.py:521
msgid "Failed to renew virtual machine."
msgstr "A virtuális gép meghosszabbítása sikertelen."
#: views.py:432
#: views.py:529
msgid "Virtual machine is successfully powered off."
msgstr "A virtuális gép kikapcsolása sikeres."
#: views.py:442
#: views.py:539
msgid "Virtual machine is successfully restarted."
msgstr "A virtuális gép újraindítása sikeres."
#: views.py:444
#: views.py:541
msgid "Failed to restart virtual machine."
msgstr "A virtuális gép újraindítása sikertelen."
#: views.py:459
msgid "Failed to add public key"
#: views.py:559
msgid "Failed to add public key."
msgstr "Nyilvános kulcs hozzáadása sikertelen."
#: views.py:469
#: views.py:561
msgid "Public key successfully added."
msgstr "Nyilvános kulcs hozzáadása sikeres."
#: views.py:572
msgid "Failed to delete public key"
msgstr "Nyilvános kulcs törlése sikertelen."
#: views.py:480
#: views.py:584
msgid "Failed to reset keys"
msgstr "Kulcsok újragenerálása"
#: templates/404.html:7 templates/404.html.py:10
#: templates/404.html:8 templates/500.html:8
msgid ":("
msgstr ":("
#: templates/new-share.html:7
#, python-format
msgid "Sharing template: %(t)s"
msgstr "Sablon megosztása: %(t)s"
#: templates/404.html:10
msgid "The requested page does not exists... Please go away..."
msgstr "A kért oldal nem található. Nincs itt semmi látnivaló."
#: templates/new-share.html:11
msgid "Choose a group"
msgstr "Válasszon csoportot"
#: templates/500.html:10
msgid "Internal Server Error... Please leave the server alone..."
msgstr "Kiszolgálóoldali hiba. A manóba!"
#: templates/new-share.html:13
msgid "You have no groups."
msgstr "Még nincs egy csoportja sem."
#: templates/base.html:35
msgid "Logged in:"
msgstr "Bejelentkezve:"
#: templates/new-share.html:17
msgid "Group"
msgstr "Csoport"
#: templates/base.html:36
msgid "Logout"
msgstr "Kijelentkezés"
#: templates/base.html:38
msgid "Admin"
msgstr "Admin"
#: templates/base.html:41
msgid "Login"
msgstr "Bejelentkezés"
#: templates/base.html:73
msgid "Legal notice"
msgstr "Impresszum"
#: templates/base.html:74
msgid "Policy"
msgstr "Szabályzat"
#: templates/base.html:75 templates/show.html:114
#: templates/vm-credentials.html:12 templates/box/file/box.html:14
#: templates/box/template/box.html:15 templates/box/vm/box.html:15
msgid "Help"
msgstr "Súgó"
#: templates/new-share.html:32 templates/new-template-flow.html:15
#: templates/base.html:76
msgid "Support"
msgstr "Támogatás"
#: templates/edit-share.html:7
#, python-format
msgid "Editing share: %(t)s"
msgstr "Megosztás szerkesztése: %(t)s"
#: templates/edit-share.html:9 templates/edit-template-flow.html:8
#: templates/new-share.html:32 templates/new-template-flow.html:16
msgid "Change the parameters as needed."
msgstr "Változtassa meg a paramétereket szükség szerint."
#: templates/new-share.html:35
#: templates/edit-share.html:12 templates/new-share.html:35
msgid "Name of share"
msgstr "Megosztás neve"
#: templates/new-share.html:40 templates/box/file/entry.html:31
#: templates/box/vm/box.html:87 templates/box/vm/entry.html:28
#: templates/edit-share.html:17 templates/new-share.html:40
#: templates/box/file/entry.html:32 templates/box/vm/box.html:93
#: templates/box/vm/entry.html:29
msgid "Type"
msgstr "Típus"
#: templates/new-share.html:58 templates/box/vm/box.html:91
#: templates/edit-share.html:34 templates/new-share.html:58
#: templates/box/vm/box.html:97
#, python-format
msgid "Suspend after %(time)s."
msgstr "Felfüggesztés %(time)s után."
#: templates/new-share.html:61 templates/box/vm/box.html:95
#: templates/edit-share.html:37 templates/new-share.html:61
#: templates/box/vm/box.html:101
#, python-format
msgid "Delete after %(time)s."
msgstr "Törlés %(time)s után."
#: templates/new-share.html:68
#: templates/edit-share.html:44 templates/new-share.html:68
msgid "Maximal count of instances"
msgstr "Példányok maximális száma"
#: templates/new-share.html:73
#: templates/edit-share.html:49 templates/new-share.html:73
msgid "Maximal count of instaces/user"
msgstr "Példányok max. száma/felhasználó"
#: templates/new-share.html:79 templates/new-template-flow.html:49
#: templates/box/template/box.html:107 templates/box/template/entry.html:32
#: templates/box/vm/box.html:99
#: templates/edit-share.html:55 templates/edit-template-flow.html:42
#: templates/new-share.html:79 templates/new-template-flow.html:50
#: templates/box/template/box.html:123 templates/box/template/entry.html:32
#: templates/box/vm/box.html:105
msgid "Description"
msgstr "Leírás"
#: templates/new-share.html:85 templates/new-template-flow-1.html:43
#: templates/new-template-flow.html:55
#: templates/edit-share.html:61 templates/edit-template-flow.html:48
#: templates/new-share.html:85 templates/new-template-flow-1.html:44
#: templates/new-template-flow.html:56
msgid "Cancel"
msgstr "Mégsem"
#: templates/new-share.html:86 templates/box/template/box.html:65
#: templates/box/template/box.html.py:66
#: templates/box/template/summary.html:46
#: templates/box/template/summary.html:47 templates/box/vm/entry.html:33
#: templates/edit-share.html:62 templates/edit-template-flow.html:49
#: templates/show.html:49 templates/box/file/box.html:112
msgid "Save"
msgstr "Mentés"
#: templates/edit-template-flow.html:7
msgid "Edit template"
msgstr "Sablon szerkesztése"
#: templates/edit-template-flow.html:11 templates/new-template-flow.html:19
msgid "Name"
msgstr "Név"
#: templates/edit-template-flow.html:17 templates/new-template-flow.html:25
#: templates/box/template/box.html:114 templates/box/template/entry.html:23
#: templates/box/vm/box.html:84 templates/box/vm/entry.html:44
msgid "Size"
msgstr "Méret"
#: templates/edit-template-flow.html:33 templates/new-template-flow.html:41
#, python-format
msgid "%(n)s core"
msgid_plural "%(n)s cores"
msgstr[0] "%(n)s mag"
msgstr[1] "%(n)s mag"
#: templates/new-share.html:7
#, python-format
msgid "Sharing template: %(t)s"
msgstr "Sablon megosztása: %(t)s"
#: templates/new-share.html:11
msgid "Choose a group"
msgstr "Válasszon csoportot"
#: templates/new-share.html:13
msgid "You have no groups."
msgstr "Még nincs egy csoportja sem."
#: templates/new-share.html:17
msgid "Group"
msgstr "Csoport"
#: templates/new-share.html:86 templates/box/template/box.html:71
#: templates/box/template/box.html.py:72
#: templates/box/template/summary.html:60
#: templates/box/template/summary.html:61 templates/box/vm/entry.html:34
msgid "Share"
msgstr "Megosztás"
#: templates/new-template-flow-1.html:11 templates/new-template-flow.html:11
#: templates/new-template-flow-1.html:12 templates/new-template-flow.html:12
#, python-format
msgid "%(step)s/%(all)s"
msgstr "%(step)s/%(all)s"
#: templates/new-template-flow-1.html:14 templates/new-template-flow.html:14
#: templates/new-template-flow-1.html:15 templates/new-template-flow.html:15
#, python-format
msgid "Step %(step)s"
msgstr "%(step)s. lépés"
#: templates/new-template-flow-1.html:16
#: templates/new-template-flow-1.html:17
msgid "Please choose the base system you want to customize."
msgstr "Válasszon egy alaprendszert, amelyet testre kíván szabni."
#: templates/new-template-flow-1.html:21
#: templates/new-template-flow-1.html:22
msgid "There are no available templates."
msgstr "Nincs elérhető sablon."
#: templates/new-template-flow-1.html:31 templates/box/template/box.html:56
#: templates/new-template-flow-1.html:32 templates/box/template/box.html:62
msgid "locked"
msgstr "zárolt"
#: templates/new-template-flow-1.html:32 templates/box/template/box.html:57
#: templates/new-template-flow-1.html:33 templates/box/template/box.html:63
msgid "This is a shared template."
msgstr "Ez egy megosztott sablon."
#: templates/new-template-flow-1.html:44
#: templates/new-template-flow-1.html:45
msgid "Next &raquo;"
msgstr "Tovább &raquo;"
#: templates/new-template-flow.html:18
msgid "Name"
msgstr "Név"
#: templates/new-template-flow.html:24 templates/box/template/box.html:98
#: templates/box/template/entry.html:23 templates/box/vm/box.html:78
#: templates/box/vm/entry.html:43
msgid "Size"
msgstr "Méret"
#: templates/new-template-flow.html:40
#, python-format
msgid "%(n)s core"
msgid_plural "%(n)s cores"
msgstr[0] "%(n)s mag"
msgstr[1] "%(n)s mag"
#: templates/new-template-flow.html:56
#: templates/new-template-flow.html:57
msgid "Launch master instance"
msgstr "Mesterpéldány indítása"
#: templates/show.html:28
#: templates/show.html:43
msgid "This is a master image for your new template."
msgstr "Ez egy mestergép az új sablonhoz."
#: templates/show.html:34 templates/box/file/box.html:106
msgid "Save"
msgstr "Mentés"
#: templates/show.html:39
#: templates/show.html:54
msgid "Connect to the machine."
msgstr "Csatlakozzon a géphez."
#: templates/show.html:41
#: templates/show.html:56
msgid "Do all the needed installation/customization."
msgstr "Végezze el a szükséges telepítést, testreszabást."
#: templates/show.html:44
#: templates/show.html:59
msgid "Log off (keep the machine running)."
msgstr "Jelentkezzen ki (a gépet NE állítsa le)."
#: templates/show.html:47
#: templates/show.html:62
msgid "Click on the \"save\" button on the right."
msgstr "Kattintson jobboldalt a „mentés” gombra."
#: templates/show.html:50
#: templates/show.html:65
msgid "The machine will be shut down and its disk saved."
msgstr "A gép leáll, lemeze mentésre kerül."
#: templates/show.html:53
#: templates/show.html:68
msgid "You can share the template with your groups."
msgstr "Megoszthatja a sablont csoportjaival."
#: templates/show.html:65
#: templates/show.html:80
msgid "Starting..."
msgstr "Indítás…"
#: templates/show.html:71
#: templates/show.html:85
msgid "Saving..."
msgstr "Mentés…"
#: templates/show.html:91
msgid "Running"
msgstr "Fut"
#: templates/show.html:75
#: templates/show.html:95
msgid "Stopped"
msgstr "Leállítva"
#: templates/show.html:78
#: templates/show.html:98
msgid "Deleted"
msgstr "Törölve"
#: templates/show.html:81
#: templates/show.html:101
msgid "Unexpected error occured"
msgstr "Váratlan hiba történt"
#: templates/show.html:86
#: templates/show.html:106
msgid "Login credentials"
msgstr "Belépési adatok"
#: templates/show.html:94 templates/vm-credentials.html:11
#: templates/box/file/box.html:12 templates/box/template/box.html:13
#: templates/box/vm/box.html:13
msgid "Help"
msgstr "Súgó"
#: templates/show.html:97
#: templates/show.html:117
msgid ""
"This is a list about the network ports\n"
" forwarded to the public internet."
msgstr "Ez a nyilvános internet felé továbbított hálózati portok listája."
#: templates/show.html:99
#: templates/show.html:119
msgid ""
"You can access the given private port of\n"
" the VM trough the public address of the network.\n"
" "
msgstr "A VM megadott belső portját elérheti a hálózat külső címén keresztül."
msgstr ""
"A VM megadott belső portját elérheti a hálózat külső címén keresztül.\n"
" "
#: templates/show.html:102
#: templates/show.html:122
msgid ""
"On the IPV6 network you can access the\n"
" listed private ports direcly using the VM's global IPV6\n"
" address (connections to other ports are dropped).\n"
" "
msgstr ""
"Az IPV6 hálózaton a megadott belső portokat közvetlenül érheti el a VM "
"globális IPV6 címén (a többi portra érkező kapcsolatokat eldobjuk)."
"Az IPV6 hálózaton a megadott belső portokat közvetlenül érheti el a VM\n"
"globális IPV6 címén (a többi portra érkező kapcsolatokat eldobjuk).\n"
" "
#: templates/show.html:108
#: templates/show.html:128
msgid "Port administration"
msgstr "Portok kezelése"
#: templates/show.html:114 templates/vm-credentials.html:6
#: templates/show.html:134 templates/vm-credentials.html:7
msgid "Protocol"
msgstr "Protokoll"
#: templates/show.html:115
#: templates/show.html:135
msgid "Public port"
msgstr "Külső port"
#: templates/show.html:116
#: templates/show.html:136
msgid "Private port"
msgstr "Belső port"
#: templates/show.html:124 templates/box/template/box.html:82
#: templates/box/template/summary.html:20 templates/box/vm/summary.html:39
#: templates/box/vm/summary.html.py:40 templates/box/vm/summary.html:49
#: templates/box/vm/summary.html.py:50 templates/box/vm/summary.html:56
#: templates/box/vm/summary.html.py:57 templates/box/vm/summary.html:60
#: templates/box/vm/summary.html.py:61
#: templates/show.html:144 templates/box/template/box.html:91
#: templates/box/template/summary.html:24 templates/box/vm/summary.html:40
#: templates/box/vm/summary.html.py:41 templates/box/vm/summary.html:50
#: templates/box/vm/summary.html.py:51 templates/box/vm/summary.html:57
#: templates/box/vm/summary.html.py:58 templates/box/vm/summary.html:61
#: templates/box/vm/summary.html.py:62
msgid "Delete"
msgstr "Törlés"
#: templates/show.html:142
#: templates/show.html:164
msgid "Add"
msgstr "Hozzáadás"
#: templates/vm-credentials.html:15
#: templates/vm-credentials.html:16
msgid ""
"You can access Linux machines through\n"
" the SSH protocol (we recommend\n"
......@@ -759,134 +836,137 @@ msgid ""
" "
msgstr ""
"A Linux gépeket az SSH protokollon érheti el. Windowshoz a <a href=\"http://"
"www.chiark.greenend.org.uk/~sgtatham/putty/\">PuTTY</a>-ot, minden más "
"rendszerhez az OpenSSH klienst ajánljuk."
"www.chiark.greenend.org.uk/~sgtatham/putty/\">PuTTY</a>-ot, minden más\n"
"rendszerhez az OpenSSH klienst ajánljuk.\n"
" "
#: templates/vm-credentials.html:21
#: templates/vm-credentials.html:22
msgid ""
"Graphical log in is also supported with\n"
" the <a href=\"http://www.nomachine.com/download.php"
"\">\n"
" NoMachine NX Client</a> application."
msgstr ""
"Grafikus bejelentkezés a <a href=\"http://www.nomachine.com/download.php\"> "
"Grafikus bejelentkezés a <a href=\"http://www.nomachine.com/download.php\">\n"
"NoMachine NX Client</a> alkalmazással lehetséges."
#: templates/vm-credentials.html:26
#: templates/vm-credentials.html:27
msgid ""
"You can access Windows machines through\n"
" the remote desktop protocol."
msgstr "A Windows gépeket a távoli asztal protokollon érheti el."
#: templates/vm-credentials.html:28
#: templates/vm-credentials.html:29
msgid ""
"We recommend the built-in remote desktop\n"
" client for Windows and Remmina for Linux."
msgstr ""
"Windowshoz a beépített távoli asztali kapcsolat alkalmazást, Linuxhoz a "
"Windowshoz a beépített távoli asztali kapcsolat alkalmazást, Linuxhoz a\n"
"Remminát ajánljuk."
#: templates/vm-credentials.html:37
#: templates/vm-credentials.html:38
msgid "IP"
msgstr "IP"
#: templates/vm-credentials.html:41
#: templates/vm-credentials.html:42
msgid "Port"
msgstr "Port"
#: templates/vm-credentials.html:45
#: templates/vm-credentials.html:46
msgid "Username"
msgstr "Felhasználónév"
#: templates/vm-credentials.html:49
#: templates/vm-credentials.html:50
msgid "Password"
msgstr "Jelszó"
#: templates/box/file/box.html:7
#: templates/box/file/box.html:8
msgid "Data store"
msgstr "Adattár"
#: templates/box/file/box.html:15
#: templates/box/file/box.html:17
msgid "This is your global data store."
msgstr "Ez az ön központi adattárja."
#: templates/box/file/box.html:16
#: templates/box/file/box.html:18
msgid ""
"You can access it from all your own virtual machines,\n"
" the lab client, this web interface, or through SFTP protocol.\n"
" "
msgstr ""
"A fájlokat elérheti az összes virtuális gépéről, a laborkliensről, erről a "
"webes felületről, vagy SFTP protokollon."
"A fájlokat elérheti az összes virtuális gépéről, a laborkliensről, erről\n"
"a webes felületről, vagy SFTP protokollon.\n"
" "
#: templates/box/file/box.html:19
#: templates/box/file/box.html:21
msgid ""
"This directory is mounted on Windows machines as Z:\n"
" drive, and on Linux ones as ~/sshfs."
msgstr ""
"A windowsos gépeken a Z: meghajtóra, Linuxon a ~/sshfs katalógusba van "
"csatolva."
"A windowsos gépeken a Z: meghajtóra, Linuxon a ~/sshfs katalógusba\n"
"vancsatolva."
#: templates/box/file/box.html:21
#: templates/box/file/box.html:23
msgid ""
"If you log in on lab machines (currently Ubuntu only),\n"
" you can see this folder also as ~/sshfs."
msgstr ""
"Ha a laborgépekre bejelentkezik (jelenleg csak Ubuntu alatt), akkor a "
"fájlokat szintén a ~/sshfs katalógusban találja."
"Ha a laborgépekre bejelentkezik (jelenleg csak Ubuntu alatt), akkor\n"
"afájlokat szintén a ~/sshfs katalógusban találja."
#: templates/box/file/box.html:23
#: templates/box/file/box.html:25
#, python-format
msgid ""
"You can also use an SFTP client (eg.\n"
" WinSCP) to access your files at %(serv)s. You will need to register "
"a\n"
" WinSCP) to access your files at %(serv)s. You will need to "
"register a\n"
" public key bellow."
msgstr ""
"SFTP klienst (pl. WinSCP) is használhat a %(serv)s címre csatlakozva. Ehhez "
"alább tudja nyilvános kulcsát regisztrálni."
"SFTP klienst (pl. WinSCP) is használhat a %(serv)s címre csatlakozva.\n"
"Ehhezalább tudja nyilvános kulcsát regisztrálni."
#: templates/box/file/box.html:31 templates/box/template/box.html:26
#: templates/box/vm/box.html:26
msgid "Show/hide box"
msgstr "Doboz megjelenítése/rejtése"
#: templates/box/file/box.html:60
#: templates/box/file/box.html:66
msgid "No files."
msgstr "Nincs megjeleníthető fájl."
#: templates/box/file/box.html:73
#: templates/box/file/box.html:79
msgid "Create folder"
msgstr "Mappa létrehozása"
#: templates/box/file/box.html:75
#: templates/box/file/box.html:81
msgid "Name of new folder"
msgstr "Új mappa neve"
#: templates/box/file/box.html:83
msgid "Toplist"
msgstr "Legújabb fájlok"
#: templates/box/file/box.html:89
#: templates/box/file/box.html:95
msgid "Manage keys"
msgstr "Kulcsok kezelése"
#: templates/box/file/box.html:98
#: templates/box/file/box.html:104
msgid "Add public key"
msgstr "Nyilvános kulcs hozzáadása"
#: templates/box/file/box.html:105
#: templates/box/file/box.html:111
msgid "Public key in OpenSSH format"
msgstr "Nyilvános kulcs OpenSSH formátumban"
#: templates/box/file/box.html:113
#: templates/box/file/box.html:119
msgid "Reset key"
msgstr "Kulcsok újragenerálása"
#: templates/box/file/box.html:122
#: templates/box/file/box.html:128
msgid "File upload"
msgstr "Fájlfeltöltés"
#: templates/box/file/box.html:128
#: templates/box/file/box.html:134
msgid "Drag and drop files here to start uploading."
msgstr "Húzza ide a fájlt a feltöltés megkezdéséhez."
#: templates/box/file/box.html:130
#: templates/box/file/box.html:136
msgid ""
"You can also use the <a href=\"#\" id=\"old-upload\">the traditional upload "
"form</a>."
......@@ -894,222 +974,402 @@ msgstr ""
"Használhatja a <a href=\"#\" id=\"old-upload\">hagyományos feltöltő űrlapot</"
"a> is."
#: templates/box/file/box.html:132
#: templates/box/file/box.html:138
msgid "Upload limit is 1GB per file!"
msgstr "A feltöltési limit 1GiB fájlonként!"
#: templates/box/file/box.html:136
#: templates/box/file/box.html:142
msgid "Error: File is bigger than 1GB!"
msgstr "Hiba: a fájl nagyobb 1 GiB-nál."
#: templates/box/file/box.html:137
#: templates/box/file/box.html:143
msgid "Error: Upload server is not available!"
msgstr "Hiba: a feltöltő kiszolgáló nem érhető el."
#: templates/box/file/box.html:138
#: templates/box/file/box.html:144
msgid "Error: File already exists!"
msgstr "Hiba: a fájl már létezik."
#: templates/box/file/box.html:157
#: templates/box/file/box.html:163
msgid "File quota"
msgstr "Fájlkvóta"
#: templates/box/file/box.html:157
#: templates/box/file/box.html:163
msgid "Used space"
msgstr "Használt terület"
#: templates/box/file/box.html:158
#: templates/box/file/box.html:164
msgid "soft limit"
msgstr "puha limit"
#: templates/box/file/box.html:160
#: templates/box/file/box.html:166
msgid "hard limit"
msgstr "kemény limit"
#: templates/box/file/entry.html:11
#: templates/box/file/entry.html:12
msgid "rename"
msgstr "átnevezés"
#: templates/box/file/entry.html:14
#: templates/box/file/entry.html:15
msgid "remove"
msgstr "eltávolítás"
#: templates/box/file/entry.html:17
#: templates/box/file/entry.html:18
msgid "download"
msgstr "letöltés"
#: templates/box/file/entry.html:27
#: templates/box/file/entry.html:28
msgid "Last modification"
msgstr "Utolsó módosítás"
#: templates/box/key/entry.html:18 templates/box/template/summary.html:50
#: templates/box/template/summary.html:51
#: templates/box/key/entry.html:19 templates/box/template/summary.html:64
#: templates/box/template/summary.html:65
msgid "Remove"
msgstr "Törlés"
#: templates/box/template/box.html:7
#: templates/box/template/box.html:8
msgid "Templates"
msgstr "Sablonok"
#: templates/box/template/box.html:16
#: templates/box/template/box.html:18
msgid "This is the list of your own templates."
msgstr "Ez a saját sablonjainak listája."
#: templates/box/template/box.html:17
#: templates/box/template/box.html:19
msgid "Templates are customized versions of the base images."
msgstr "A sablonok alaprendszerek testre szabott változatai."
#: templates/box/template/box.html:18
#: templates/box/template/box.html:20
msgid ""
"You can install all the needed software on a master\n"
" machine, and it will be ready to run by your students in minutes.\n"
" machine, and it will be ready to run by your students in "
"minutes.\n"
" "
msgstr ""
"Telepítheti az összes szükséges szoftvert egy mestergépen, és az így készült "
"sablon pár perc múltán készen is állhat a hallgatók számára."
"Telepítheti az összes szükséges szoftvert egy mestergépen, és az így\n"
"készült sablon pár perc múltán készen is állhat a hallgatók számára.\n"
" "
#: templates/box/template/box.html:34
#: templates/box/template/box.html:40
msgid "You have no own templates."
msgstr "Még nincs egy sablonja sem."
#: templates/box/template/box.html:36
#: templates/box/template/box.html:42
msgid ""
"Create a new one, and share it with your students. Or you can also use a "
"common one."
msgstr ""
"Hozzon létre egyet, és ossza meg hallgatóival. Vagy használjon egy közöset."
#: templates/box/template/box.html:62 templates/box/template/summary.html:40
#: templates/box/template/box.html:68 templates/box/template/summary.html:54
msgid "Try"
msgstr "Kipróbálás"
#: templates/box/template/box.html:63 templates/box/template/summary.html:41
#: templates/box/template/box.html:69 templates/box/template/summary.html:55
msgid "Start"
msgstr "Indítás"
#: templates/box/template/box.html:93 templates/box/template/entry.html:18
#: templates/box/vm/box.html:73 templates/box/vm/entry.html:23
#: templates/box/template/box.html:88 templates/box/template/summary.html:21
#: templates/box/template/summary.html:50
#: templates/box/template/summary.html:51
#: templates/box/template/summary.html:57
#: templates/box/template/summary.html:58
msgid "Edit"
msgstr "Szerkesztés"
#: templates/box/template/box.html:99 templates/box/template/summary.html:32
msgid "No description available"
msgstr "Nincs leírás"
#: templates/box/template/box.html:109 templates/box/template/entry.html:18
#: templates/box/vm/box.html:79 templates/box/vm/entry.html:24
msgid "System"
msgstr "Rendszer"
#: templates/box/template/box.html:112 templates/box/template/entry.html:37
#: templates/box/vm/entry.html:52
#: templates/box/template/box.html:128 templates/box/template/entry.html:37
#: templates/box/vm/entry.html:53
msgid "Created at"
msgstr "Létrehozás ideje"
#: templates/box/template/box.html:117 templates/box/template/entry.html:42
#: templates/box/template/box.html:133 templates/box/template/entry.html:42
msgid "Running instances"
msgstr "Futó példányok"
#: templates/box/template/box.html:131
#: templates/box/template/box.html:147
#, python-format
msgid "Share quota: %(used)s/%(all)s"
msgstr "Megosztó kvóta: %(used)s/%(all)s"
#: templates/box/template/summary.html:43
#: templates/box/template/summary.html:44
#: templates/box/template/summary.html:53
#: templates/box/template/summary.html:54
msgid "Edit"
msgstr "Szerkesztés"
#: templates/box/vm/box.html:7
#: templates/box/vm/box.html:8
msgid "Virtual machines"
msgstr "Virtuális gépek"
#: templates/box/vm/box.html:16
#: templates/box/vm/box.html:18
msgid "This is the list of your running virtual machines."
msgstr "Ez az ön futó virtuális gépeinek listája."
#: templates/box/vm/box.html:17
#: templates/box/vm/box.html:19
msgid ""
"You can launch a new VM instance if it is shared by\n"
" a teacher for one of your groups."
msgstr ""
"Egy VM példányt akkor tud elindítani, ha egy oktató megosztotta egy olyan "
"Egy VM példányt akkor tud elindítani, ha egy oktató megosztotta egy olyan\n"
"csoporttal, amelynek tagja."
#: templates/box/vm/box.html:19
#: templates/box/vm/box.html:21
msgid ""
"Please note, that users and shares both have a limit\n"
" of launchable instances."
msgstr ""
"Vegye figyelembe, hogy a felhasználóknak és az egyes megosztásoknak is "
"Vegye figyelembe, hogy a felhasználóknak és az egyes megosztásoknak is\n"
"korlátozva van a futtatható példányszám."
#: templates/box/vm/box.html:34
#: templates/box/vm/box.html:40
msgid "You have not started any machines yet."
msgstr "Még nem indított egy gépet sem."
#: templates/box/vm/box.html:36
#: templates/box/vm/box.html:42
msgid "Choose a template, and you can use the system in a minute."
msgstr "Válasszon egy sablont, és egy percen belül használhatja a rendszert."
#: templates/box/vm/box.html:45
#: templates/box/vm/box.html:51
msgid "Start new machine"
msgstr "Új gép indítása"
#: templates/box/vm/box.html:50
#: templates/box/vm/box.html:56
msgid "Available shares"
msgstr "Elérhető megosztások"
#: templates/box/vm/box.html:52
#: templates/box/vm/box.html:58
msgid "Choose one of the following shared templates to launch."
msgstr "Válasszon egyet az alábbi megosztott sablonok közül."
#: templates/box/vm/box.html:108
#: templates/box/vm/box.html:114
msgid "Quota reached"
msgstr "Kvóta betelt"
#: templates/box/vm/box.html:108
#: templates/box/vm/box.html:114
msgid "Launch"
msgstr "Indítás"
#: templates/box/vm/box.html:128
#: templates/box/vm/box.html:134
#, python-format
msgid "Personal quota: %(used)s/%(all)s"
msgstr "Személyes kvóta: %(used)s/%(all)s"
#: templates/box/vm/entry.html:18
#: templates/box/vm/entry.html:19
msgid "Hostname"
msgstr "Gépnév"
#: templates/box/vm/entry.html:38
#: templates/box/vm/entry.html:39
msgid "Template"
msgstr "Sablon"
#: templates/box/vm/entry.html:59 templates/box/vm/entry.html.py:60
#: templates/box/vm/entry.html:60 templates/box/vm/entry.html.py:61
msgid "Renew suspend time"
msgstr "Felfüggesztési idő meghosszabbítása"
#: templates/box/vm/entry.html:69 templates/box/vm/entry.html.py:70
#: templates/box/vm/entry.html:70 templates/box/vm/entry.html.py:71
msgid "Renew deletion time"
msgstr "Törlési idő meghosszabbítása"
#: templates/box/vm/entry.html:78 templates/box/vm/summary.html:15
#: templates/box/vm/entry.html:79 templates/box/vm/summary.html:16
msgid "More details"
msgstr "További részletek"
#: templates/box/vm/summary.html:25 templates/box/vm/summary.html.py:26
#: templates/box/vm/summary.html:26 templates/box/vm/summary.html.py:27
msgid "Edit name"
msgstr "Név szerkesztése"
#: templates/box/vm/summary.html:33 templates/box/vm/summary.html.py:34
#: templates/box/vm/summary.html:34 templates/box/vm/summary.html.py:35
msgid "Connect"
msgstr "Csatlakozás"
#: templates/box/vm/summary.html:36 templates/box/vm/summary.html.py:37
#: templates/box/vm/summary.html:37 templates/box/vm/summary.html.py:38
msgid "Pause"
msgstr "Felfüggesztés"
#: templates/box/vm/summary.html:42
#: templates/box/vm/summary.html:43
msgid "Restart"
msgstr "Újraindítás"
#: templates/box/vm/summary.html:53 templates/box/vm/summary.html.py:54
#: templates/box/vm/summary.html:54 templates/box/vm/summary.html.py:55
msgid "Resume"
msgstr "Folytatás"
#: templates/mails/base.txt:2
#, python-format
msgid ""
"\n"
"Dear %(name)s,\n"
"\n"
msgstr ""
"\n"
"Kedves %(name)s!\n"
"\n"
#: templates/mails/notification-ban-now.txt:6
#, python-format
msgid ""
"\n"
"Our network intrusion detection system showed that your machine\n"
"\"%(vm)s\" pursues the following forbidden network activity: %(reason)s.\n"
"\n"
"\"%(vm)s\" has been BANNED from all network activity\n"
"including remote desktop and shell connection.\n"
"\n"
"Details:\n"
"%(snort_message)s\n"
msgstr ""
"\n"
"A hálózatibehatolás-érzékelő rendszerünk jelzése szerint az ön „%(vm)s”\n"
"nevű gépe a következő tiltott hálózati aktivitást folytatja: %(reason)s.\n"
"\n"
"A(z) „%(vm)s” gép minden hálózati aktivitása TILTÁSRA került, beleértve a \n"
"távoli asztali- és shellkapcsolatokat.\n"
"\n"
"Részletek: %(snort_message)s\n"
#: templates/mails/notification-ban-now.txt:18
#, python-format
msgid ""
"\n"
"Please, reply to this notification, or delete the instance on the\n"
"cloud portal: %(url)s\n"
msgstr ""
"\n"
"Kérjük, válaszoljon erre a figyelmeztetésre, vagy törölje a gépet a\n"
"cloud\n"
"portálon: %(url)s\n"
#: templates/mails/notification-delete-now.txt:6
#, python-format
msgid ""
"\n"
"Your %(state)s virtual machine \"%(vm)s\" has been DELETED\n"
"at %(date)s.\n"
msgstr ""
"\n"
"Az ön „%(vm)s” nevű %(state)s állapotú virtuális gépét TÖRÖLTÜK\n"
"%(date)s időpontban.\n"
#: templates/mails/notification-delete-now.txt:11
msgid ""
"\n"
"The disk image is IRRECOVERABLY REMOVED.\n"
msgstr ""
"\n"
"A lemezkép VISSZAÁLLÍTHATATLANUL TÖRLÉSRE került.\n"
#: templates/mails/notification-delete-now.txt:15
#, python-format
msgid ""
"\n"
"You can start a new instance of the template on the cloud portal:\n"
"%(url)s\n"
msgstr ""
"\n"
"Elindíthatja a sablon egy új példányát a cloud portálon:\n"
"%(url)s\n"
#: templates/mails/notification-delete.txt:6
#, python-format
msgid ""
"\n"
"Your %(state)s virtual machine \"%(vm)s\" is going to be DELETED\n"
"at %(date)s (in %(time)s).\n"
msgstr ""
"\n"
"Az ön „%(vm)s” nevű %(state)s állapotú virtuális gépe TÖRLÉSRE\n"
"kerül %(date)s időpontban (%(time)s múlva).\n"
#: templates/mails/notification-delete.txt:11
msgid ""
"\n"
"The disk image will be IRRECOVERABLY REMOVED.\n"
msgstr ""
"\n"
"A lemezkép HELYREÁLLÍTHATATLANUL TÖRLÉSRE kerül.\n"
#: templates/mails/notification-delete.txt:15
#, python-format
msgid ""
"\n"
"You can renew or delete the instance on the cloud portal:\n"
"%(url)s\n"
msgstr ""
"\n"
"Megújíthatja vagy törölheti a példányt a cloud portálon:\n"
"%(url)s\n"
#: templates/mails/notification-suspend-now.txt:6
#, python-format
msgid ""
"\n"
"Your %(state)s virtual machine \"%(vm)s\" has been STOPPED\n"
"at %(date)s.\n"
msgstr ""
"\n"
"Az ön „%(vm)s” nevű %(state)s állapotú gépe FELFÜGGESZTÉSRE\n"
"került %(date)s időpontban.\n"
#: templates/mails/notification-suspend-now.txt:11
#, python-format
msgid ""
"\n"
"The disk and memory image is stored, and you can resume it\n"
"until the final expiration time (%(deldate)s).\n"
msgstr ""
"\n"
"A lemez- és memóriaképet tároljuk, így a végleges lejárati\n"
"időig (%(deldate)s) folytathatja a futtatását.\n"
#: templates/mails/notification-suspend-now.txt:16
#: templates/mails/notification-suspend.txt:16
#, python-format
msgid ""
"\n"
"You can also renew or delete the instance on the cloud portal:\n"
"%(url)s\n"
msgstr ""
"\n"
"Megújíthatja vagy törölheti a példányt a cloud portálon:\n"
"%(url)s\n"
#: templates/mails/notification-suspend.txt:6
#, python-format
msgid ""
"\n"
"Your %(state)s virtual machine \"%(vm)s\" is going to be STOPPED\n"
"at %(date)s (in %(time)s).\n"
msgstr ""
"\n"
"Az ön „%(vm)s” nevű %(state)s állapotú gépe FELFÜGGESZTÉSRE\n"
"kerül %(date)s időpontban (%(time)s múlva).\n"
#: templates/mails/notification-suspend.txt:11
#, python-format
msgid ""
"\n"
"The disk and memory image will be stored, and you can resume it\n"
"until the final expiration time (%(deldate)s).\n"
msgstr ""
"\n"
"A lemez- és memóriaképet tárolni fogjuk, így a végleges lejárati\n"
"időig (%(deldate)s) folytathatja a futtatását.\n"
#~ msgid "Impressum"
#~ msgstr "Impresszum"
#~ msgid "Delete notification"
#~ msgstr "Figyelmeztetés törlésről"
#~ msgid "Stop notification"
#~ msgstr "Figyelmeztetés felfüggesztésről"
#~ msgid "Toplist"
#~ msgstr "Legújabb fájlok"
#~ msgid "Public keys"
#~ msgstr "Nyilvános kulcsok"
......
......@@ -6,8 +6,8 @@ msgid ""
msgstr ""
"Project-Id-Version: \n"
"Report-Msgid-Bugs-To: \n"
"POT-Creation-Date: 2013-02-21 18:06+0100\n"
"PO-Revision-Date: 2013-02-21 18:09+0100\n"
"POT-Creation-Date: 2013-03-07 18:16+0100\n"
"PO-Revision-Date: 2013-03-07 17:02+0100\n"
"Last-Translator: \n"
"Language-Team: Hungarian <cloud@ik.bme.hu>\n"
"Language: hu\n"
......@@ -17,108 +17,117 @@ msgstr ""
"Plural-Forms: nplurals=2; plural=(n != 1)\n"
"X-Generator: Lokalize 1.4\n"
#: static/script/cloud.js:24
#: static/script/cloud.js:24 static/script/cloud.min.js:1
msgid "Are you sure deleting key?"
msgstr "Biztosan törli a kulcsot?"
#: static/script/cloud.js:24 static/script/cloud.js.c:246
#: static/script/cloud.js:320 static/script/cloud.js.c:533
#: static/script/store.js:273
#: static/script/cloud.js:24 static/script/cloud.js.c:296
#: static/script/cloud.js:370 static/script/cloud.js.c:623
#: static/script/cloud.min.js:1 static/script/store.js:288
#: static/script/store.min.js:1
msgid "Delete"
msgstr "Törlés"
#: static/script/cloud.js:36
#: static/script/cloud.js:36 static/script/cloud.min.js:1
msgid ""
"Are you sure about reseting store credentials?<br /> You will lose your "
"access to your store account on your existing virtual machines!"
msgstr ""
"Biztosan újragenerálja az adattár-kulcsait?<br /> "
"El fogja veszteni az adattár-hozzáférést a már futó virtuális gépekből!"
"Biztosan újragenerálja az adattár-kulcsait?<br /> El fogja veszteni az "
"adattár-hozzáférést a már futó virtuális gépekből!"
#: static/script/cloud.js:36
#: static/script/cloud.js:36 static/script/cloud.min.js:1
msgid "Reset"
msgstr "Újragenerálás"
#: static/script/cloud.js:65 static/script/store.js:309
#: static/script/cloud.js:75 static/script/cloud.min.js:1
#: static/script/store.js:323 static/script/store.min.js:1
msgid "Rename"
msgstr "Átnevezés"
#: static/script/cloud.js:221 static/script/store.js:273
#: static/script/cloud.js:271 static/script/cloud.min.js:1
#: static/script/store.js:288 static/script/store.min.js:1
msgid "Cancel"
msgstr "Mégsem"
#: static/script/cloud.js:235
#: static/script/cloud.js:285 static/script/cloud.min.js:1
#, c-format
msgid "Are you sure stopping %s?"
msgstr "Biztosan felfüggeszti a következőt: %s?"
#: static/script/cloud.js:236
#: static/script/cloud.js:286 static/script/cloud.min.js:1
msgid "Stop"
msgstr "Felfüggesztés"
#: static/script/cloud.js:245
#: static/script/cloud.js:295 static/script/cloud.min.js:1
#, c-format
msgid "Are you sure deleting %s?"
msgstr "Biztosan törli a következőt: %s?"
#: static/script/cloud.js:255
#: static/script/cloud.js:305 static/script/cloud.min.js:1
#, c-format
msgid "Are you sure restarting %s?"
msgstr "Biztosan újraindítja a következőt: %s?"
#: static/script/cloud.js:256
#: static/script/cloud.js:306 static/script/cloud.min.js:1
msgid "Restart"
msgstr "Újraindítás"
#: static/script/cloud.js:319
#: static/script/cloud.js:369 static/script/cloud.min.js:1
#, c-format
msgid "Are you sure deleting this %s template?"
msgstr "Biztosan törli a következő sablont: %s?"
#: static/script/cloud.js:452 static/script/cloud.js.c:459
#: static/script/cloud.js:547 static/script/cloud.js.c:550
#: static/script/cloud.min.js:1
msgid "Add owner"
msgstr "Tulajdonos hozzáadása"
#: static/script/cloud.js:457
#: static/script/cloud.js:550 static/script/cloud.min.js:1
msgid "Unknown"
msgstr "Ismeretlen"
#: static/script/cloud.js:533
#: static/script/cloud.js:623 static/script/cloud.min.js:1
#, c-format
msgid "Are you sure deleting <strong>%s</strong>"
msgstr "Törli a következő fájlt: <strong>%s</strong>"
#: static/script/store.js:57 static/script/store.js.c:66
#: static/script/store.js:75 static/script/store.js.c:205
#: static/script/store.js:267
#: static/script/store.js:52 static/script/store.js.c:61
#: static/script/store.js:70 static/script/store.js.c:220
#: static/script/store.js:282 static/script/store.min.js:1
msgid "file"
msgstr "fájl"
#: static/script/store.js:268
#: static/script/store.js:125 static/script/store.min.js:1
msgid "Toplist"
msgstr "Legújabb fájlok"
#: static/script/store.js:127 static/script/store.min.js:1
msgid "Back to the root folder"
msgstr "Vissza a gyökérmappába"
#: static/script/store.js:283 static/script/store.min.js:1
#, c-format
msgid "You are removing the file <strong>%s</strong>."
msgstr "Törli a következő fájlt: <strong>%s</strong>."
#: static/script/store.js:270
#: static/script/store.js:285 static/script/store.min.js:1
#, c-format
msgid "You are removing the folder <strong>%s</strong> (and its content)."
msgstr "Törli a következő könyvtárat és tartalmát: <strong>%s</strong>."
#: static/script/store.js:273
#: static/script/store.js:288 static/script/store.min.js:1
msgid "Are you sure?"
msgstr "Biztos benne?"
#: static/script/store.js:427 static/script/store.js.c:429
#: static/script/store.js:446 static/script/store.js.c:448
#: static/script/store.min.js:1
msgid "Upload"
msgstr "Feltöltés"
#: static/script/store.js:429
#: static/script/store.js:448 static/script/store.min.js:1
msgid "done, processing..."
msgstr "kész, feldolgozás..."
#, fuzzy
#~ msgid "Are you sure about reseting store credentials"
#~ msgstr "Biztosan újraindítja a következőt: %s?"
#~ msgid "Please choose a different name."
#~ msgstr "Kérem, válasszon eltérő nevet."
......@@ -14,7 +14,7 @@ from django.db.models.signals import post_save
from django import forms
from django.utils.translation import ugettext_lazy as _
from firewall.models import Host, Rule, Vlan
from firewall.models import Host, Rule, Vlan, Record
from school.models import Person, Group
from store.api import StoreApi
from .util import keygen
......@@ -224,7 +224,7 @@ class Disk(models.Model):
return u"%s (#%d)" % (self.name, self.id)
@staticmethod
def update():
def update(delete=True):
"""Get and register virtual disks from OpenNebula."""
import subprocess
proc = subprocess.Popen(["/opt/occi.sh", "storage", "list"],
......@@ -244,6 +244,7 @@ class Disk(models.Model):
except:
Disk(id=id, name=name).save()
l.append(id)
if delete:
Disk.objects.exclude(id__in=l).delete()
class Network(models.Model):
......@@ -400,34 +401,46 @@ class Instance(models.Model):
@models.permalink
def get_absolute_url(self):
return ('vm_show', None, {'iid':self.id})
return ('one.views.vm_show', None, {'iid':self.id})
def get_port(self):
def get_port(self, use_ipv6=False):
"""Get public port number for default access method."""
proto = self.template.access_type
if self.template.network.nat:
if self.template.network.nat and not use_ipv6:
return {"rdp": 23000, "nx": 22000, "ssh": 22000}[proto] + int(self.ip.split('.')[2]) * 256 + int(self.ip.split('.')[3])
else:
return {"rdp": 3389, "nx": 22, "ssh": 22}[proto]
def get_connect_host(self):
def get_connect_host(self, use_ipv6=False):
"""Get public hostname."""
if self.firewall_host is None:
return _('None')
try:
if use_ipv6:
return self.firewall_host.record_set.filter(type='AAAA')[0].get_data()['name']
else:
if self.template.network.nat:
return 'cloud'
ip = self.firewall_host.pub_ipv4
return Record.objects.filter(type='A', address=ip)[0].get_data()['name']
else:
return self.ip
return self.firewall_host.record_set.filter(type='A')[0].get_data()['name']
except:
if self.template.network.nat:
return self.firewall_host.pub_ipv4
else:
return self.firewall_host.ipv4
def get_connect_uri(self):
def get_connect_uri(self, use_ipv6=False):
"""Get access parameters in URI format."""
try:
proto = self.template.access_type
if proto == 'ssh':
proto = 'sshterm'
port = self.get_port()
host = self.get_connect_host()
port = self.get_port(use_ipv6=use_ipv6)
host = self.get_connect_host(use_ipv6=use_ipv6)
pw = self.pw
return ("%(proto)s:cloud:%(pw)s:%(host)s:%(port)d" %
{"port": port, "proto": proto, "pw": pw,
"host": self.firewall_host.pub_ipv4})
"host": host})
except:
return
......@@ -540,11 +553,13 @@ class Instance(models.Model):
inst.save()
inst.update_state()
host = Host(vlan=Vlan.objects.get(name=template.network.name),
owner=owner, shared_ip=True)
owner=owner)
host.hostname = hostname
host.mac = x.getElementsByTagName("MAC")[0].childNodes[0].nodeValue
host.ipv4 = inst.ip
if inst.template.network.nat:
host.pub_ipv4 = Vlan.objects.get(name=template.network.name).snat_ip
host.shared_ip = True
host.ipv6 = "auto"
try:
host.save()
......@@ -575,7 +590,10 @@ class Instance(models.Model):
if self.firewall_host:
h = self.firewall_host
self.firewall_host = None
try:
self.save()
except:
pass
h.delete()
def _update_vm(self, template):
......@@ -611,12 +629,12 @@ class Instance(models.Model):
self._change_state("POWEROFF")
def restart(self):
self._change_state("RESET")
def renew(self, which):
if which == 'suspend':
def renew(self, which='both'):
if which in ['suspend', 'both']:
self.time_of_suspend = self.share.get_type()['suspendx']
elif which == 'delete':
if which in ['delete', 'both']:
self.time_of_delete = self.share.get_type()['deletex']
else:
if not (which in ['suspend', 'delete', 'both']):
raise ValueError('No such expiration type.')
self.save()
def save_as(self):
......@@ -633,7 +651,7 @@ class Instance(models.Model):
def check_if_is_save_as_done(self):
if self.state != 'DONE':
return False
Disk.update()
Disk.update(delete=False)
imgname = "template-%d-%d" % (self.template.id, self.id)
disks = Disk.objects.filter(name=imgname)
if len(disks) != 1:
......
var toggleDetails;
$(function() {
toggleDetails = cloud.throttle(function() {
if($(this).parent('.entry').hasClass('opened')) {
if ($(this).parent('.entry').hasClass('opened')) {
$(this).parent('.entry').removeClass('opened');
$(this).next('.details').slideUp(700);
} else {
......@@ -9,7 +9,7 @@ $(function() {
$(this).next('.details').slideDown(700);
}
})
$('a').click(function(e){
$('a').click(function(e) {
e.stopPropagation();
});
$('.delete-template').click(function(e) {
......@@ -32,19 +32,19 @@ $(function() {
});
});
});
$('#reset-key').click(function(e){
vm_confirm_popup(gettext('Are you sure about reseting store credentials?<br /> You will lose your access to your store account on your existing virtual machines!'), gettext('Reset'), function(){
$('#reset-key').click(function(e) {
vm_confirm_popup(gettext('Are you sure about reseting store credentials?<br /> You will lose your access to your store account on your existing virtual machines!'), gettext('Reset'), function() {
$.ajax({
type: 'POST',
url: '/ajax/key/reset/',
success: function(){
success: function() {
window.location.reload();
}
})
});
});
$('.entry .summary').click(toggleDetails);
if(window.navigator.userAgent.indexOf('cloud-gui') < 0) {
if (window.navigator.userAgent.indexOf('cloud-gui') < 0) {
$('.connect-vm').click(function(e) {
e.preventDefault();
e.stopPropagation();
......@@ -59,7 +59,17 @@ $(function() {
e.preventDefault();
e.stopPropagation();
var id = $(this).data('id');
var handler = arguments.callee;
var oldName = $(this).data('name');
var content = $('#vm-' + id + '-name').html();
var self=this;
$(this).unbind('click').click(function(e){
e.preventDefault();
e.stopPropagation();
$(this).unbind('click').click(handler);
$('#vm-' + id + '-name-details').show();
$('#vm-' + id + '-name').html(content);
})
$('#vm-' + id + '-name-details').hide();
$('#vm-' + id + '-name').html('<input type="text" value="' + oldName + '" />\
<input type="submit" value="' + gettext('Rename') + '" />');
......@@ -79,6 +89,7 @@ $(function() {
success: function(data) {
$('#vm-' + id + '-name-details').removeAttr('style');
$('#vm-' + id + '-name').text(data.name);
$(self).click(handler);
}
});
})
......@@ -129,6 +140,19 @@ $(function() {
})
$('#modal').show();
});
$('.edit-template').click(function(e){
e.preventDefault();
e.stopPropagation();
var id=$(this).data('id');
$.ajax({
type: 'GET',
url: '/ajax/templateEditWizard/'+id+'/',
success: function(data){
$('#modal').show();
$('#modal-container').html(data);
}
});
});
$('#shadow').click(function() {
$('#modal').hide();
$('#modal-container').html('');
......@@ -141,7 +165,7 @@ $(function() {
})
$('#modal').show();
});
$('.template-unshare').click(function(e){
$('.template-unshare').click(function(e) {
e.stopPropagation();
});
$('#old-upload').click(function(e) {
......@@ -154,7 +178,7 @@ $(function() {
$(this).css('backgroundColor', function(w) {
return 'hsla(' + (120 - parseFloat(w) / 100 * 120).toFixed(0) + ', 100%, 50%, 0.2)';
}($(this)[0].style.width));
if(parseInt($(this).css('width')) > 0) $(this).css('borderRight', function(w) {
if (parseInt($(this).css('width')) > 0) $(this).css('borderRight', function(w) {
return '1px solid hsla(' + (120 - parseFloat(w) / 100 * 120).toFixed(0) + ', 100%, 30%, 0.4)';
}($(this)[0].style.width));
});
......@@ -183,14 +207,41 @@ $(function() {
$('#new-group-members').change(updateSummary);
});
$('.hidden-password').click(function() {
if($(this).attr('type') == 'password'){
if ($(this).attr('type') == 'password') {
$(this).attr('type', 'text');
$(this).addClass('shown');
} else {
} else if (this.selectionStart - this.selectionEnd == 0) {
$(this).attr('type', 'password');
$(this).removeClass('shown');
}
});
$('.shares li').click(function(e) {
e.preventDefault();
e.stopPropagation();
e = $(this);
if (!e.hasClass('description')) {
if (e.next().is(':hidden')) {
e.next().slideDown(700);
} else {
e.next().slideUp(700);
}
} else {
e.slideUp(700);
}
});
$('.shares .edit').click(function(e) {
e.preventDefault();
e.stopPropagation();
$.ajax({
type: 'GET',
url: '/ajax/shareEdit/' + $(this).data('id') + '/',
success: function(data) {
$('#modal').show();
$('#modal-container').html(data);
}
})
})
$('.selected-summary').next().show();
/**
* Connect button new window
......@@ -200,7 +251,7 @@ $(function() {
$.get('/vm/credentials/' + id, function(data) {
$('#modal-container').html(data);
$('#modal-container .hidden-password').click(function() {
if($(this).attr('type') == 'password'){
if ($(this).attr('type') == 'password') {
$(this).attr('type', 'text');
$(this).addClass('shown');
} else {
......@@ -286,7 +337,7 @@ $(function() {
type: 'POST',
url: '/vm/' + state + '/' + id + '/',
success: function(data, b, c) {
if(state == "resume") {
if (state == "resume") {
window.location.href = '/vm/show/' + id + "/";
} else {
window.location.reload();
......@@ -345,9 +396,9 @@ $(function() {
function hide_group(id) {
var hidden_groups = JSON.parse(window.localStorage.getItem('hidden_groups')) || {};
var hidden_groups_for_user = hidden_groups[current_user] || [];
for(var i in hidden_groups_for_user) {
for (var i in hidden_groups_for_user) {
var hide = hidden_groups_for_user[i];
if(hide == id) return false;
if (hide == id) return false;
}
hidden_groups_for_user.push(id);
hidden_groups[current_user] = hidden_groups_for_user;
......@@ -358,7 +409,7 @@ $(function() {
function hide_groups() {
var hidden_groups = JSON.parse(window.localStorage.getItem('hidden_groups')) || {};
var hidden_groups_for_user = hidden_groups[current_user] || [];
for(var i in hidden_groups_for_user) {
for (var i in hidden_groups_for_user) {
var hide = hidden_groups_for_user[i];
$('#group-' + hide).hide();
}
......@@ -373,9 +424,57 @@ $(function() {
function hidden_group_count() {
var hidden_groups = JSON.parse(window.localStorage.getItem('hidden_groups')) || {};
return(hidden_groups[current_user] || []).length;
return (hidden_groups[current_user] || []).length;
}
function toggle_box(id) {
var boxes = JSON.parse(window.localStorage.getItem('hidden_boxes')) || {};
var user_boxes = boxes[current_user] || [];
for (var i in user_boxes) {
var box = user_boxes[i];
if (box == id) {
user_boxes.splice(i, 1);
boxes[current_user] = user_boxes;
window.localStorage.setItem('hidden_boxes', JSON.stringify(boxes));
$('#toggle-box-' + id).attr('src', '/static/icons/eye-half.png');
$('#toggle-box-' + id).parent().parent().parent().next().slideDown(700);
return;
}
}
user_boxes.push(id);
boxes[current_user] = user_boxes;
$('#toggle-box-' + id).attr('src', '/static/icons/eye.png');
$('#toggle-box-' + id).parent().parent().parent().next().slideUp(700);
console.log($('#toggle-box-' + id).parent().parent().parent().next()[0])
window.localStorage.setItem('hidden_boxes', JSON.stringify(boxes));
}
function box_hidden(id) {
var boxes = JSON.parse(window.localStorage.getItem('hidden_boxes')) || {};
var user_boxes = boxes[current_user] || [];
for (var i in user_boxes) {
var box = user_boxes[i];
if (box == id) {
return true;
}
}
return false;
}
if(hidden_group_count() == 0) {
$('.toggle-box').each(function() {
var id = $(this).data('id');
$(this).click(function() {
toggle_box(id);
});
if (box_hidden(id)) {
$(this).attr('src', '/static/icons/eye.png');
$(this).parent().parent().parent().next().hide();
} else {
$(this).attr('src', '/static/icons/eye-half.png');
}
})
if (hidden_group_count() == 0) {
$('#show-hidden-groups').hide();
}
......@@ -383,7 +482,7 @@ $(function() {
e.preventDefault();
e.stopPropagation();
hide_group($(this).data('id'));
if($('#show-hidden-groups').is(':hidden')) {
if ($('#show-hidden-groups').is(':hidden')) {
$('#show-hidden-groups').slideDown(700);
}
return false;
......@@ -394,7 +493,7 @@ $(function() {
show_hidden_groups();
$('#show-hidden-groups').slideUp(700);
$('#groups > li').each(function() {
if($(this).is(':hidden')) {
if ($(this).is(':hidden')) {
$(this).slideDown(700);
}
})
......@@ -429,46 +528,38 @@ $(function() {
});
$('#new-owner-form input').keyup(function() {
var timer;
return function(e){
var val=$(this).val().split(' ')[0];
return function(e) {
var val = $(this).val().split(' ')[0];
clearTimeout(timer);
timer=setTimeout(function(){
if(val.length<1) return;
timer = setTimeout(function() {
if (val.length < 1) return;
$.ajax({
type: 'POST',
data: 'q='+val,
data: 'q=' + val,
url: '/ajax/group/autocomplete/',
dataType: 'json',
success: function(data){
success: function(data) {
console.log(data);
$('#new-owner-autocomplete')[0].innerHTML='<ul>';
var el=$('#new-owner-autocomplete')[0];
for(var i in data){
var d=data[i];
el.innerHTML+='<li>'
+d.name+': '
+d.neptun
+' <input type="button" value="'+gettext('Add owner')+'" data-neptun="'+d.neptun+'" />'
+'<div class="clear"></div></li>';
}
if(data.length == 0){
el.innerHTML+='<li>'
+gettext('Unknown')+': '
+val
+' <input type="button" value="'+gettext('Add owner')+'" data-neptun="'+val+'" />'
+'<div class="clear"></div></li>';
}
el.innerHTML+='</ul>';
$(el).find('input').each(function(){
var self=this;
$(this).click(function(e){
$('#new-owner-autocomplete')[0].innerHTML = '<ul>';
var el = $('#new-owner-autocomplete')[0];
for (var i in data) {
var d = data[i];
el.innerHTML += '<li>' + d.name + ': ' + d.neptun + ' <input type="button" value="' + gettext('Add owner') + '" data-neptun="' + d.neptun + '" />' + '<div class="clear"></div></li>';
}
if (data.length == 0) {
el.innerHTML += '<li>' + gettext('Unknown') + ': ' + val + ' <input type="button" value="' + gettext('Add owner') + '" data-neptun="' + val + '" />' + '<div class="clear"></div></li>';
}
el.innerHTML += '</ul>';
$(el).find('input').each(function() {
var self = this;
$(this).click(function(e) {
e.stopPropagation();
$.ajax({
type: 'POST',
data: 'neptun='+$(self).data('neptun'),
url: '/ajax/group/'+$('#new-owner').data('gid')+'/addOwner/',
data: 'neptun=' + $(self).data('neptun'),
url: '/ajax/group/' + $('#new-owner').data('gid') + '/addOwner/',
dataType: 'json',
success: function(data){
success: function(data) {
window.location.reload();
}
})
......@@ -476,7 +567,7 @@ $(function() {
})
}
});
},1000);
}, 1000);
e.stopPropagation();
}
}());
......
......@@ -28,18 +28,13 @@ var cloud = (function(cloud) {
return cloud.convert(self.quota.rawSoft(), 1);
});
self.quota.usedBar = ko.computed(function() {
return(self.quota.rawUsed() / self.quota.rawHard() * 100).toFixed(0) + '%';
return (self.quota.rawUsed() / self.quota.rawHard() * 100).toFixed(0) + '%';
}, self);
self.quota.softPos = ko.computed(function() {
return(self.quota.rawSoft() / self.quota.rawHard() * 100).toFixed(0) + '%';
return (self.quota.rawSoft() / self.quota.rawHard() * 100).toFixed(0) + '%';
}, self);
self.sortBy = ko.observable('name');
$('#current-location select').on('change', function() {
self.sortBy($('#current-location select').val());
sortFiles();
})
/**
* Loads the parent folder
*/
......@@ -48,31 +43,31 @@ var cloud = (function(cloud) {
loadFolder(s.substr(0, s.substr(0, s.length - 1).lastIndexOf('/') + 1));
};
var sortFiles = (function() {
self.sortFiles = (function() {
self.files.sort({
name: function(a, b) {
if(a.type === b.type) {
if (a.type === b.type) {
return a.originalName.localeCompare(b.originalName);
}
if(a.type === gettext('file')) {
if (a.type === gettext('file')) {
return 1;
}
return -1;
},
date: function(a, b) {
if(a.type === b.type) {
if (a.type === b.type) {
return new Date(b.mTime).getTime() - new Date(a.mTime).getTime();
}
if(a.type === gettext('file')) {
if (a.type === gettext('file')) {
return 1;
}
return -1;
},
size: function(a, b) {
if(a.type === b.type) {
if (a.type === b.type) {
return b.originalSize - a.originalSize;
}
if(a.type === gettext('file')) {
if (a.type === gettext('file')) {
return 1;
}
return -1;
......@@ -91,7 +86,7 @@ var cloud = (function(cloud) {
url: '/ajax/store/list',
dataType: 'json',
success: function(data) {
if(!fast) {
if (!fast) {
$('.file-list .real').css({
left: 0,
position: 'relative'
......@@ -113,7 +108,27 @@ var cloud = (function(cloud) {
})
});
self.loadTopList = cloud.throttle(function() {
var showToplist = ko.observable(false);
self.toggleToplist = cloud.throttle(function() {
if (!showToplist()) {
showToplist(true);
loadToplist();
} else {
showToplist(false);
self.currentPath('/');
loadFolder('/');
}
});
self.getToplistText = ko.computed(function() {
if (!showToplist()) {
return gettext('Toplist');
} else {
return gettext('Back to the root folder');
}
})
function loadToplist() {
self.currentPath('/');
$.ajax({
type: 'POST',
......@@ -135,8 +150,8 @@ var cloud = (function(cloud) {
}, 500);
});
}
})
});
}
/**
* After loadFolder completes, this function updates the UI
......@@ -147,10 +162,10 @@ var cloud = (function(cloud) {
var added = 0;
self.notInRoot(self.currentPath().lastIndexOf('/') !== 0);
self.files([]);
for(var i in data) {
for (var i in data) {
addFile(data[i]);
}
sortFiles();
self.sortFiles();
}
/**
......@@ -159,7 +174,7 @@ var cloud = (function(cloud) {
function addFile(d) {
var viewData;
if(d.TYPE === 'D') {
if (d.TYPE === 'D') {
viewData = {
originalName: d.NAME,
originalSize: 0,
......@@ -185,8 +200,8 @@ var cloud = (function(cloud) {
ppt: /\.pptx?/,
music: /\.(wav|mp3)$/
};
for(var i in ext) {
if(d.NAME.match(ext[i])) {
for (var i in ext) {
if (d.NAME.match(ext[i])) {
type = i;
break;
}
......@@ -194,7 +209,7 @@ var cloud = (function(cloud) {
var extension;
try {
extension = d.NAME.match(/\.\w+$/)[0].substr(1);
} catch(ex) {
} catch (ex) {
extension = 'N/A';
}
viewData = {
......@@ -220,7 +235,7 @@ var cloud = (function(cloud) {
//firefox sucks :S
try {
$(e).hide().slideDown(500);
} catch(ex) {
} catch (ex) {
}
}
......@@ -230,7 +245,7 @@ var cloud = (function(cloud) {
$(e).slideUp(500, function() {
e.parentNode.removeChild(e);
});
} catch(ex) {
} catch (ex) {
e.parentNode.removeChild(e);
}
}
......@@ -241,7 +256,7 @@ var cloud = (function(cloud) {
self.download = function(item, ev) {
ev.stopPropagation();
ev.preventDefault();
if(window.navigator.userAgent.indexOf('cloud-gui') > -1) {
if (window.navigator.userAgent.indexOf('cloud-gui') > -1) {
window.location.href = 'cloudfile:' + self.currentPath() + item.originalName;
return;
}
......@@ -253,7 +268,7 @@ var cloud = (function(cloud) {
success: function(data) {
window.location.href = data.url;
}
})
});
}
/**
......@@ -264,7 +279,7 @@ var cloud = (function(cloud) {
ev.preventDefault();
$('#modal').show();
s = "";
if(item.type == gettext('file')) {
if (item.type == gettext('file')) {
s = gettext("You are removing the file <strong>%s</strong>.");
} else {
s = gettext("You are removing the folder <strong>%s</strong> (and its content).");
......@@ -303,8 +318,7 @@ var cloud = (function(cloud) {
g.stopPropagation();
self.rename(item, g);
});
})
//$(e.target).parent().parent().parent().unbind('click');
});
$(e.target).parent().parent().parent().find('.name').html('<input type="text" value="' + item.originalName + '" />\
<input type="submit" value="' + gettext('Rename') + '" />');
$(e.target).parent().parent().parent().find('.name input').click(function(f) {
......@@ -372,9 +386,10 @@ var cloud = (function(cloud) {
/**
* Uploads the specified file(s)
*/
var readfiles = cloud.delayUntil(function(file) {
var readfiles = cloud.delayUntil(function(file, next) {
console.log('read', file, next)
//1 GB file limit
if(file.size > 1024 * 1024 * 1024) {
if (file.size > 1024 * 1024 * 1024) {
$('#upload-zone').hide();
$('#upload-error').show();
$('#upload-error-size').show();
......@@ -387,26 +402,30 @@ var cloud = (function(cloud) {
}
var formData = tests.formdata ? new FormData() : null;
formData.append('data', file);
// now post a new XHR request
if(tests.formdata) {
if (tests.formdata) {
var xhr = new XMLHttpRequest();
var start = new Date().getTime();
xhr.open('POST', self.uploadURL());
xhr.onload = xhr.onerror = function() {
self.uploadProgress('0%');
self.uploadURL('/');
if (next) {
console.log('complete, next')
next();
} else {
$('.file-upload').removeClass('opened');
$('.file-upload .details').slideUp(700);
$('#upload-zone').show();
$('#upload-progress-text').hide();
self.uploadProgress('0%');
self.uploadURL('/');
loadFolder(self.currentPath());
}
if(tests.progress) {
}
if (tests.progress) {
$('#upload-zone').hide();
$('#upload-progress-text').show();
var originalUsedQuota = self.quota.rawUsed();
xhr.upload.onprogress = function(event) {
if(event.lengthComputable) {
if (event.lengthComputable) {
self.quota.rawUsed(originalUsedQuota + parseInt(event.loaded / 1024));
var complete = (event.loaded / event.total * 100 | 0);
//progress.value = progress.innerHTML = complete;
......@@ -414,16 +433,16 @@ var cloud = (function(cloud) {
var suffix = 'B KB MB GB'.split(' ');
var l = event.loaded;
var t = event.total;
for(var i = 0; l > 1024; i++) {
for (var i = 0; l > 1024; i++) {
l /= 1024;
}
l = l.toFixed(1) + ' ' + suffix[i];
for(var i = 0; t > 1024; i++) {
for (var i = 0; t > 1024; i++) {
t /= 1024;
}
t = t.toFixed(1) + ' ' + suffix[i];
var diff = new Date().getTime() - start;
if(complete < 100) {
if (complete < 100) {
$('#upload-progress-text').html(gettext('Upload') + ': ' + cloud.convert(event.loaded / diff * 1000) + '/s (' + (event.loaded / event.total * 100).toFixed(2) + '%)');
} else {
$('#upload-progress-text').html(gettext('Upload') + ': ' + gettext('done, processing...'));
......@@ -443,11 +462,30 @@ var cloud = (function(cloud) {
document.addEventListener('drop', function(e) {
e.stopPropagation();
e.preventDefault();
readfiles(e.dataTransfer.files[0]);
var len = e.dataTransfer.files.length;
var files = e.dataTransfer.files;
console.log(files);
console.log(e.dataTransfer.files);
var i = 1;
readfiles(e.dataTransfer.files[0], function() {
console.log('next', i);
next = arguments.callee;
return function() {
console.log('readnext', i, len);
if (i >= len - 2) {
console.log('end', i, len);
self.getUploadURL();
readfiles(files[i++], null);
return;
}
self.getUploadURL();
readfiles(files[i++], next());
}
}());
return false;
});
document.addEventListener('dragover', function(e) {
if(!uploadURLRequestInProgress && self.uploadURL() == '/') {
if (!uploadURLRequestInProgress && self.uploadURL() == '/') {
$('.file-upload .summary').click();
}
e.stopPropagation();
......@@ -483,6 +521,10 @@ var cloud = (function(cloud) {
$('.key').slideDown(700);
$('#keys').slideUp(700);
});
$('#current-location select').on('change', function() {
model.sortBy($('#current-location select').val());
model.sortFiles();
})
});
document.addEventListener('dragenter', function(e) {
e.stopPropagation();
......
html
{
min-height: 100%;
position: relative;
}
body
{
min-height:100%;
......@@ -15,6 +20,7 @@ body
width:970px;
text-align:left;
margin:0 auto;
padding-bottom: 100px;
}
.contentblock
......@@ -198,6 +204,13 @@ input[type=submit], input[type=button], input[type=reset]{
background: rgba(0,0,0,0.2);
};
}
input:disabled {
background-color: rgba(255,0,0,0.2);
color: #222;
&:hover {
background-color: rgba(255,0,0,0.5);
}
}
textarea {
border-radius: 2px;
......@@ -263,3 +276,29 @@ textarea::-moz-placeholder{
textarea:-ms-input-placeholder{
color: @placeholderColor;
}
body > footer {
z-index: 999;
position: absolute;
bottom: 0;
width: 100%;
text-align: center;
border-top: 1px solid #888;
box-shadow:0 0 30px rgba(0,0,0,0.4);
margin:0;
background-color: white;
}
#http-error {
margin: 20px auto;
width: 500px;
border-radius: 4px;
border: 1px solid #888;
background: #FFFF66;
box-shadow: 0 0 20px rgba(0,0,0,0.2);
padding: 20px;
}
.irasmu p {
margin-top: 20px;
}
.boxes
{
.boxes {
width:480px;
float:left;
}
.box
{
.box {
background-color:#000;
background-image:url(/static/image/hexa.png);
background-position:center 30%;
......@@ -18,43 +16,41 @@
border-top-width:30px;
margin:10px 420px 10px 10px;
padding:2px;
h3
{
h3 {
color:#fff;
text-align:center;
margin:0;
padding:3px;
}
.content
{
.content {
min-height:100px;
margin:0;
padding:5px;
}
}
.tooltip{
.tooltip {
position: relative;
z-index: 1;
.container{
.container {
margin: 10px 10px 5px 150px;
border-radius: 4px;
border: 1px solid #888;
background: #FFFF66;
box-shadow: 0 0 20px rgba(0,0,0,0.2);
p{
p {
text-align: left;
font-size: 0.8em;
word-spacing: 2px;
padding: 5px;
}
.tail{
.tail {
position: absolute;
left: 350px;
border-width: 17px;
border-style: solid;
border-color: #888 transparent transparent transparent;
&:after{
&:after {
content: "";
position: absolute;
left: -17px;
......@@ -70,9 +66,9 @@
.entry-list {
list-style-type: none;
}
.entry{
.entry {
&.opened {
.actions{
.actions {
display: block !important;
}
.summary .name .details {
......@@ -80,13 +76,13 @@
border: none;
}
}
&.small .summary{
&.small .summary {
padding: 5px;
cursor: default;
&:hover{
&:hover {
background-color: #c1c1c1;
}
.name{
.name {
background: none !important;
text-align: center;
float: none;
......@@ -116,24 +112,24 @@
background-image: url(/static/icons/key--exclamation.png);
}
}
.quota{
.quota {
left: 0;
top: 0;
z-index: 0;
position: absolute;
width: 100%;
height: 100%;
.used{
.used {
height: 100%;
position: absolute;
}
.softLimit{
.softLimit {
height: 100%;
position: absolute;
border-left: 1px solid red;
}
}
.summary{
.summary {
padding: 15px 5px;
line-height: 1.7em;
border-top: 1px solid #888;
......@@ -144,32 +140,32 @@
-moz-transition: background-color 0.3s;
-o-transition: background-color 0.3s;
transition: background-color 0.3s;
&.unfinished{
&.unfinished {
background-color: rgb(252, 252, 108);
background-image: url(/static/image/constr.png);
background-position: right top;
background-repeat: no-repeat;
&:hover{
&:hover {
background-color: rgb(236, 236, 106);
background-image: url(/static/image/constr.png);
}
}
&.selected-summary{
&.selected-summary {
background-color: rgb(124, 236, 103);
&:hover{
&:hover {
background-color: rgb(135, 211, 120);
}
}
&.public-template{
&.public-template {
background-color: rgb(167, 179, 195);
&:hover{
&:hover {
background-color: rgb(157, 169, 185);
}
}
&:hover{
&:hover {
background-color: #b1b1b1;
background-image: none;
.actions{
.actions {
display: block;
}
.name .details {
......@@ -178,11 +174,11 @@
}
}
.id{
.id {
float: right;
width: 30px;
}
.name{
.name {
float: left;
padding-left: 25px;
background-repeat: no-repeat;
......@@ -197,27 +193,27 @@
display: none;
}
}
.status{
.status {
text-align: right;
float: right;
width: 60px;
z-index: 2;
position: relative;
}
.actions{
.actions {
float: right;
margin-left: 5px;
display: none;
z-index: 2;
position: relative;
a{
a {
margin: 2px 0;
height: 16px;
width: 16px;
display: block;
float: left;
margin-left: 2px;
&:hover{
&:hover {
box-shadow: 0 0 10px rgba(0,0,0,0.4);
background-color: rgba(0,0,0,0.4);
}
......@@ -234,12 +230,12 @@
&.opened #new-folder-form {
display: block;
}
.details{
.details {
border-top: 1px solid #888;
display: none;
.container{
.container {
padding: 5px 5px;
.upload-zone{
.upload-zone {
margin: 10px;
border-radius: 10px;
border: 2px dashed #666;
......@@ -251,70 +247,73 @@
}
}
}
h3{
h3 {
font-weight: normal;
}
ul{
ul {
list-style: none;
margin: 0px 5px;
}
li{
li {
margin: 8px 0px;
padding: 3px 0px 3px 20px;
border-bottom: 1px dotted #aaa;
background-repeat: no-repeat;
background-position: 0px 4px;
&:last-child{
&:last-child {
border-bottom: none;
};
}
a{
a {
text-decoration: underline;
}
.name{
.name {
float: none;
background-image: url(/static/icons/computer.png);
}
.os-win{
background-image: url(/static/icons/windows.png)
.os-win {
background-image: url(/static/icons/windows.png);
}
.os-linux {
background-image: url(/static/icons/animal-penguin.png);
}
.os-linux{
background-image: url(/static/icons/animal-penguin.png)
.template {
background-image: url(/static/icons/document-template.png);
}
.template{
background-image: url(/static/icons/document-template.png)
.type {
background-image: url(/static/icons/box-share.png);
}
.type{
background-image: url(/static/icons/box-share.png)
.date {
background-image: url(/static/icons/calendar-day.png);
}
.date{
background-image: url(/static/icons/calendar-day.png)
.cpu {
background-image: url(/static/icons/processor.png);
}
.cpu{
background-image: url(/static/icons/processor.png)
.memory {
background-image: url(/static/icons/memory.png);
}
.memory{
background-image: url(/static/icons/memory.png)
.count {
background-image: url(/static/icons/documents-stack.png);
}
.count{
background-image: url(/static/icons/documents-stack.png)
.share-type {
background-image: url(/static/icons/calendar-day.png);
}
.value{
.value {
float: right;
width: 200px;
text-align: right;
}
.description{
.description {
font-size: inherit;
background-image: url(/static/icons/document-snippet.png);
.value{
.value {
font-size: 0.8em;
word-spacing: 3px;
width: 350px;
}
}
}
&.new .name{
&.new .name {
background-image: url(/static/icons/computer--plus.png);
}
}
......@@ -327,11 +326,11 @@
background-position: left center;
background-repeat: no-repeat;
padding-left: 18px;
&.suspend{
background-image: url(/static/icons/control-pause.png)
&.suspend {
background-image: url(/static/icons/control-pause.png);
}
&.delete{
background-image: url(/static/icons/minus-circle.png)
&.delete {
background-image: url(/static/icons/minus-circle.png);
}
}
}
......@@ -344,25 +343,25 @@
background-position: left center;
background-repeat: no-repeat;
padding-left: 18px;
&.cpu{
background-image: url(/static/icons/processor.png)
&.cpu {
background-image: url(/static/icons/processor.png);
}
&.memory{
background-image: url(/static/icons/memory.png)
&.memory {
background-image: url(/static/icons/memory.png);
}
&.credit{
background-image: url(/static/icons/point.png)
&.credit {
background-image: url(/static/icons/point.png);
}
}
}
.file-list{
.file-list {
list-style: none;
max-height: 400px;
.name{
.name {
float: left;
}
.info{
.info {
float: right;
width: 65px;
text-align: right;
......@@ -377,19 +376,19 @@
}
#file-list {
overflow-y: scroll;
li:nth-child(3) .summary{
li:nth-child(3) .summary {
border-top: none;
}
li:nth-child(2) .summary{
li:nth-child(2) .summary {
border-top: none;
}
li:nth-child(1) .summary{
li:nth-child(1) .summary {
border-top: none;
border-bottom: 1px solid #888
}
}
#current-location{
.summary{
#current-location {
.summary {
border-bottom: 1px solid #888;
height: 25px;
.name {
......@@ -453,55 +452,55 @@
.filetype-jump-out {
background-image: url(/static/icons/arrow-curve-090.png);
}
.vm-on{
.vm-on {
background-image: url(/static/icons/computer-cloud.png);
}
.vm-off{
.vm-off {
background-image: url(/static/icons/computer-off.png);
}
#template .entry .summary .name{
background-image: url(/static/icons/document-template.png)
#template .entry .summary .name {
background-image: url(/static/icons/document-template.png);
}
#template .entry .public-template .name{
background-image: url(/static/icons/blue-document-share.png)
#template .entry .public-template .name {
background-image: url(/static/icons/blue-document-share.png);
}
#new-template-button .name{
background-image: url(/static/icons/document--plus.png) !important
#new-template-button .name {
background-image: url(/static/icons/document--plus.png) !important;
}
.wm-list.modal{
.wm-list.modal {
border-radius: 4px;
border: 1px solid #666;
}
.wm-list.modal input{
.wm-list.modal input {
padding: 2px 10px;
}
.wm-list.modal .wm:nth-child(1) .summary{
.wm-list.modal .wm:nth-child(1) .summary {
border-top: none;
}
#template{
#template {
.entry {
.template-details{
.template-details {
margin: 0;
padding: 0;
border-top: 1px solid #888;
display: none;
ul{
ul {
list-style-type: none;
}
li{
li {
padding-left: 10px;
border-top: 1px solid #aaa;
position: relative;
&:first-child{
&:first-child {
border-top: none;
};
.status{
.status {
float: right;
padding: 0 5px;
}
.group-name{
.group-name {
float: left;
line-height: 1.5em;
z-index: 2;
......@@ -525,7 +524,7 @@ table {
&:hover {
background-color: rgba(0,0,0,0.1);
};
td,th {
td, th {
padding: 5px;
}
td {
......@@ -591,7 +590,7 @@ table {
-moz-transition: background-color 0.3s;
-o-transition: background-color 0.3s;
transition: background-color 0.3s;
&:hover{
&:hover {
background-color: rgba(0,0,0,0.1);
border: 1px solid #666;
input {
......@@ -611,6 +610,19 @@ table {
height: 30px;
right: -5px;
}
&.description {
display: none;
height: default;
font-size: 0.8em;
margin-left: 20px;
}
.edit {
margin: 0 2px;
img:hover {
box-shadow: 0 0 10px rgba(0,0,0,0.4);
background-color: rgba(0,0,0,0.4);
}
}
}
}
......@@ -632,13 +644,22 @@ table {
margin:20px;
display: none;
}
&:hover .boxhelp-box {
.help:hover .boxhelp-box {
display: block;
}
.help {
img {
cursor: default;
}
}
.icon {
display: block;
float: right;
}
img {
margin: 3px;
cursor: pointer;
}
}
#new-owner-autocomplete {
......
body{min-height:100%;font-family:'Titillium Web',sans-serif;font-size:.9em;background:#dadada url(/static/image/site_bgr.png) repeat-x;background-position:80px 0;margin:0;padding:0;overflow:scroll}#content{width:970px;text-align:left;margin:0 auto}.contentblock{background-color:#ccc;border-radius:4px;border:1px solid #aaa;box-shadow:0 0 30px rgba(0,0,0,0.3);margin:20px}.contentblock p,.contentblock dl{margin:0;padding:5px}.contentblock h2{background-color:#000;background-image:url(/static/image/hexabar.png);background-position:right center;background-repeat:no-repeat;border-radius:4px;border-bottom-left-radius:0;border-bottom-right-radius:0;color:#eee;font-size:1.5em;margin-top:0;padding:10px;position:relative}.contentblock.wide{margin-right:30px}.contentblock.note{background-color:#ffc}.contentblock ol{margin-left:2em}.contentblock ol li.done{color:#aaa}.big{font-size:2em}ul.messagelist{text-align:left;margin:0;padding:0 0 5px}ul.messagelist li{font-size:12px;display:block;border-bottom:1px solid #ddd;color:#666;background:#ffc url(/static/admin/img/icon_success.gif) 5px .3em no-repeat;margin:0 0 3px;padding:4px 5px 4px 25px}ul.messagelist li.warning{background-image:url(/static/admin/img/icon_alert.gif)}ul.messagelist li.error{background-image:url(/static/admin/img/icon_error.gif)}input.validated{padding-right:15px;background-image:url(/static/admin/img/icon_success.gif);background-repeat:no-repeat;background-position:right center}input.validated.error{background:#fcc url(/static/admin/img/icon_error.gif) right center no-repeat;padding-right:15px}.errornote{font-size:12px!important;display:block;border:1px solid red;color:red;background:#ffc url(/static/admin/img/icon_error.gif) 5px .3em no-repeat;margin:0 0 3px;padding:4px 5px 4px 25px}.errorlist li{font-size:12px!important;display:block;border:1px solid red;color:#FFF;background:#f00 url(/static/admin/img/icon_alert.gif) 5px .3em no-repeat;margin:0 0 3px;padding:4px 5px 4px 25px}.errorlist li a{color:#FFF;text-decoration:underline}td ul.errorlist li{margin:0!important}.errors{background:#ffc}.errors input,.errors select,.errors textarea{border:1px solid red}div.system-message{background:#ffc;font-size:.8em;margin:10px;padding:6px 8px}div.system-message p.system-message-title{color:red;background:#ffc url(/static/admin/img/icon_error.gif) 5px .3em no-repeat;margin:0;padding:4px 5px 4px 25px}small{font-size:.8em}input{border-radius:2px;border:1px solid #777;padding:2px;margin:1px 5px;background:rgba(0,0,0,0.1);font-family:'Titillium Web',sans-serif;outline:0;box-shadow:inset 0 0 10px rgba(0,0,0,0.2),0 0 5px rgba(0,0,0,0.2);-webkit-transition:box-shadow .5s;-moz-transition:box-shadow .5s;-o-transition:box-shadow .5s;transition:box-shadow .5s}input:hover{border:1px solid #666;box-shadow:inset 0 0 10px rgba(0,0,0,0.2),0 0 5px rgba(255,255,0,0.5)}input:focus{border:1px solid #555;box-shadow:inset 0 0 10px rgba(0,0,0,0.2),0 0 10px rgba(255,255,0,0.8)}input[type=submit],input[type=button],input[type=reset]{border:1px solid #777;cursor:pointer;box-shadow:0 0 5px rgba(0,0,0,0.2);-webkit-transition:background .5s;-moz-transition:background .5s;-o-transition:background .5s;transition:background .5s}input[type=submit]:hover,input[type=button]:hover,input[type=reset]:hover{background:rgba(0,0,0,0.2)}textarea{border-radius:2px;border:1px solid #777;padding:5px;margin:10px 5px;width:300px;height:100px;background:rgba(0,0,0,0.1);font-family:'Titillium Web',sans-serif;outline:0;box-shadow:inset 0 0 10px rgba(0,0,0,0.2),0 0 5px rgba(0,0,0,0.2);-webkit-transition:box-shadow .5s;-moz-transition:box-shadow .5s;-o-transition:box-shadow .5s;transition:box-shadow .5s}textarea:hover{border:1px solid #666;box-shadow:inset 0 0 10px rgba(0,0,0,0.2),0 0 5px rgba(255,255,0,0.5)}textarea:focus{border:1px solid #555;box-shadow:inset 0 0 10px rgba(0,0,0,0.2),0 0 10px rgba(255,255,0,0.8)}.hilight{background-color:#ff6}.hidden-password{padding-right:25px;background-image:url(/static/icons/eye-half.png);background-repeat:no-repeat;background-position:right center;cursor:pointer}.hidden-password.shown{background-image:url(/static/icons/eye.png)}input::-webkit-input-placeholder{color:#444}input:-moz-placeholder{color:#444}input::-moz-placeholder{color:#444}input:-ms-input-placeholder{color:#444}textarea::-webkit-input-placeholder{color:#444}textarea:-moz-placeholder{color:#444}textarea::-moz-placeholder{color:#444}textarea:-ms-input-placeholder{color:#444}#header{height:80px;background-color:#072c61;background-image:url(/static/image/bme_feher2.png);background-repeat:no-repeat;background-position:20px 18px;border-bottom:3px solid #0b4599;box-shadow:0 0 30px rgba(0,0,0,0.4);margin:0;padding:0 0 0 200px}#header h1{font-size:2em;line-height:80px;float:left;margin:0;padding:0 1em}#header h1 a{color:#fff;text-decoration:none}#loginblock{position:absolute;right:0;top:0;background-color:#000;background-image:url(/static/image/hexabar.png);background-position:center center;border-radius:0 0 0 10px;color:#fff;font-weight:700;margin:0;padding:7px}#loginblock a{color:#fff;text-decoration:underline}#loginblock a:hover{color:#aaa}.boxes{width:480px;float:left}.box{background-color:#000;background-image:url(/static/image/hexa.png);background-position:center 30%;background-repeat:no-repeat;color:#fff;font-weight:700;line-height:1.5em;width:400px;border-radius:10px;border-top-width:30px;margin:10px 420px 10px 10px;padding:2px}.box h3{color:#fff;text-align:center;margin:0;padding:3px}.box .content{min-height:100px;margin:0;padding:5px}.tooltip{position:relative;z-index:1}.tooltip .container{margin:10px 10px 5px 150px;border-radius:4px;border:1px solid #888;background:#ff6;box-shadow:0 0 20px rgba(0,0,0,0.2)}.tooltip .container p{text-align:left;font-size:.8em;word-spacing:2px;padding:5px}.tooltip .container .tail{position:absolute;left:350px;border-width:17px;border-style:solid;border-color:#888 transparent transparent transparent}.tooltip .container .tail:after{content:"";position:absolute;left:-17px;top:-18px;border-width:17px;border-style:solid;border-color:#ff6 transparent transparent transparent}.entry-list{list-style-type:none}.entry.opened .actions{display:block!important}.entry.opened .summary .name .details{display:inline;border:0}.entry.small .summary{padding:5px;cursor:default}.entry.small .summary:hover{background-color:#c1c1c1}.entry.small .summary .name{background:none!important;text-align:center;float:none}.entry.small-row .summary{padding:5px}.entry.small-row .summary:hover{background-color:#b1b1b1}.entry.small-row .summary .name{float:none}.entry.key .name{background-image:url(/static/icons/key.png)}.entry.key textarea{margin:10px;width:93%}.entry.key #new-key .name{background-image:url(/static/icons/key--plus.png)}.entry.key #reset-key .name{background-image:url(/static/icons/key--exclamation.png)}.entry .quota{left:0;top:0;z-index:0;position:absolute;width:100%;height:100%}.entry .quota .used{height:100%;position:absolute}.entry .quota .softLimit{height:100%;position:absolute;border-left:1px solid red}.entry .summary{padding:15px 5px;line-height:1.7em;border-top:1px solid #888;cursor:pointer;background-color:#c1c1c1;position:relative;-webkit-transition:background-color .3s;-moz-transition:background-color .3s;-o-transition:background-color .3s;transition:background-color .3s}.entry .summary.unfinished{background-color:#fcfc6c;background-image:url(/static/image/constr.png);background-position:right top;background-repeat:no-repeat}.entry .summary.unfinished:hover{background-color:#ecec6a;background-image:url(/static/image/constr.png)}.entry .summary.selected-summary{background-color:#7cec67}.entry .summary.selected-summary:hover{background-color:#87d378}.entry .summary.public-template{background-color:#a7b3c3}.entry .summary.public-template:hover{background-color:#9da9b9}.entry .summary:hover{background-color:#b1b1b1;background-image:none}.entry .summary:hover .actions{display:block}.entry .summary:hover .name .details{display:inline;border:0}.entry .summary .id{float:right;width:30px}.entry .summary .name{float:left;padding-left:25px;background-repeat:no-repeat;background-position:left center;z-index:2;position:relative;height:24px}.entry .summary .name.filetype-new-folder{float:left}.entry .summary .name .details{display:none}.entry .summary .status{text-align:right;float:right;width:60px;z-index:2;position:relative}.entry .summary .actions{float:right;margin-left:5px;display:none;z-index:2;position:relative}.entry .summary .actions a{margin:2px 0;height:16px;width:16px;display:block;float:left;margin-left:2px}.entry .summary .actions a:hover{box-shadow:0 0 10px rgba(0,0,0,0.4);background-color:rgba(0,0,0,0.4)}.entry .summary #new-folder-form{float:right;margin-left:5px;display:none;z-index:2;position:relative}.entry.opened #new-folder-form{display:block}.entry .details{border-top:1px solid #888;display:none}.entry .details .container{padding:5px 5px}.entry .details .container .upload-zone{margin:10px;border-radius:10px;border:2px dashed #666;text-align:center;font-size:.8em;padding:10px}.entry .details .container .upload-zone p{padding:0}.entry .details h3{font-weight:normal}.entry .details ul{list-style:none;margin:0 5px}.entry .details li{margin:8px 0;padding:3px 0 3px 20px;border-bottom:1px dotted #aaa;background-repeat:no-repeat;background-position:0 4px}.entry .details li:last-child{border-bottom:0}.entry .details a{text-decoration:underline}.entry .details .name{float:none;background-image:url(/static/icons/computer.png)}.entry .details .os-win{background-image:url(/static/icons/windows.png)}.entry .details .os-linux{background-image:url(/static/icons/animal-penguin.png)}.entry .details .template{background-image:url(/static/icons/document-template.png)}.entry .details .type{background-image:url(/static/icons/box-share.png)}.entry .details .date{background-image:url(/static/icons/calendar-day.png)}.entry .details .cpu{background-image:url(/static/icons/processor.png)}.entry .details .memory{background-image:url(/static/icons/memory.png)}.entry .details .count{background-image:url(/static/icons/documents-stack.png)}.entry .details .value{float:right;width:200px;text-align:right}.entry .details .description{font-size:inherit;background-image:url(/static/icons/document-snippet.png)}.entry .details .description .value{font-size:.8em;word-spacing:3px;width:350px}.entry.new .name{background-image:url(/static/icons/computer--plus.png)}#new-share .type-summary.type-summary,.share-type .value.type-summary{font-size:.8em;text-align:right}#new-share .type-summary span,.share-type .value span{background-position:left center;background-repeat:no-repeat;padding-left:18px}#new-share .type-summary span.suspend,.share-type .value span.suspend{background-image:url(/static/icons/control-pause.png)}#new-share .type-summary span.delete,.share-type .value span.delete{background-image:url(/static/icons/minus-circle.png)}#template-wizard .size-summary.size-summary,.type .value.size-summary{font-size:.8em;text-align:right}#template-wizard .size-summary span,.type .value span{background-position:left center;background-repeat:no-repeat;padding-left:18px}#template-wizard .size-summary span.cpu,.type .value span.cpu{background-image:url(/static/icons/processor.png)}#template-wizard .size-summary span.memory,.type .value span.memory{background-image:url(/static/icons/memory.png)}#template-wizard .size-summary span.credit,.type .value span.credit{background-image:url(/static/icons/point.png)}.file-list{list-style:none;max-height:400px}.file-list .name{float:left}.file-list .info{float:right;width:65px;text-align:right;font-size:.8em}.file-list select{position:absolute;left:10px;top:5px;z-index:10}#file-list{overflow-y:scroll}#file-list li:nth-child(3) .summary{border-top:0}#file-list li:nth-child(2) .summary{border-top:0}#file-list li:nth-child(1) .summary{border-top:0;border-bottom:1px solid #888}#current-location .summary{border-bottom:1px solid #888;height:25px}#current-location .summary .name{position:absolute;left:100px;text-align:left}.filetype-c{background-image:url(/static/icons/document-visual-studio.png)}.filetype-text{background-image:url(/static/icons/document.png)}.filetype-image{background-image:url(/static/icons/document-image.png)}.filetype-zip{background-image:url(/static/icons/folder-zipper.png)}.filetype-pdf{background-image:url(/static/icons/document-pdf.png)}.filetype-doc{background-image:url(/static/icons/document-word.png)}.filetype-excel{background-image:url(/static/icons/document-excel.png)}.filetype-csv{background-image:url(/static/icons/document-excel-csv.png)}.filetype-php{background-image:url(/static/icons/document-php.png)}.filetype-tex{background-image:url(/static/icons/document-tex.png)}.filetype-ppt{background-image:url(/static/icons/document-powerpoint.png)}.filetype-music{background-image:url(/static/icons/document-music.png)}.filetype-movie{background-image:url(/static/icons/document-film.png)}.filetype-folder{background-image:url(/static/icons/folder.png)}.toplist{background-image:url(/static/icons/arrow-circle-double.png)}.filetype-up{background-image:url(/static/icons/upload-cloud.png)}.filetype-new-folder{background-image:url(/static/icons/folder--plus.png)}.filetype-jump-out{background-image:url(/static/icons/arrow-curve-090.png)}.vm-on{background-image:url(/static/icons/computer-cloud.png)}.vm-off{background-image:url(/static/icons/computer-off.png)}#template .wm .summary .name{background-image:url(/static/icons/document-template.png)}#template .wm .public-template .name{background-image:url(/static/icons/blue-document-share.png)}#new-template-button .name{background-image:url(/static/icons/document--plus.png)!important}.wm-list.modal{border-radius:4px;border:1px solid #666}.wm-list.modal input{padding:2px 10px}.wm-list.modal .wm:nth-child(1) .summary{border-top:0}#template .entry .template-details{margin:0;padding:0;border-top:1px solid #888;display:none}#template .entry .template-details ul{list-style-type:none}#template .entry .template-details li{padding-left:10px;border-top:1px solid #aaa;position:relative}#template .entry .template-details li:first-child{border-top:0}#template .entry .template-details li .status{float:right;padding:0 5px}#template .entry .template-details li .group-name{float:left;line-height:1.5em;z-index:2;position:relative}#vm-credentials .content,#ports .content{padding:15px}table{width:100%;border-collapse:collapse}table tr{width:100%}table tr:hover{background-color:rgba(0,0,0,0.1)}table tr td,table tr th{padding:5px}table tr td{width:150px}#groups .entry .summary .name{background-image:url(/static/icons/users.png)}#groups #new-group .summary .name{background-image:url(/static/icons/user--plus.png)}#groups #show-hidden-groups .summary .name{background-image:url(/static/icons/eye.png)}#group-members .summary .name,#group-owners .summary .name{background-image:url(/static/icons/user.png);float:left}#new-member .name,#new-owner .name{background-image:url(/static/icons/user--plus.png)!important;float:left}#new-member #new-member-form,#new-owner #new-member-form,#new-member #new-owner-form,#new-owner #new-owner-form{float:right;margin-left:5px;display:none;z-index:2;position:relative}.shares{margin:5px;list-style:none}.shares li{overflow:hidden;border-radius:2px;border:1px solid #888;height:30px;position:relative;margin:5px 0;line-height:30px;padding-left:10px;background-color:rgba(0,0,0,0.05);-webkit-transition:background-color .3s;-moz-transition:background-color .3s;-o-transition:background-color .3s;transition:background-color .3s}.shares li:hover{background-color:rgba(0,0,0,0.1);border:1px solid #666}.shares li:hover input{border-left:1px solid #666}.shares li form{position:relative}.shares li input{border:0;border-radius:0;border-left:1px solid #888;box-shadow:none;position:relative;top:-1px;height:30px;right:-5px}.boxhelp{position:relative}.boxhelp .boxhelp-box{color:#000;position:absolute;left:-100px;width:500px;z-index:1000000;font-size:.7em;background-color:#ffc;border-radius:4px;border:1px solid #aaa;box-shadow:0 0 30px rgba(0,0,0,0.3);margin:20px;display:none}.boxhelp:hover .boxhelp-box{display:block}.boxhelp .icon{display:block;float:right}#modal{top:0;position:absolute;width:100%;height:100%;z-index:999}#shadow{position:fixed;height:100%;width:100%;background-color:rgba(0,0,0,0.6)}#modal-container{min-width:500px;position:fixed;left:50%;top:100px;margin-left:-270px;margin-top:0;min-height:50px;background-color:#fff;border-radius:4px;padding:20px;box-shadow:0 0 30px rgba(0,0,0,0.4);border:1px solid #333;max-height:60%;overflow:auto}#modal-container .container{max-height:400px;overflow:auto;border-radius:2px;border:1px solid #888;background-color:#ccc}#modal-container ul{list-style:none}#modal-container ul li:first-child .summary{border:0}.wizard li{border-bottom:1px dotted #999}.wizard label{display:inline-block;padding:3px;margin:10px 5px}.wizard h2{margin:10px 0}.wizard .progress{text-align:center;position:relative;width:100%;height:15px}.wizard .progress .bar{height:20px;background-color:#66c400;border-right:1px solid #468600}.wizard .progress .bar-container{border:1px solid #666;box-shadow:0 0 20px rgba(0,0,0,0.2);border-radius:4px;height:20px;position:absolute;width:500px}.wizard .progress h3{width:100%;position:absolute}.wizard input[type=text],.wizard input[type=number],.wizard select{display:block;float:right;margin-top:8px}.wizard input[type=number]{width:4em}.wizard textarea{float:right;text-align:right}.wizard nav{margin-top:15px}.wizard nav a{text-decoration:underline;display:block}.wizard nav .prev{float:left}.wizard nav .next{float:right}.wizard ul.radio{float:right}.wizard ul.radio label{float:left;margin:0}.wizard .radio li{float:left;padding:5px;margin:5px 3px;border-bottom:none!important}.wizard .size-summary{margin:10px}#new-template-name input{margin:10px 5px}*{margin:0;padding:0}.clear{clear:both}abbr{border-bottom:1px dotted #666}a:link,a:visited{color:black}
\ No newline at end of file
from celery.task import Task, PeriodicTask
import logging
import celery
import os
import sys
import time
from django.core.mail import send_mail
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) )
{% extends "base.html" %}
{% load i18n %}
{% get_current_language as LANGUAGE_CODE %}
<!doctype html>
<html lang="{{LANGUAGE_CODE}}">
<head>
<meta charset="UTF-8">
<title>404 - {% trans ":(" %}</title>
</head>
<body>
{% block content %}
<div id="http-error">
<h1>404 - {% trans ":(" %}</h1>
</body>
</html>
<p>
{% trans "The requested page does not exists... Please go away..." %}
</p>
</div>
{% endblock %}
{% extends "base.html" %}
{% load i18n %}
{% get_current_language as LANGUAGE_CODE %}
{% block content %}
<div id="http-error">
<h1>500 - {% trans ":(" %}</h1>
<p>
{% trans "Internal Server Error... Please leave the server alone..." %}
</p>
</div>
{% endblock %}
<!DOCTYPE html>
{% load i18n %}
{% load staticfiles %}
{% get_current_language as lang %}
<html lang="{{lang}}">
<head>
<title>{% block title %}IK Cloud{% endblock %}</title>
<link href="https://fonts.googleapis.com/css?family=Titillium+Web&amp;subset=latin,latin-ext" rel="stylesheet" type="text/css">
<link rel="icon" type="image/png" href="/static/favicon.png" />
<link rel="stylesheet/less" href="/static/style/style.less" />
<link href="https://fonts.googleapis.com/css?family=Titillium+Web&amp;subset=latin,latin-ext" rel="stylesheet" type="text/css" />
<link rel="icon" type="image/png" href="{% static "favicon.png" %}" />
{% if DEBUG %}<link rel="stylesheet/less" href="{% static "style/style.less" %}" />{% else %}
<link href="{% static "style/style.css" %}" rel="stylesheet" type="text/css" />{% endif %}
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8" />
<script src="/static/script/jquery.min.js"></script>
<script src="{% static "script/jquery.min.js" %}"></script>
<script type="text/javascript" src="{% url django.views.i18n.javascript_catalog %}"></script>
<script type="text/javascript">
window.localStorage.removeItem('https://cloud.ik.bme.hu/static/style/style.less:timestamp');
{% if DEBUG %}window.localStorage.removeItem('https://cloud.ik.bme.hu/static/style/style.less:timestamp');{% endif %}
var current_user={{user.id}};
</script>
<script src="/static/script/less.min.js"></script>
<script src="/static/script/knockout.min.js"></script>
<script type="text/javascript" src="/static/script/util.js"></script>
<script type="text/javascript" src="/static/script/cloud.js"></script>
{% if DEBUG %}<script src="{% static "script/less.min.js" %}"></script>{% endif %}
<script src="{% static "script/knockout.min.js" %}"></script>
{% if DEBUG %}<script type="text/javascript" src="{% static "script/util.js" %}"></script>
{% else %}<script type="text/javascript" src="{% static "script/util.min.js" %}"></script>
{% endif %}
{% if DEBUG %}<script type="text/javascript" src="{% static "script/cloud.js" %}"></script>
{% else %}<script type="text/javascript" src="{% static "script/cloud.min.js" %}"></script>
{% endif %}
{{ form.media }}
{% block js %}{% endblock %}
</head>
......@@ -26,25 +32,27 @@
{% block login %}
<div id="loginblock"><p>
{% if user.is_authenticated %}
Bejelentkezve: {{ user.username }}.
<a href="/logout/">Kijelentkezés</a>.
{% trans "Logged in:" %} {{ user.username }}.
<a href="{% url logout %}">{% trans "Logout" %}</a>.
{% if user.is_staff %}
<a href="/admin/">Admin</a>.
<a href="{% url admin:index %}">{% trans "Admin" %}</a>.
{% endif %}
{% else %}
<a href="/login/">Bejelentkezés</a>.
<a href="{% url login %}">{% trans "Login" %}</a>.
{% endif %}
{% if user.is_authenticated %}
{% if lang == 'hu' %}
<a href="/language/en/">In English</a>.
<a href="{% url school.views.language "en" %}">In English</a>.
{% else %}
<a href="/language/hu/">Magyarul</a>.
<a href="{% url school.views.language "hu" %}">Magyarul</a>.
{% endif %}
{% endif %}
</p>
</div>
{% endblock %}
{% block header %}
{% block header_title %}
<h1><a href="/">IK Cloud</a></h1>
<h1><a href="{% url one.views.index %}">IK Cloud</a></h1>
{% endblock %}
{% endblock %}
</div>
......@@ -61,11 +69,27 @@
{% block content %}{% endblock %}
<div class="clear"></div>
</div>
<footer>
<a href="/sites/legal/">{% trans "Legal notice" %}</a> |
<a href="/sites/policy/">{% trans "Policy" %}</a> |
<a href="/sites/help/">{% trans "Help" %}</a> |
<a href="/sites/support/">{% trans "Support" %}</a>
</footer>
<div id="modal" style="display: none">
<div id="shadow"></div>
<div id="modal-container">
</div>
</div>
<script type="text/javascript">
var _gaq = _gaq || [];
_gaq.push(['_setAccount', 'UA-39125666-1']);
_gaq.push(['_trackPageview']);
(function() {
var ga = document.createElement('script'); ga.type = 'text/javascript'; ga.async = true;
ga.src = ('https:' == document.location.protocol ? 'https://ssl' : 'http://www') + '.google-analytics.com/ga.js';
var s = document.getElementsByTagName('script')[0]; s.parentNode.insertBefore(ga, s);
})();
</script>
</body>
</html>
{% extends "box/base/box.html" %}
{% load i18n %}
{% load l10n %}
{% load staticfiles %}
{% get_current_language as LANGUAGE_CODE %}
{% block title %}
......@@ -8,8 +9,9 @@
{% endblock title %}
{% block boxhelp %}
<div class="boxhelp">
<div class="help">
<div class="icon">
<img src="/static/icons/information-frame.png" alt="{% trans "Help" %}" />
<img src="{% static "icons/information-frame.png" %}" alt="{% trans "Help" %}" />
</div>
<div class="boxhelp-box">
<p>{% blocktrans %}This is your global data store.{% endblocktrans %}</p>
......@@ -24,6 +26,10 @@
WinSCP) to access your files at {{serv}}. You will need to register a
public key bellow.{% endblocktrans %}</p>
</div>
</div>
<div class="icon">
<img src="" alt="toggle" title="{% trans "Show/hide box" %}" class="toggle-box" data-id="files" id="toggle-box-files"/>
</div>
</div>
{% endblock %}
......@@ -80,7 +86,7 @@
</li>
<li class="entry small-row">
<div class="summary" id="new-folder">
<div class="name toplist" data-bind="click: loadTopList">{% trans "Toplist" %}</div>
<div class="name toplist" data-bind="click: toggleToplist, text: getToplistText"></div>
<div class="clear"></div>
</div>
</li>
......@@ -100,7 +106,7 @@
</div>
<div class="details">
<div class="container">
<form style="padding-bottom: 10px" action="/key/add/" method="POST">
<form style="padding-bottom: 10px" action="{% url one.views.key_add %}" method="POST">
{% csrf_token %}
<textarea style="margin-bottom: 5px" name="key" placeholder="{% trans "Public key in OpenSSH format" %}"></textarea><br />
<input type="submit" style="margin-left: 10px;" value="{% trans "Save" %}" />
......@@ -139,7 +145,7 @@
<p id="upload-error-unknown" style="display: none"></p>
</div>
<div style="display: none" class="upload-zone" id="old-upload-form">
<form action="/" method="POST" data-bind="attr: {action: uploadURL}" enctype="multipart/form-data">
<form action="{% url one.views.home %}" method="POST" data-bind="attr: {action: uploadURL}" enctype="multipart/form-data">
<input type="file" name="data" />
<input type="submit" value="Feltöltés" />
</form>
......
{% extends "box/base/entry.html" %}
{% load i18n %}
{% load staticfiles %}
{% get_current_language as LANGUAGE_CODE %}
{% block summary %}
......@@ -8,13 +9,13 @@
<div class="info" data-bind="text: size"></div>
<div class="actions">
<a href="#" data-bind="click: $parent.rename, clickBubble: false">
<img src="/static/icons/pencil.png" alt="{% trans "rename" %}" />
<img src="{% static "icons/pencil.png" %}" alt="{% trans "rename" %}" />
</a>
<a href="#" data-bind="click: $parent.delete, clickBubble: false">
<img src="/static/icons/minus-circle.png" alt="{% trans "remove" %}" />
<img src="{% static "icons/minus-circle.png" %}" alt="{% trans "remove" %}" />
</a>
<a href="#" data-bind="click: $parent.download, clickBubble: false">
<img src="/static/icons/download-cloud.png" alt="{% trans "download" %}" />
<img src="{% static "icons/download-cloud.png" %}" alt="{% trans "download" %}" />
</a>
</div>
<div class="clear"></div>
......
{% extends "box/base/entry.html" %}
{% load i18n %}
{% load staticfiles %}
{% get_current_language as LANGUAGE_CODE %}
{% block content %}
......@@ -15,7 +16,7 @@
</div>
<div class="actions">
<a href="#" class="remove delete-key" data-id="{{key.id}}">
<img src="/static/icons/minus-circle.png" alt="{% trans 'Remove' %}" />
<img src="{% static "icons/minus-circle.png" %}" alt="{% trans 'Remove' %}" />
</a>
</div>
<div class="clear"></div>
......
{% extends "box/base/box.html" %}
{% load i18n %}
{% load l10n %}
{% load staticfiles %}
{% get_current_language as LANGUAGE_CODE %}
{% block title %}
......@@ -9,8 +10,9 @@
{% block boxhelp %}
<div class="boxhelp">
<div class="help">
<div class="icon">
<img src="/static/icons/information-frame.png" alt="{% trans "Help" %}" />
<img src="{% static "icons/information-frame.png" %}" alt="{% trans "Help" %}" />
</div>
<div class="boxhelp-box">
<p>{% blocktrans %}This is the list of your own templates.{% endblocktrans %}</p>
......@@ -19,6 +21,10 @@
machine, and it will be ready to run by your students in minutes.
{% endblocktrans %}</p>
</div>
</div>
<div class="icon">
<img src="" alt="toggle" title="{% trans "Show/hide box" %}" class="toggle-box" data-id="templates" id="toggle-box-templates"/>
</div>
</div>
{% endblock %}
......@@ -53,17 +59,17 @@
<div class="summary public-template">
<div class="name">
{{t.name}}
<img src="/static/icons/lock-small.png" alt="{% trans "locked" %}"
<img src="{% static "icons/lock-small.png" %}" alt="{% trans "locked" %}"
title="{% trans "This is a shared template." %}" />
</div>
<div class="status">{{t.state}}</div>
<div class="actions">
{% if t.state == 'READY' %}
<a href="#" class="try-template-button" data-id="{{t.id}}" title="{% trans "Try" %}">
<img src="/static/icons/control.png" alt="{% trans "Start" %}"/>
<img src="{% static "icons/control.png" %}" alt="{% trans "Start" %}"/>
</a>
<a href="#" class="template-share" data-id="{{t.id}}" data-gid="{{group.id}}" title="{% trans "Share" %}">
<img src="/static/icons/user-share.png" alt="{% trans "Share" %}" />
<img src="{% static "icons/user-share.png" %}" alt="{% trans "Share" %}" />
</a>
{% endif %}
</div>
......@@ -75,14 +81,24 @@
<div class="quota">
<div class="used" style="width: {{ i.get_instance_pc|unlocalize }}%"></div>
</div>
<form action="/vm/unshare/{{i.id}}/" method="post">
<form action="{% url one.views.vm_unshare i.id %}" method="post">
<span title="{{i.name}}">{{i.name|truncatechars:20}}</span>
({{i.get_running}}/{{i.instance_limit}})
({{i.get_running}}/{{i.instance_limit}}) {{i.type}}
<a href="#" class="edit" data-id="{{i.id}}">
<img src="{% static "icons/pencil.png" %}" alt="{% trans "Edit" %}" title="{% trans "Edit" %}" />
</a>
{% csrf_token %}
<input type="submit" class="template-unshare" value="{% trans "Delete" %}" style="float: right"/>
</form>
<div class="clear"></div>
</li>
<li class="description{% if not i.description %} empty{% endif %}">
{% if i.description %}
{{i.description}}
{% else %}
{% trans "No description available" %}
{% endif %}
</li>
{% endfor %}
</ul>
{% endif %}
......
{% extends "box/base/summary.html" %}
{% load i18n %}
{% load l10n %}
{% load staticfiles %}
{% get_current_language as LANGUAGE_CODE %}
{% block content %}
......@@ -13,14 +14,24 @@
<div class="quota">
<div class="used" style="width: {{ i.get_instance_pc|unlocalize }}%"></div>
</div>
<form action="/vm/unshare/{{i.id}}/" method="post">
<form action="{% url one.views.vm_unshare i.id %}" method="post">
<span title="{{i.name}}">{{i.name|truncatechars:20}}</span>
({{i.get_running}}/{{i.instance_limit}})
({{i.get_running}}/{{i.instance_limit}}) {{i.type}}
<a href="#" class="edit" data-id="{{i.id}}">
<img src="{% static "icons/pencil.png" %}" alt="{% trans "Edit" %}" title="{% trans "Edit" %}" />
</a>
{% csrf_token %}
<input class="template-unshare" type="submit" value="{% trans "Delete" %}" style="float: right"/>
</form>
<div class="clear"></div>
</li>
<li class="description{% if not i.description %} empty{% endif %}">
{% if i.description %}
{{i.description}}
{% else %}
{% trans "No description available" %}
{% endif %}
</li>
{% endfor %}
</ul>
{% endif %}
......@@ -32,25 +43,25 @@
{% endblock %}
{% block status %}
{{vm.state}}
{{t.state}}
{% endblock status %}
{% block actions %}
<a href="#" class="edit-template" data-id="{{ t.id }}" title="{% trans "Edit" %}">
<img src="{% static "icons/pencil.png" %}" alt="{% trans "Edit" %}" />
</a>
{% if t.state == 'READY' %}
<a href="#" class="try-template" data-id="{{t.id}}" title="{% trans "Try" %}">
<img src="/static/icons/control.png" alt="{% trans "Start" %}"/>
<img src="{% static "icons/control.png" %}" alt="{% trans "Start" %}"/>
</a>
<!--<a href="#" title="{% trans "Edit" %}">
<img src="/static/icons/pencil.png" alt="{% trans "Edit" %}" />
<img src="{% static "icons/pencil.png" %}" alt="{% trans "Edit" %}" />
</a>-->
<a href="#" class="template-share" data-id="{{t.id}}" data-gid="{{group.id}}" title="{% trans "Share" %}">
<img src="/static/icons/user-share.png" alt="{% trans "Share" %}" />
<img src="{% static "icons/user-share.png" %}" alt="{% trans "Share" %}" />
</a>
{% endif %}
<a href="#" class="delete-template" data-id="{{ t.id }}" data-name="{{ t.name }}" title="{% trans "Remove" %}">
<img src="/static/icons/minus-circle.png" alt="{% trans "Remove" %}" />
<img src="{% static "icons/minus-circle.png" %}" alt="{% trans "Remove" %}" />
</a>
<!--<a href="#" class="edit-template" data-id="{{ t.id }}" title="{% trans "Edit" %}">
<img src="/static/icons/pencil.png" alt="{% trans "Edit" %}" />
</a>-->
{% endblock actions %}
{% extends "box/base/box.html" %}
{% load i18n %}
{% load l10n %}
{% load staticfiles %}
{% get_current_language as LANGUAGE_CODE %}
{% block title %}
......@@ -9,8 +10,9 @@
{% block boxhelp %}
<div class="boxhelp">
<div class="help">
<div class="icon">
<img src="/static/icons/information-frame.png" alt="{% trans "Help" %}" />
<img class="help" src="{% static "icons/information-frame.png" %}" alt="{% trans "Help" %}" />
</div>
<div class="boxhelp-box">
<p>{% blocktrans %}This is the list of your running virtual machines.{% endblocktrans %}</p>
......@@ -19,6 +21,10 @@
<p>{% blocktrans %}Please note, that users and shares both have a limit
of launchable instances.{% endblocktrans %}</p>
</div>
</div>
<div class="icon">
<img src="" alt="{% trans "Show/hide box" %}" class="toggle-box" data-id="vms" id="toggle-box-vms"/>
</div>
</div>
{% endblock %}
......@@ -103,7 +109,7 @@
<li>
&nbsp;
<span class="value">
<form method="POST" action="/vm/new/s{{s.pk}}/">
<form method="POST" action="{% url one.views.vm_new share=s.id %}">
{% csrf_token %}
<input {% if s.running_shared >= s.per_user_limit or s.get_running >= s.instance_limit%}disabled="disabled" value="{% trans "Quota reached" %}" {%else%}value="{% trans "Launch" %}"{% endif %} type="submit" />
</form>
......
{% extends "box/base/entry.html" %}
{% load i18n %}
{% load staticfiles %}
{% get_current_language as LANGUAGE_CODE %}
{% block content %}
......@@ -26,7 +27,7 @@
</li>
<li class="template">
{% trans "Type" %}:
<span class="value">{{vm.share.type}}</span>
<span class="value">{% if vm.share %}{{vm.share.type}}{% else %}{% trans "Try" %}{% endif %}</span>
<div class="clear"></div>
</li>
<li class="template">
......@@ -56,9 +57,9 @@
<li class="date">
{% trans "time of suspend"|capfirst %}:
<span class="value"> <abbr title="{{vm.time_of_suspend}}">{{vm.time_of_suspend|timeuntil}}</abbr>
<a href="#" class="renew-vm-button renew-suspend-vm-button" data-id="{{ vm.id }}" title="{% trans "Renew suspend time" %}">
<img src="/static/icons/control-double.png" alt="{% trans "Renew suspend time" %}" />
</a>
{% if vm.share %}<a href="#" class="renew-vm renew-suspend-vm" data-id="{{ vm.id }}" title="{% trans "Renew suspend time" %}">
<img src="{% static "icons/control-double.png" %}" alt="{% trans "Renew suspend time" %}" />
</a>{% endif %}
</span>
</li>
{% endif %}
......@@ -66,16 +67,16 @@
<li class="date">
{% trans "time of delete"|capfirst %}:
<span class="value"> <abbr title="{{vm.time_of_delete}}">{{vm.time_of_delete|timeuntil}}</abbr>
<a href="#" class="renew-vm-button renew-delete-vm-button" data-id="{{ vm.id }}" title="{% trans "Renew deletion time" %}">
<img src="/static/icons/control-double.png" alt="{% trans "Renew deletion time" %}" />
</a>
{% if vm.share %}<a href="#" class="renew-vm renew-delete-vm" data-id="{{ vm.id }}" title="{% trans "Renew deletion time" %}">
<img src="{% static "icons/control-double.png" %}" alt="{% trans "Renew deletion time" %}" />
</a>{% endif %}
</span>
</li>
{% endif %}
<li>
&nbsp;
<span class="value">
<a href="/vm/show/{{vm.id}}/" title="{{vm.name}}">{% trans "More details" %}</a>
<a href="{{ vm.get_absolute_url }}" title="{{vm.name}}">{% trans "More details" %}</a>
</span>
</li>
</ul>
......
{% extends "box/base/summary.html" %}
{% load staticfiles %}
{% load i18n %}
{% get_current_language as LANGUAGE_CODE %}
......@@ -12,53 +13,53 @@
<div class="name {% if vm.state == 'ACTIVE' %}vm-on{% else %}vm-off{% endif %}">
<span id="vm-{{vm.id}}-name">{{vm.name|truncatechars:20}}</span>
<small id="vm-{{vm.id}}-name-details" class="details">
(<a href="/vm/show/{{vm.id}}/" title="{{vm.name}}">{% trans "More details" %}</a>)
(<a href="{{ vm.get_absolute_url }}" title="{{vm.name}}">{% trans "More details" %}</a>)
</small>
</div>
{% endblock %}
{% block status %}
{{vm.state}}
{% if vm.template.state != "READY" %} {{vm.template.state}} {% else %} {{vm.state}} {% endif %}
{% endblock status %}
{% block actions %}
<a href="#" class="rename-vm" data-name="{{ vm.name }}" data-id="{{ vm.id }}" title="{% trans "Edit name" %}">
<img src="/static/icons/pencil.png" alt="{% trans "Edit name" %}" />
<img src="{% static "icons/pencil.png" %}" alt="{% trans "Edit name" %}" />
</a>
{% if vm.waiting %}
<a href="#">
<img src="/static/image/load.gif" />
<img src="{% static "image/load.gif" %}" />
</a>
{% elif vm.state == 'ACTIVE' %}
<a href="{{vm.get_connect_uri}}" data-id="{{ vm.id }}" class="connect-vm" title="{% trans "Connect" %}">
<img src="/static/icons/plug.png" alt="{% trans "Connect" %}" />
<img src="{% static "icons/plug.png" %}" alt="{% trans "Connect" %}" />
</a>
<a href="#" class="stop-vm" data-name="{{ vm.name }}" data-id="{{ vm.id }}" title="{% trans "Pause" %}">
<img src="/static/icons/control-pause.png" alt="{% trans "Pause" %}" />
<img src="{% static "icons/control-pause.png" %}" alt="{% trans "Pause" %}" />
</a>
<a href="#" class="delete-vm" data-name="{{ vm.name }}" data-id="{{ vm.id }}" title="{% trans "Delete" %}">
<img src="/static/icons/minus-circle.png" alt="{% trans "Delete" %}" />
<img src="{% static "icons/minus-circle.png" %}" alt="{% trans "Delete" %}" />
</a>
<a href="#" class="restart-vm" data-name="{{ vm.name }}" data-id="{{ vm.id }}" title="{% trans "Restart" %}">
<img src="/static/icons/arrow-circle-double.png" alt="↺" />
<img src="{% static "icons/arrow-circle-double.png" %}" alt="↺" />
</a>
{% elif vm.state == 'PENDING' %}
<a href="#">
<img src="/static/image/load.gif" />
<img src="{% static "image/load.gif" %}" />
</a>
<a style="float: right" href="#" class="delete-vm" data-name="{{ vm.name }}" data-id="{{ vm.id }}" title="{% trans "Delete" %}">
<img src="/static/icons/minus-circle.png" alt="{% trans "Delete" %}" />
<img src="{% static "icons/minus-circle.png" %}" alt="{% trans "Delete" %}" />
</a>
{% elif vm.state == 'STOPPED' %}
<a href="#" class="resume-vm" data-name="{{ vm.name }}" data-id="{{ vm.id }}" title="{% trans "Resume" %}">
<img src="/static/icons/control.png" alt="{% trans "Resume" %}" />
<img src="{% static "icons/control.png" %}" alt="{% trans "Resume" %}" />
</a>
<a href="#" class="delete-vm" data-name="{{ vm.name }}" data-id="{{ vm.id }}" title="{% trans "Delete" %}">
<img src="/static/icons/minus-circle.png" alt="{% trans "Delete" %}" />
<img src="{% static "icons/minus-circle.png" %}" alt="{% trans "Delete" %}" />
</a>
{% elif vm.state == 'FAILED' %}
<a href="#" class="delete-vm" data-name="{{ vm.name }}" data-id="{{ vm.id }}" title="{% trans "Delete" %}">
<img src="/static/icons/minus-circle.png" alt="{% trans "Delete" %}" />
<img src="{% static "icons/minus-circle.png" %}" alt="{% trans "Delete" %}" />
</a>
{% endif %}
{% endblock actions %}
{% load i18n %}
{% get_current_language as LANGUAGE_CODE %}
<form action="{% url one.views.ajax_share_edit_wizard share.id %}" method="post" id="template-wizard">
{% csrf_token %}
<div id="new-share" class="wizard">
<h2>
{% blocktrans with t=share.name%}Editing share: {{t}}{% endblocktrans %}
</h2>
<p>{% trans "Change the parameters as needed." %}</p>
<ul>
<li>
<label for="share-name">{% trans "Name of share" %}</label>
<input type="text" name="name" id="share-name" value="{{share.name}}" />
<div class="clear"></div>
</li>
<li class="li-share-type">
<label for="share-type">{% trans "Type" %}</label>
<ul class="radio">
{% for s in types %}
<li>
<label>
<input type="radio" name="type" value="{{s.id}}" id="share-type-{{s.id}}"
{% if s.id == share.type %}checked="checked"{% endif %} />{{s.verbose_name}}
</label>
</li>
{% endfor %}
</ul>
{% for s in types %}
<p id="share-type-summary-{{s.id}}" class="type-summary clear"
{% if not s.id == share.type %}style="display:none"{% endif %}>
{{s.help_text}}
({% if s.suspend %}
<span class="suspend"
title="{% blocktrans with time=s.suspend %}Suspend after {{time}}.{%endblocktrans%}">{{s.suspendx|timeuntil}}</span>
{%endif%}{% if s.delete %}
<span class="delete"
title="{% blocktrans with time=s.delete %}Delete after {{time}}.{%endblocktrans%}">{{s.deletex|timeuntil}}</span>
{%endif%})
</p>
{% endfor %}
<div class="clear"></div>
</li>
<li>
<label for="share-instance-limit">{% trans "Maximal count of instances" %}</label>
<input type="number" name="instance_limit" id="share-instance-limit" value="{{share.instance_limit}}" />
<div class="clear"></div>
</li>
<li>
<label for="share-per-user-limit">{% trans "Maximal count of instaces/user" %}</label>
<input type="number" name="per_user_limit" id="share-per-user-limit" value="{{share.per_user_limit}}" />
<div class="clear"></div>
</li>
<li style="border: none" class="clear">
<label for="share-description">{% trans "Description" %}</label>
<textarea name="description" id="share-description" style="text-align: left">{{share.description}}</textarea>
<div class="clear"></div>
</li>
</ul>
<nav>
<input type="reset" class="prev" value="{% trans "Cancel" %}" />
<input type="submit" value="{% trans "Save" %}"/>
<div class="clear"></div>
</nav>
<script type="text/javascript">
$(function(){
$('#new-share nav .prev').click(function(){
$('#modal').hide();
})
$("#new-share input[name='type']").click(function(e){ /* TODO */
var v = $("#new-share input[name='type']:checked").val();
$("p.type-summary").hide();
$("#share-type-summary-" + v).show();
});
})
</script>
</div>
</form>
{% load i18n %}
{% load staticfiles %}
{% get_current_language as LANGUAGE_CODE %}
<form action="{% url one.views.ajax_template_edit_wizard template.id %}" method="post" id="template-wizard">
{% csrf_token %}
<div id="new-template-step-2" class="wizard">
<h2>{% trans "Edit template" %}</h2>
<p>{% trans "Change the parameters as needed." %}</p>
<ul>
<li>
<label for="new-template-name">{% trans "Name" %}</label>
<input type="text" name="name" id="new-template-name" value="{{template.name}}"
class="validated" />
<div class="clear"></div>
</li>
<li class="new-tpl-size">
<label for="new-template-size">{% trans "Size" %}</label>
<ul class="radio">
{% for s in sizes %}
<li>
<label>
<input type="radio" name="size" value="{{s.id}}" id="new-template-size-{{s.id}}"
{% if s == template.instance_type %}checked="checked"{% endif %} />
{{s.name}}
</label>
</li>
{% endfor %}
</ul>
{% for s in sizes %}
<p id="new-template-size-summary-{{s.id}}" class="size-summary clear"
{% if s != template.instance_type %}style="display:none"{% endif %}>
<span class="cpu">
{% blocktrans count n=s.CPU %}{{n}} core{% plural %}{{n}} cores{% endblocktrans %}
</span>
<span class="memory">{{s.RAM}} MiB</span>
<span class="credit">{{s.credit}}</span>
</p>
{% endfor %}
<div class="clear"></div>
</li>
<li style="border: none">
<label for="new-template-description">{% trans "Description" %}</label>
<textarea name="description" id="new-template-description" style="text-align: left">{{template.description}}</textarea>
<div class="clear"></div>
</li>
</ul>
<nav>
<input type="reset" class="prev" value="{% trans "Cancel" %}" />
<input type="submit" class="next" value="{% trans "Save" %}" />
<div class="clear"></div>
</nav>
<script type="text/javascript">
$(function(){
var original = '{{template.name}}';
$('#new-template-step-2 nav .prev').click(function(){
$('#modal').hide();
})
$(".new-tpl-size input[name='size']").click(function(e){
var v = $(".new-tpl-size input[name='size']:checked").val();
$("p.size-summary").hide();
$("#new-template-size-summary-" + v).show();
});
$("#new-template-name").keyup(function(){
var timer;
return function(e){
var self = this;
clearTimeout(timer);
timer=setTimeout(function(){
var s = $(self).val();
$.ajax({
'type': 'GET',
'url': '{% url one.views.ajax_template_name_unique %}?name=' + s,
'success': function(data, b, c) {
if (s != $("#new-template-name").val()) {
return true;
}
if (data == "True" || s == original) {
$('#new-template-name').removeClass("error");
$('#new-template-step-2 nav .next').removeAttr("disabled");
$('#new-template-name').removeProp("title");
}
else {
$('#new-template-name').addClass("error");
$('#new-template-step-2 nav .next').attr("disabled", "disabled");
$('#new-template-name').prop("title", gettext('Please choose a different name.'));
}
}
});
}, 1000)
}
}());
$("#template-wizard").submit(function(e){
e.preventDefault();
$.ajax({
'type': 'GET',
'url': '{% url one.views.ajax_template_name_unique %}?name=' + $("#new-template-name").val(),
'success': function(data, b, c) {
if (data == "True" || s == original) {
$("#template-wizard").unbind('submit').submit()
}
else {
$('#new-template-name').addClass("error");
$('#new-template-step-2 nav .next').attr("disabled", "disabled");
$('#new-template-name').prop("title", gettext('Please choose a different name.'));
}
}
});
});
})
</script>
</div>
</form>
{% extends "base.html" %}
{% load i18n %}
{% load staticfiles %}
{% get_current_language as LANGUAGE_CODE %}
{% block js %}
<script type="text/javascript" src="/static/script/store.js"></script>
{% if DEBUG %}<script type="text/javascript" src="{% static "script/store.js" %}"></script>
{% else %}<script type="text/javascript" src="{% static "script/store.min.js" %}"></script>
{% endif %}
{% endblock %}
{% block content %}
<div class="boxes">
......
{% load i18n %}
{% blocktrans with name=user.get_full_name %}
Dear {{name}},
{% endblocktrans %}
{% block body %}
{% endblock %}
--
{{site}}
{% extends "mails/base.txt" %}
{% load i18n %}
{% block body %}
{% blocktrans with reason=bl.reason snort_message=bl.snort_message vm=instance.name %}
Our network intrusion detection system showed that your machine
"{{vm}}" pursues the following forbidden network activity: {{reason}}.
"{{vm}}" has been BANNED from all network activity
including remote desktop and shell connection.
Details:
{{snort_message}}
{% endblocktrans %}
{% blocktrans with url=url %}
Please, reply to this notification, or delete the instance on the
cloud portal: {{url}}
{% endblocktrans %}
{% endblock %}
{% extends "mails/base.txt" %}
{% load i18n %}
{% block body %}
{% blocktrans with vm=instance.name state=instance.state|lower date=instance.time_of_delete %}
Your {{state}} virtual machine "{{vm}}" has been DELETED
at {{date}}.
{% endblocktrans %}
{% blocktrans %}
The disk image is IRRECOVERABLY REMOVED.
{% endblocktrans %}
{% blocktrans with url=url %}
You can start a new instance of the template on the cloud portal:
{{url}}
{% endblocktrans %}
{% endblock %}
{% extends "mails/base.txt" %}
{% load i18n %}
{% block body %}
{% blocktrans with vm=instance.name state=instance.state|lower date=instance.time_of_delete time=exp|timeuntil %}
Your {{state}} virtual machine "{{vm}}" is going to be DELETED
at {{date}} (in {{time}}).
{% endblocktrans %}
{% blocktrans %}
The disk image will be IRRECOVERABLY REMOVED.
{% endblocktrans %}
{% blocktrans with url=url %}
You can renew or delete the instance on the cloud portal:
{{url}}
{% endblocktrans %}
{% endblock %}
{% extends "mails/base.txt" %}
{% load i18n %}
{% block body %}
{% blocktrans with vm=instance.name state=instance.state|lower date=instance.time_of_suspend %}
Your {{state}} virtual machine "{{vm}}" has been STOPPED
at {{date}}.
{% endblocktrans %}
{% blocktrans with deldate=instance.time_of_delete %}
The disk and memory image is stored, and you can resume it
until the final expiration time ({{deldate}}).
{% endblocktrans %}
{% blocktrans with url=url %}
You can also renew or delete the instance on the cloud portal:
{{url}}
{% endblocktrans %}
{% endblock %}
{% extends "mails/base.txt" %}
{% load i18n %}
{% block body %}
{% blocktrans with vm=instance.name state=instance.state|lower date=instance.time_of_suspend time=exp|timeuntil url=url %}
Your {{state}} virtual machine "{{vm}}" is going to be STOPPED
at {{date}} (in {{time}}).
{% endblocktrans %}
{% blocktrans with deldate=instance.time_of_delete %}
The disk and memory image will be stored, and you can resume it
until the final expiration time ({{deldate}}).
{% endblocktrans %}
{% blocktrans with url=url %}
You can also renew or delete the instance on the cloud portal:
{{url}}
{% endblocktrans %}
{% endblock %}
{% load i18n %}
{% get_current_language as LANGUAGE_CODE %}
<form action="/ajax/share/{{base.id}}/" method="post" id="template-wizard">
<form action="{% url one.views.ajax_share_wizard id=base.id %}" method="post" id="template-wizard">
{% csrf_token %}
<div id="new-share" class="wizard">
<h2>
......
{% load i18n %}
{% load staticfiles %}
{% get_current_language as LANGUAGE_CODE %}
<form action="/ajax/templateWizard" method="post" id="template-wizard">
<form action="{% url one.views.ajax_template_wizard %}" method="post" id="template-wizard">
{% csrf_token %}
<div id="new-template-step-1" class="wizard">
<div class="progress">
......@@ -28,7 +29,7 @@
<input type="radio" name="base" value="{{m.id}}" />
{{m.name}}
{% if m.public %}
<img src="/static/icons/lock-small.png" alt="{% trans "locked" %}"
<img src="{% static "icons/lock-small.png" %}" alt="{% trans "locked" %}"
title="{% trans "This is a shared template." %}" />
{% endif %}
</label>
......@@ -56,7 +57,7 @@
else {
$.ajax({
'type': 'POST',
'url': '/ajax/templateWizard',
'url': '{% url one.views.ajax_template_wizard %}',
'data': $('#template-wizard').serialize(),
'success': function(data) {
$('#modal-container').html(data);
......
{% load i18n %}
{% load staticfiles %}
{% get_current_language as LANGUAGE_CODE %}
<form action="/vm/new/{{base.id}}/" method="post" id="template-wizard">
<form action="{% url new_vm_from_template base.id %}" method="post" id="template-wizard">
{% csrf_token %}
<div id="new-template-step-2" class="wizard">
<div class="progress">
......@@ -75,7 +76,7 @@
var s = $(self).val();
$.ajax({
'type': 'GET',
'url': '/ajax/template_name_unique/' + s,
'url': '{% url one.views.ajax_template_name_unique %}?name=' + s,
'success': function(data, b, c) {
if (s != $("#new-template-name").val()) {
return true;
......@@ -99,7 +100,7 @@
e.preventDefault();
$.ajax({
'type': 'GET',
'url': '/ajax/template_name_unique/' + $("#new-template-name").val(),
'url': '{% url one.views.ajax_template_name_unique %}?name=' + $("#new-template-name").val(),
'success': function(data, b, c) {
if (data == "True") {
$("#template-wizard").unbind('submit').submit()
......
{% extends "base.html" %}
{% load i18n %}
{% load staticfiles %}
{% block js %}
<script type="text/javascript">
......@@ -8,14 +9,28 @@
$.ajax({
type: 'GET',
dataType: 'json',
url: '/ajax/vm/status/{{ id }}',
url: '{% url one.views.vm_ajax_instance_status id %}',
success: function(data){
if( !data.booting && data.state == 'ACTIVE'){
if (!data.booting && data.state == 'ACTIVE'){
window.location.reload();
}
}
})
},2000);
});
}, 5000);
{% endif %}
{% if i.template.state == 'SAVING' %}
var savingTimer=setInterval(function(){
$.ajax({
type: 'GET',
dataType: 'json',
url: '{% url one.views.vm_ajax_instance_status id %}',
success: function(data){
if(data.template.state == 'READY'){
window.location.href='{% url one.views.home %}';
}
}
});
}, 10000);
{% endif %}
</script>
{% endblock %}
......@@ -61,13 +76,18 @@
<div class="content">
{% if state == "PENDING" or state == "ACTIVE" and booting %}
<p style="font-size:25px; line-height:2em;text-align:center;">
<img src="/static/image/load.gif" />
<img src="{% static "image/load.gif" %}" />
{% trans "Starting..." %}
</p>
{% elif i.template.state == "SAVING" %}
<p style="font-size:25px; line-height:2em;text-align:center;">
<img src="{% static "image/load.gif" %}" />
{% trans "Saving..." %}
</p>
{% elif state == "ACTIVE" and not booting %}
<p id="connect" style="display:block; font-size:25px; line-height:2em;text-align:center;">
<a href="{{uri}}" class="button" onclick="return connectbutton();">
<img src="/static/image/load.gif" id="connecting" style="display:none;" />
<img src="{% static "image/load.gif" %}" id="connecting" style="display:none;" />
{% trans "Running" %}
</a>
</p>
......@@ -90,8 +110,9 @@
<div class="contentblock" id="ports">
<h2>
<div class="boxhelp">
<div class="help">
<div class="icon">
<img src="/static/icons/information-frame.png" alt="{% trans "Help" %}" />
<img src="{% static "icons/information-frame.png" %}" alt="{% trans "Help" %}" />
</div>
<div class="boxhelp-box">
<p>{% blocktrans %}This is a list about the network ports
......@@ -105,23 +126,24 @@
{% endblocktrans %}</p>
</div>
</div>
</div>
{% trans "Port administration" %}</h2>
<div class="content">
<form action="{% url vm_port_add i.id %}" method="post">
<form action="{% url one.views.vm_port_add i.id %}" method="post">
{% csrf_token %}
<table>
<tr>
<th>{% trans "Protocol" %}</th>
<th>{% trans "Public port" %}</th>
<th colspan="2">{% trans "Private port" %}</th>
{% if i.template.network.nat %}<th colspan="2">{% trans "Private port" %}</th>{%endif%}
</tr>
{% for port in ports %}
<tr>
<td>{{port.proto}}</td>
<td>{{port.public}}</td>
<td>{{port.private}}</td>
{% if i.template.network.nat %}<td>{{port.private}}</td>{%endif%}
<td>
<a href="/vm/port_del/{{i.id}}/{{port.proto}}/{{port.public}}/">{% trans "Delete" %}</a>
<a href="{% url one.views.vm_port_del i.id port.proto port.public %}">{% trans "Delete" %}</a>
</td>
</tr>
{% endfor %}
......@@ -135,9 +157,11 @@
<td>
<input style="min-width:70px;width:70px;" type="text" name="public"/>
</td>
{% if i.template.network.nat %}
<td>
<input style="min-width:70px;width:70px;" type="text" name="private"/>
</td>
{% endif %}
<td>
<input type="submit" style="min-width:3em" value="{% trans "Add" %}" />
</td>
......
{% load l10n %}
<html>
<head>
<!--Load the AJAX API-->
<script type="text/javascript" src="https://www.google.com/jsapi"></script>
<script type="text/javascript">
// Load the Visualization API and the piechart package.
google.load('visualization', '1.0', {'packages':['corechart']});
// Set a callback to run when the Google Visualization API is loaded.
google.setOnLoadCallback(drawChart);
// Callback that creates and populates a data table,
// instantiates the pie chart, passes in the data and
// draws it.
function drawChart() {
// Create the data table.
var data_cpu = new google.visualization.DataTable();
data_cpu.addColumn('string', 'Topping');
data_cpu.addColumn('number', 'Slices');
data_cpu.addRows([
['Free CPU', {{STAT.CPU.FREE_CPU}}],
['Allocated CPU', {{STAT.CPU.ALLOC_CPU}}],
['Used CPU', {{STAT.CPU.USED_CPU}}],
]);
// Set chart options
var cpu_options = {'title':'Cloud CPU usage percent (100/CPU)',
'width':400,
'height':300,
slices: {0: {color: 'blue'}, 1:{color: 'orange'},
2:{color: 'red'}}
};
var data_mem = new google.visualization.DataTable();
data_mem.addColumn('string', 'Topping');
data_mem.addColumn('number', 'Slices');
data_mem.addRows([
['Free Memory', {{STAT.MEM.FREE_MEM|unlocalize}}],
['Allocated Memory', {{STAT.MEM.ALLOC_MEM|unlocalize}}],
['Used Memory', {{STAT.MEM.USED_MEM|unlocalize}}],
]);
// Set chart options
var mem_options = {'title':'Cloud Memory usage in {{STAT.DIMENSION}}',
'width':400,
'height':300,
slices: {0: {color: 'blue'}, 1:{color: 'orange'},
2:{color: 'red'}}
};
// Instantiate and draw our chart, passing in some options.
var chart = new
google.visualization.PieChart(document.getElementById('chart_cpu_div'));
chart.draw(data_cpu, cpu_options);
var chart = new
google.visualization.PieChart(document.getElementById('chart_mem_div'));
chart.draw(data_mem, mem_options);
}
</script>
</head>
<body>
<!--Div that will hold the pie chart-->
<div>Running VMs: {{STAT.VMS}}</div>
<div id="chart_cpu_div"></div>
<div id="chart_mem_div"></div>
</body>
</html>
{% load i18n %}
{% load staticfiles %}
{% get_current_language as LANGUAGE_CODE %}
<div class="content">
<table>
......@@ -7,8 +8,9 @@
<td>
<div class="boxhelp">
<div class="help">
<div class="icon">
<img src="/static/icons/information-frame.png" alt="{% trans "Help" %}" />
<img src="{% static "icons/information-frame.png" %}" alt="{% trans "Help" %}" />
</div>
<div class="boxhelp-box">
{% if i.template.os_type == 'linux' %}
......@@ -30,16 +32,17 @@
{% endif %}
</div>
</div>
</div>
{{i.template.access_type|upper}}
</td>
</tr>
<tr>
<th>{% trans "IP" %}:</th>
<td>{{ i.firewall_host.pub_ipv4 }}</td>
<td>{{ i.hostname }}</td>
</tr>
<tr>
<th>{% trans "Port" %}:</th>
<td>{{ i.get_port}}</td>
<td>{{ i.port}}</td>
</tr>
<tr>
<th>{% trans "Username" %}:</th>
......
"""
This file demonstrates writing tests using the unittest module. These will pass
when you run "manage.py test".
Replace this with more appropriate tests for your application.
"""
from django.test import TestCase
class SimpleTest(TestCase):
def test_basic_addition(self):
"""
Tests that 1 + 1 always equals 2.
"""
self.assertEqual(1 + 1, 2)
class ViewsTestCase(TestCase):
def test_index(self):
'''Test whether index is reachable.'''
resp = self.client.get('/', follow=True)
self.assertEqual(resp.status_code, 200)
......@@ -26,6 +26,7 @@ from school.models import *
import django.contrib.auth as auth
import json
import logging
import subprocess
logger = logging.getLogger(__name__)
......@@ -33,11 +34,23 @@ def _list_instances(request):
instances = Instance.objects.exclude(state='DONE').filter(owner=request.user)
for i in instances:
i.update_state()
instances = instances.exclude(state='DONE')
return instances
def info(request):
return render_to_response("info.html", RequestContext(request, {}))
def index(request):
if request.user.is_authenticated():
return redirect(home)
else:
return redirect(info)
@require_GET
@login_required
def home(request):
instances = _list_instances(request)
shares = [s for s in request.user.person_set.all()[0].get_shares()]
for i, s in enumerate(shares):
s.running_shared = s.instance_set.all().exclude(state="DONE").filter(owner=request.user).count()
......@@ -52,10 +65,10 @@ def home(request):
except:
generated_public_key = -1
return render_to_response("home.html", RequestContext(request, {
'instances': instances,
'shares': shares,
'templates': Template.objects.filter(state='READY'),
'mytemplates': Template.objects.filter(owner=request.user),
'instances': _list_instances(request),
'groups': request.user.person_set.all()[0].owned_groups.all(),
'semesters': Semester.objects.all(),
'userdetails': details,
......@@ -82,7 +95,8 @@ def ajax_template_delete(request):
else:
return HttpResponse(unicode(_("Unexpected error happened.")), status=404)
def ajax_template_name_unique(request, name):
def ajax_template_name_unique(request):
name = request.GET['name']
s = "True"
if Template.objects.filter(name=name).exists():
s = "False"
......@@ -92,6 +106,9 @@ def ajax_template_name_unique(request, name):
def vm_credentials(request, iid):
try:
vm = get_object_or_404(Instance, pk=iid, owner=request.user)
proto = len(request.META["REMOTE_ADDR"].split('.')) == 1
vm.hostname = vm.get_connect_host(use_ipv6=proto)
vm.port = vm.get_port(use_ipv6=proto)
return render_to_response('vm-credentials.html', RequestContext(request, { 'i' : vm }))
except:
return HttpResponse(_("Could not get Virtual Machine credentials."), status=404)
......@@ -118,6 +135,27 @@ class AjaxTemplateWizard(View):
}))
ajax_template_wizard = login_required(AjaxTemplateWizard.as_view())
class AjaxTemplateEditWizard(View):
def get(self, request, id, *args, **kwargs):
template = get_object_or_404(Template, id=id)
if template.owner != request.user and not template.public and not request.user.is_superuser:
raise PermissionDenied()
return render_to_response('edit-template-flow.html', RequestContext(request, {
'sizes': InstanceType.objects.all(),
'template': template,
}))
def post(self, request, id, *args, **kwargs):
template = get_object_or_404(Template, id=id)
if template.owner != request.user and not template.public and not request.user.is_superuser:
raise PermissionDenied()
template.instance_type_id = request.POST['size']
template.description = request.POST['description']
template.name = request.POST['name']
template.save()
return redirect(home)
ajax_template_edit_wizard = login_required(AjaxTemplateEditWizard.as_view())
class AjaxShareWizard(View):
def get(self, request, id, gid=None, *args, **kwargs):
......@@ -166,7 +204,43 @@ class AjaxShareWizard(View):
return redirect(group)
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:
return HttpResponse(unicode(_('You do not have any free share quota.')))
types = TYPES_L
for i, t in enumerate(types):
t['deletex'] = datetime.now() + td(seconds=1) + t['delete'] if t['delete'] else None
t['suspendx'] = datetime.now() + td(seconds=1) + t['suspend'] if t['suspend'] else None
types[i] = t
share = get_object_or_404(Share, id=id)
return render_to_response('edit-share.html', RequestContext(request, {
'share': share,
'types': types,
}))
def post(self, request, id, *args, **kwargs):
det = UserCloudDetails.objects.get(user=request.user)
share = get_object_or_404(Share, id=id)
if share.owner != request.user and not request.user.is_superuser:
raise PermissionDenied()
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:
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
share.save()
messages.success(request, _('Successfully edited share %s.') % share)
return redirect(share.group)
ajax_share_edit_wizard = login_required(AjaxShareEditWizard.as_view())
@require_POST
......@@ -289,6 +363,14 @@ def vm_show(request, iid):
ports = inst.firewall_host.list_ports()
except:
ports = None
try:
details = UserCloudDetails.objects.get(user=request.user)
except UserCloudDetails.DoesNotExist:
details = UserCloudDetails(user=request.user)
details.save()
proto = len(request.META["REMOTE_ADDR"].split('.')) == 1
inst.hostname = inst.get_connect_host(use_ipv6=proto)
inst.port = inst.get_port(use_ipv6=proto)
return render_to_response("show.html", RequestContext(request,{
'uri': inst.get_connect_uri(),
'state': inst.state,
......@@ -299,6 +381,7 @@ def vm_show(request, iid):
'i': inst,
'booting' : not inst.active_since,
'ports': ports,
'userdetails': details
}))
@require_safe
......@@ -306,7 +389,12 @@ def vm_show(request, iid):
def vm_ajax_instance_status(request, iid):
inst = get_object_or_404(Instance, id=iid, owner=request.user)
inst.update_state()
return HttpResponse(json.dumps({'booting': not inst.active_since, 'state': inst.state}))
return HttpResponse(json.dumps({
'booting': not inst.active_since,
'state': inst.state,
'template': {
'state': inst.template.state
}}))
@login_required
def vm_ajax_rename(request, iid):
......@@ -336,7 +424,11 @@ class VmPortAddView(View):
if public >= 22000 and public < 24000:
raise ValidationError(_("Port number is in a restricted domain (22000 to 24000)."))
inst = get_object_or_404(Instance, id=iid, owner=request.user)
inst.firewall_host.add_port(proto=request.POST['proto'], public=public, private=int(request.POST['private']))
if inst.template.network.nat:
private = private=int(request.POST['private'])
else:
private = 0
inst.firewall_host.add_port(proto=request.POST['proto'], public=public, private=private)
messages.success(request, _(u"Port %d successfully added.") % public)
except:
messages.error(request, _(u"Adding port failed."))
......@@ -355,7 +447,7 @@ def vm_port_del(request, iid, proto, public):
inst = get_object_or_404(Instance, id=iid, owner=request.user)
try:
inst.firewall_host.del_port(proto=proto, public=public)
messages.success(request, _(u"Port %d successfully removed.") % public)
messages.success(request, _(u"Port %s successfully removed.") % public)
except:
messages.error(request, _(u"Removing port failed."))
return redirect('/vm/show/%d/' % int(iid))
......@@ -413,17 +505,22 @@ def vm_stop(request, iid, *args, **kwargs):
@require_POST
def vm_resume(request, iid, *args, **kwargs):
try:
get_object_or_404(Instance, id=iid, owner=request.user).resume()
obj = get_object_or_404(Instance, id=iid, owner=request.user)
obj.resume()
messages.success(request, _('Virtual machine is successfully resumed.'))
except:
messages.error(request, _('Failed to resume virtual machine.'))
try:
obj.renew()
except:
pass
return redirect('/')
@login_required
@require_POST
def vm_renew(request, which, iid, *args, **kwargs):
try:
get_object_or_404(Instance, id=iid, owner=request.user).renew(which)
get_object_or_404(Instance, id=iid, owner=request.user).renew()
messages.success(request, _('Virtual machine is successfully renewed.'))
except:
messages.error(request, _('Failed to renew virtual machine.'))
......@@ -460,9 +557,13 @@ def key_add(request):
key.save()
_update_keys(request.user)
except ValidationError as e:
messages.error(request, ''.join(e.messages))
for m in e.messages:
messages.error(request, m)
except:
messages.error(request, _('Failed to add public key'))
messages.error(request, _('Failed to add public key.'))
else:
messages.success(request, _('Public key successfully added.'))
return redirect('/')
@login_required
......@@ -497,5 +598,23 @@ def _update_keys(user):
user = user.username
StoreApi.updateauthorizationinfo(user, password, key_list)
def stat(request):
values = subprocess.check_output(['/opt/webadmin/cloud/miscellaneous/stat/stat_wrap.sh'])
# values = '''
# {"CPU": {"USED_CPU": 2, "ALLOC_CPU": 0,
# "FREE_CPU": 98}, "MEM": {"FREE_MEM": 1685432, "ALLOC_MEM":0,
# "USED_MEM": 366284}}'''
stat_dict = json.loads(values)
return HttpResponse(render_to_response("stat.html", RequestContext(
request, {
'STAT' : stat_dict,
}
)))
def sites(request, site):
if site in [ "legal", "policy", "help", "support" ]:
return render_to_response("sites/%s.html" % site, RequestContext(request, {}))
else:
return redirect(home)
# vim: et sw=4 ai fenc=utf8 smarttab :
......@@ -6,10 +6,10 @@ msgid ""
msgstr ""
"Project-Id-Version: \n"
"Report-Msgid-Bugs-To: \n"
"POT-Creation-Date: 2013-02-21 18:06+0100\n"
"PO-Revision-Date: 2013-02-19 18:47+0100\n"
"POT-Creation-Date: 2013-03-07 18:16+0100\n"
"PO-Revision-Date: 2013-03-07 17:48+0100\n"
"Last-Translator: \n"
"Language-Team: American English <kde-l10n-hu@kde.org>\n"
"Language-Team: American English <cloud@ik.bme.hu>\n"
"Language: en_US\n"
"MIME-Version: 1.0\n"
"Content-Type: text/plain; charset=UTF-8\n"
......@@ -159,127 +159,179 @@ msgstr "Érvénytelen Neptun-kód."
msgid "Invalid NEPTUN code"
msgstr "Érvénytelen Neptun-kód"
#: templates/show-group.html:8
#: templates/show-group.html:9
msgid "Owners of"
msgstr "Tulajdonosok"
#: templates/show-group.html:22 templates/box/person/entry.html:22
#: templates/show-group.html:23 templates/box/person/entry.html:23
msgid "Remove"
msgstr "Eltávolítás"
#: templates/show-group.html:30 templates/box/person/entry.html:31
#: templates/show-group.html:31 templates/box/person/entry.html:32
msgid "This user never logged in, no data available"
msgstr "Ez a felhasználó még nem lépett be, nincs adat róla"
#: templates/show-group.html:34 templates/box/person/entry.html:35
#: templates/show-group.html:35 templates/box/person/entry.html:36
msgid "Name"
msgstr "Név"
#: templates/show-group.html:37 templates/box/person/entry.html:38
#: templates/show-group.html:38 templates/box/person/entry.html:39
msgid "NEPTUN"
msgstr "NEPTUN"
#: templates/show-group.html:50
#: templates/show-group.html:51
msgid "Add owner"
msgstr "Tulajdonos hozzáadása"
#: templates/show-group.html:55
#: templates/show-group.html:56
msgid "Owner name/NEPTUN"
msgstr "Tulajdonos neve/NEPTUN-kódja"
#: templates/show-group.html:68
#: templates/show-group.html:69
msgid "This group has no shared templates."
msgstr "Ennek a csoportnak egy sablon sincs megosztva."
#: templates/show-group.html:71
#: templates/show-group.html:72
msgid "Share one, and the group members can start their own virtual machine."
msgstr ""
"Osszon meg egyet, hogy a csoport tagjai is elindíthassák egy példányát."
#: templates/box/group/box.html:7
#: templates/box/group/box.html:11 templates/box/person/box.html:11
msgid "Help"
msgstr "Segítség"
#: templates/box/group/box.html:14
msgid "This is the list of groups you own."
msgstr "Ez az ön csoportjainak felsorolása."
#: templates/box/group/box.html:15
msgid "Groups are collections of users."
msgstr "A csoportok felhasználók halmazai."
#: templates/box/group/box.html:16
msgid ""
"You can share templates with your groups, so\n"
" that they can run instances of those templates.\n"
" "
msgstr ""
"Megoszthatja a sablonokat csoportjaival, \n"
" így a tagok elindíthatják a sablonokból saját példányaikat.\n"
" "
#: templates/box/group/box.html:22 templates/box/person/box.html:21
msgid "Show/hide box"
msgstr "Doboz megjelenítése/rejtése"
#: templates/box/group/box.html:28
msgid "My Groups"
msgstr "Saját csoportok"
#: templates/box/group/box.html:19
#: templates/box/group/box.html:40
msgid "You have no groups."
msgstr "Nincs még csoportja."
#: templates/box/group/box.html:21
#: templates/box/group/box.html:42
msgid "Create a new one, and add your students to the new group."
msgstr "Hozzon létre egyet, és vegy fel hallgatóit."
#: templates/box/group/box.html:29
#: templates/box/group/box.html:50
msgid "Show hidden groups"
msgstr "Elrejtett csoportok megjelenítése"
#: templates/box/group/box.html:35 templates/box/group/box.html.py:41
#: templates/box/group/box.html:56 templates/box/group/box.html.py:62
msgid "Create new group"
msgstr "Új csoport létrehozása"
#: templates/box/group/box.html:44
#: templates/box/group/box.html:65
msgid "Group name"
msgstr "Csoport neve"
#: templates/box/group/box.html:48 templates/box/group/entry.html:42
#: templates/box/group/box.html:69 templates/box/group/entry.html:43
msgid "Semester"
msgstr "Félév"
#: templates/box/group/box.html:56
#: templates/box/group/box.html:77
msgid "Members"
msgstr "Tagok"
#: templates/box/group/box.html:57
#: templates/box/group/box.html:78
msgid "Student NEPTUN codes, one per line"
msgstr "Hallgatók NEPTUN-kódja, soronként egy"
#: templates/box/group/box.html:62
#: templates/box/group/box.html:83
msgid "Cancel"
msgstr "Mégsem"
#: templates/box/group/box.html:63
#: templates/box/group/box.html:84
msgid "Done"
msgstr "Kész"
#: templates/box/group/entry.html:15 templates/box/group/entry.html.py:56
#: templates/box/group/entry.html:16 templates/box/group/entry.html.py:57
msgid "More details"
msgstr "Részletek"
#: templates/box/group/entry.html:19
#: templates/box/group/entry.html:20
msgid "Delete"
msgstr "Törlés"
#: templates/box/group/entry.html:22
#: templates/box/group/entry.html:23
msgid "Hide"
msgstr "Elrejtés"
#: templates/box/group/entry.html:32
#: templates/box/group/entry.html:33
msgid "Course"
msgstr "Tárgy"
#: templates/box/group/entry.html:37
#: templates/box/group/entry.html:38
msgid "Not assigned"
msgstr "Nincs hozzárendelve"
#: templates/box/group/entry.html:46
#: templates/box/group/entry.html:47
msgid "Owner(s)"
msgstr "Tulajdonosok"
#: templates/box/group/entry.html:50
#: templates/box/group/entry.html:51
msgid "Member count"
msgstr "Tagok száma"
#: templates/box/person/box.html:7
#: templates/box/person/box.html:14
msgid "This is the list of this group's members."
msgstr "Ez a csoport tagjainak felsorolása."
#: templates/box/person/box.html:15
msgid ""
"Members are the people who can start new\n"
" instances of templates shared with the group.\n"
" "
msgstr ""
"A tagok azok a személyek, akik jogosultak a csoportnak\n"
" megosztott sablonok példányainak indítására.\n"
" "
#: templates/box/person/box.html:27
msgid "Members of"
msgstr "Tagok"
#: templates/box/person/box.html:17 templates/box/person/box.html.py:20
#: templates/box/person/box.html:37 templates/box/person/box.html.py:40
msgid "Add user"
msgstr "Felhasználó hozzáadása"
#: templates/box/person/box.html:19
#: templates/box/person/box.html:39
msgid "User NEPTUN code"
msgstr "Felhasználó Neptun-kódja"
#~ msgid "Templates are customized versions of the base images."
#~ msgstr "A sablonok alaprendszerek testre szabott változatai."
#~ msgid ""
#~ "You can install all the needed software on a master\n"
#~ " machine, and it will be ready to run by your students in "
#~ "minutes.\n"
#~ " "
#~ msgstr ""
#~ "Telepítheti az összes szükséges szoftvert egy mestergépen, és az "
#~ "ígykészült sablon pár perc múltán készen is állhat a hallgatók számára."
#~ msgid "Templates"
#~ msgstr "Sablonok"
......
{% extends "box/base/box.html" %}
{% load i18n %}
{% load l10n %}
{% load staticfiles %}
{% get_current_language as LANGUAGE_CODE %}
{% block boxhelp %}
<div class="boxhelp">
<div class="help">
<div class="icon">
<img src="{% static "icons/information-frame.png" %}" alt="{% trans "Help" %}" />
</div>
<div class="boxhelp-box">
<p>{% blocktrans %}This is the list of groups you own.{% endblocktrans %}</p>
<p>{% blocktrans %}Groups are collections of users.{% endblocktrans %}</p>
<p>{% blocktrans %}You can share templates with your groups, so
that they can run instances of those templates.
{% endblocktrans %}</p>
</div>
</div>
<div class="icon">
<img src="" alt="toggle" title="{% trans "Show/hide box" %}" class="toggle-box" data-id="groups" id="toggle-box-groups"/>
</div>
</div>
{% endblock %}
{% block title %}
{% trans "My Groups" %}
{% endblock title %}
......@@ -36,7 +57,7 @@
<div class="clear"></div>
</div>
<div id="new-group-wizard" style="display: none">
<form action="/group/new/" method="POST" class="wizard">
<form action="{% url school.views.group_new %}" method="POST" class="wizard">
{% csrf_token %}
<h3>{% trans "Create new group" %}</h3>
<ul>
......
{% extends "box/base/entry.html" %}
{% load i18n %}
{% load staticfiles %}
{% get_current_language as LANGUAGE_CODE %}
{% block content %}
......@@ -12,14 +13,14 @@
<div class="summary">
<div class="name">
{{ group.name }}
<small class="details">(<a href="/group/show/{{group.id}}">{% trans "More details" %}</a>)</small>
<small class="details">(<a href="{{ group.get_absolute_url }}">{% trans "More details" %}</a>)</small>
</div>
<div class="actions">
<a href="#" class="delete" data-id="{{group.id}}" data-name="{{group.name}}">
<img src="/static/icons/minus-circle.png" alt="{% trans "Delete" %}" title="{% trans "Delete" %}" />
<img src="{% static "icons/minus-circle.png" %}" alt="{% trans "Delete" %}" title="{% trans "Delete" %}" />
</a>
<a href="#" class="hide-group" data-id="{{group.id}}">
<img src="/static/icons/eye-half.png" alt="{% trans "Hide" %}" title="{% trans "Hide" %}" />
<img src="{% static "icons/eye-half.png" %}" alt="{% trans "Hide" %}" title="{% trans "Hide" %}" />
</a>
</div>
<div class="clear"></div>
......@@ -53,7 +54,7 @@
<li>
&nbsp;
<span class="value">
<a href="/group/show/{{group.id}}">{% trans "More details" %}</a>
<a href="{{group.get_absolute_url}}">{% trans "More details" %}</a>
</span>
</li>
</ul>
......
{% extends "box/base/box.html" %}
{% load i18n %}
{% load l10n %}
{% load staticfiles %}
{% get_current_language as LANGUAGE_CODE %}
{% block boxhelp %}
<div class="boxhelp">
<div class="help">
<div class="icon">
<img src="{% static "icons/information-frame.png" %}" alt="{% trans "Help" %}" />
</div>
<div class="boxhelp-box">
<p>{% blocktrans %}This is the list of this group's members.{% endblocktrans %}</p>
<p>{% blocktrans %}Members are the people who can start new
instances of templates shared with the group.
{% endblocktrans %}</p>
</div>
</div>
<div class="icon">
<img src="" alt="eye" title="{% trans "Show/hide box" %}" class="toggle-box" data-id="members" id="toggle-box-members"/>
</div>
</div>
{% endblock %}
{% block title %}
{% trans "Members of" %}: {{group.name}}
{% endblock title %}
......
{% extends "box/base/entry.html" %}
{% load i18n %}
{% load staticfiles %}
{% get_current_language as LANGUAGE_CODE %}
{% block content %}
......@@ -19,7 +20,7 @@
</div>
<div class="actions">
<a href="#" class="remove" data-gid="{{group.id}}" data-neptun="{{member.code}}">
<img src="/static/icons/minus-circle.png" alt="{% trans 'Remove' %}" />
<img src="{% static "icons/minus-circle.png" %}" alt="{% trans 'Remove' %}" />
</a>
</div>
<div class="clear"></div>
......
{% extends "base.html" %}
{% load i18n %}
{% load staticfiles %}
{% get_current_language as LANGUAGE_CODE %}
{% block content %}
<div class="boxes">
......@@ -19,7 +20,7 @@
</div>
<!--<div class="actions">
<a href="#" class="remove" data-gid="{{group.id}}" data-neptun="{{owner.code}}">
<img src="/static/icons/minus-circle.png" alt="{% trans 'Remove' %}" />
<img src="{% static "icons/minus-circle.png" %}" alt="{% trans 'Remove' %}" />
</a>
</div>-->
<div class="clear"></div>
......
......@@ -98,8 +98,10 @@ def login(request):
co.save()
g.save()
try:
affiliation = request.META['affiliation']
except KeyError:
affiliation = ''
if affiliation == '':
affiliation = []
else:
......
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