Commit 12a8d210 by Guba Sándor

Merge branch 'feature-request' into 'master'

Request 

🙏

TODO
- send notifications
- send request to irc bot
- reason for decline?

See merge request !303
parents 8d01770a 41bf99d6
......@@ -355,6 +355,7 @@ LOCAL_APPS = (
'manager',
'acl',
'monitor',
'request',
)
# See: https://docs.djangoproject.com/en/dev/ref/settings/#installed-apps
......@@ -555,3 +556,4 @@ ADMIN_ENABLED = False
BLACKLIST_PASSWORD = get_env_variable("BLACKLIST_PASSWORD", "")
BLACKLIST_HOOK_URL = get_env_variable("BLACKLIST_HOOK_URL", "")
REQUEST_HOOK_URL = get_env_variable("REQUEST_HOOK_URL", "")
......@@ -56,6 +56,16 @@ LOGGING['handlers']['console'] = {'level': level,
'formatter': 'simple'}
for i in LOCAL_APPS:
LOGGING['loggers'][i] = {'handlers': ['console'], 'level': level}
# don't print SQL queries
LOGGING['handlers']['null'] = {'level': "DEBUG",
'class': "django.utils.log.NullHandler"}
LOGGING['loggers']['django.db.backends'] = {
'handlers': ['null'],
'propagate': False,
'level': 'DEBUG',
}
# Forbid store usage
STORE_URL = ""
......
......@@ -38,6 +38,7 @@ urlpatterns = patterns(
url(r'^network/', include('network.urls')),
url(r'^blacklist-add/', add_blacklist_item),
url(r'^dashboard/', include('dashboard.urls')),
url(r'^request/', include('request.urls')),
# django/contrib/auth/urls.py (care when new version)
url((r'^accounts/reset/(?P<uidb64>[0-9A-Za-z_\-]+)/'
......
......@@ -1395,6 +1395,7 @@
"vnc_port": 1234,
"num_cores": 2,
"status": "RUNNING",
"system": "system pls",
"modified": "2013-10-14T07:27:38.192Z"
}
},
......
......@@ -1272,8 +1272,46 @@ textarea[name="new_members"] {
margin-top: 20px;
}
#vm-renew-request-lease, #vm-request-resource-form {
display: none;
}
.label-100 {
display: block;
width: 100%;
}
#modify-the-resources {
font-size: 18px;
display: none;
}
#vm-request-resource-form textarea {
max-width: 500px;
height: 150px;
}
#disk-list-table {
td:last-child {
text-align: center;
}
}
#request-buttons {
form {
display: inline;
}
textarea {
resize: none;
min-height: 80px;
}
}
.nowrap {
white-space: nowrap;
}
.little-margin-bottom {
margin-bottom: 5px;
}
......@@ -223,4 +223,25 @@ $(function() {
return false;
});
$(document).on("click", "#vm-renew-request-lease-button", function(e) {
$("#vm-renew-request-lease").stop().slideToggle();
e.preventDefault();
});
$("#vm-request-resource").click(function(e) {
$(".cpu-priority-slider, .cpu-count-slider, .ram-slider").simpleSlider("setDisabled", false);
$(".ram-input, .cpu-count-input, .cpu-priority-input").prop("disabled", false);
$("#vm-details-resources-form").prop("action", $(this).prop("href"));
$("#vm-request-resource-form").show();
$("#modify-the-resources").show();
$(this).hide();
$("html, body").animate({
scrollTop: $("#modify-the-resources").offset().top - 60
});
return e.preventDefault();
});
});
......@@ -79,10 +79,26 @@
</div>
</div>
{% empty %}
{% trans "You can't start new virtual machines because no templates are shared with you." %}
{% if not template_access_types %}
{% trans "You can't start new virtual machines because no templates are shared with you." %}
{% else %}
{% trans "You can't start new virtual machines because no templates are shared with you however you can request them via the form below." %}
<hr />
{% include "request/_request-template-form.html" %}
{% endif %}
{% endfor %}
</div>
{% if templates and template_access_types %}
{% url "request.views.request-template" as request_url %}
<hr />
<p class="text-right">
{% blocktrans with url=request_url %}
Need other templates? Submit a new <a href="{{ url }}">request</a>.
{% endblocktrans %}
</p>
{% endif %}
<style>
.progress {
position: relative;
......
{% extends "dashboard/operate.html" %}
{% load i18n %}
{% load crispy_forms_tags %}
{% block formbuttons %}
<div class="pull-right">
<a class="btn btn-default" href="{{object.get_absolute_url}}" data-dismiss="modal">
{% trans "Cancel" %}
</a>
<a class="btn btn-primary" id="vm-renew-request-lease-button"
href="{% url "request.views.request-lease" vm_pk=object.pk %}">
<i class="fa fa-forward"></i>
{% trans "Request longer lease" %}
</a>
<button class="btn btn-{{ opview.effect }} btn-op-form-send" type="submit" id="op-form-send">
{% if opview.icon %}<i class="fa fa-fw fa-{{opview.icon}}"></i> {% endif %}{{ op.name|capfirst }}
</button>
</div>
{% endblock %}
{% block extra %}
<div class="clearfix"></div>
<div id="vm-renew-request-lease">
<hr />
{% include "request/_request-lease-form.html" with form=lease_request_form vm=object %}
</div>
{% endblock %}
......@@ -22,16 +22,29 @@
{% if user.is_superuser %}
{% if ADMIN_ENABLED %}
<li>
<a href="/admin/"><i class="fa fa-cogs"></i> {% trans "Admin" %}</a>
<a href="/admin/">
<i class="fa fa-cogs"></i>
<span class="hidden-sm">{% trans "Admin" %}</span>
</a>
</li>
{% endif %}
<li>
<a href="{% url "dashboard.views.storage" %}"><i class="fa fa-database"></i>
{% trans "Storage" %}
<a href="{% url "dashboard.views.storage" %}">
<i class="fa fa-database"></i>
<span class="hidden-sm">{% trans "Storage" %}</span>
</a>
</li>
<li>
<a href="/network/"><i class="fa fa-globe"></i> {% trans "Network" %}</a>
<a href="{% url "network.index" %}">
<i class="fa fa-globe"></i>
<span class="hidden-sm">{% trans "Network" %}</span>
</a>
</li>
<li>
<a href="{% url "request.views.request-list" %}">
<i class="fa fa-phone"></i>
<span class="hidden-sm">{% trans "Requests" %}</span>
</a>
</li>
{% endif %}
<li>
......
......@@ -16,6 +16,7 @@ Do you want to perform the following operation on
{% crispy form %}
{% endif %}
{% endblock %}
{% block formbuttons %}
<div class="pull-right">
<a class="btn btn-default" href="{{object.get_absolute_url}}"
data-dismiss="modal">{% trans "Cancel" %}</a>
......@@ -23,4 +24,7 @@ Do you want to perform the following operation on
{% if opview.icon %}<i class="fa fa-fw fa-{{opview.icon}}"></i> {% endif %}{{ op.name|capfirst }}
</button>
</div>
{% endblock %}
</form>
{% block extra %}{% endblock %}
......@@ -59,10 +59,11 @@
{% if instance.is_expiring %}<i class="fa fa-warning-sign text-danger"></i>{% endif %}
<span id="vm-details-renew-op">
{% with op=op.renew %}{% if op %}
<a href="{{op.get_url}}" class="btn btn-success btn-xs
<a href="{{op.get_url}}" class="btn btn-{{op.effect}} btn-xs
operation operation-{{op.op}}">
<i class="fa fa-{{op.icon}}"></i>
{{op.name}} </a>
{{op.name}}
</a>
{% endif %}{% endwith %}
</span>
</h4>
......
......@@ -2,19 +2,42 @@
{% load sizefieldtags %}
{% load crispy_forms_tags %}
<div class="label label-info label-100" id="modify-the-resources">
{% trans "Modify the resources" %}
</div>
<form method="POST" action="{{ op.resources_change.get_url }}" id="vm-details-resources-form">
{% csrf_token %}
{% include "dashboard/_resources-sliders.html" with field_priority=resources_form.priority field_num_cores=resources_form.num_cores field_ram_size=resources_form.ram_size %}
{% if op.resources_change %}
<button type="submit" class="btn btn-success btn-sm change-resources-button"
id="vm-details-resources-save" data-vm="{{ instance.pk }}"
{% if op.resources_change.disabled %}disabled{% endif %}>
<i class="fa fa-floppy-o"></i> {% trans "Save resources" %}
</button>
<span class="change-resources-help"
{% if not op.resources_change.disabled %}style="display: none;"{% endif %}
>{% trans "Stop your VM to change resources." %}</span>
<button type="submit" class="btn btn-success btn-sm change-resources-button"
id="vm-details-resources-save" data-vm="{{ instance.pk }}"
{% if op.resources_change.disabled %}disabled{% endif %}>
<i class="fa fa-floppy-o"></i> {% trans "Save resources" %}
</button>
<span class="change-resources-help"
{% if not op.resources_change.disabled %}style="display: none;"{% endif %}>
{% trans "Stop your VM to change resources." %}
</span>
{% else %}
<div id="vm-request-resource-form">
<div class="alert alert-info text-justify">
{% trans "Changing resources is only possible on virtual machines with STOPPED state. We suggest to turn off the VM after submitting the request otherwise it will be automatically stopped in the future when the request is accepted." %}
</div>
<div class="form-group">
<label>{% trans "Message" %}*</label>
<textarea class="form-control" name="message">{% include "request/initials/resources.html" %}</textarea>
</div>
<input type="submit" class="btn btn-success btn-sm"/>
</div>
<a href="{% url "request.views.request-resource" vm_pk=object.pk %}"
class="btn btn-primary btn-sm" id="vm-request-resource">
<i class="fa fa-tasks"></i>
{% trans "Request resources" %}
</a>
{% endif %}
</form>
......
......@@ -20,8 +20,7 @@ import json
# from unittest import skip
from django.test import TestCase
from django.test.client import Client
from django.contrib.auth.models import User, Group
from django.contrib.auth.models import Permission
from django.contrib.auth.models import User, Group, Permission
from django.contrib.auth import authenticate
from common.tests.celery_mock import MockCeleryMixin
......
......@@ -228,7 +228,6 @@ urlpatterns = patterns(
url(r'^vm/opensearch.xml$', OpenSearchDescriptionView.as_view(),
name="dashboard.views.vm-opensearch"),
url(r'^storage/$', StorageDetail.as_view(),
name="dashboard.views.storage"),
url(r'^disk/(?P<pk>\d+)/$', DiskDetail.as_view(),
......
......@@ -13,3 +13,4 @@ from util import *
from vm import *
from graph import *
from storage import *
from request import *
......@@ -66,6 +66,8 @@ from ..forms import (
VmPortRemoveForm, VmPortAddForm,
VmRemoveInterfaceForm,
)
from request.models import TemplateAccessType
from request.forms import LeaseRequestForm, TemplateRequestForm
from ..models import Favourite
from manager.scheduler import has_traits
......@@ -651,10 +653,12 @@ class VmRenewView(FormOperationMixin, TokenOperationView, VmOperationView):
op = 'renew'
icon = 'calendar'
effect = 'info'
effect = 'success'
show_in_toolbar = False
form_class = VmRenewForm
wait_for_result = 0.5
template_name = 'dashboard/_vm-renew.html'
with_reload = True
def get_form_kwargs(self):
choices = Lease.get_objects_with_level("user", self.request.user)
......@@ -674,6 +678,11 @@ class VmRenewView(FormOperationMixin, TokenOperationView, VmOperationView):
instance.time_of_suspend)
return extra
def get_context_data(self, **kwargs):
context = super(VmRenewView, self).get_context_data(**kwargs)
context['lease_request_form'] = LeaseRequestForm(request=self.request)
return context
class VmStateChangeView(FormOperationMixin, VmOperationView):
op = 'emergency_change_state'
......@@ -1043,6 +1052,8 @@ class VmCreate(LoginRequiredMixin, TemplateView):
'box_title': _('Create a VM'),
'ajax_title': True,
'templates': templates.all(),
'template_access_types': TemplateAccessType.objects.exists(),
'form': TemplateRequestForm(request=request),
})
return self.render_to_response(context)
......
......@@ -6,9 +6,9 @@ msgid ""
msgstr ""
"Project-Id-Version: \n"
"Report-Msgid-Bugs-To: \n"
"POT-Creation-Date: 2015-03-05 14:32+0100\n"
"PO-Revision-Date: 2015-03-05 14:42+0116\n"
"Last-Translator: Daniel Bach <bd@doszgep.hu>\n"
"POT-Creation-Date: 2015-03-30 10:46+0200\n"
"PO-Revision-Date: 2015-03-30 12:58+0116\n"
"Last-Translator: Elek Elekebb EEeee <viktorvector@gmail.com>\n"
"Language-Team: Hungarian <cloud@ik.bme.hu>\n"
"MIME-Version: 1.0\n"
"Content-Type: text/plain; charset=UTF-8\n"
......@@ -32,79 +32,80 @@ msgstr "Hiba."
#: common/models.py:72
#, python-format
msgid "Unhandled exception: %(error)s"
msgstr "Kezeletlen kivétel: %(error)s"
#| msgid "Unhandled exception: %(error)s"
msgid "Unhandled exception: %(e)s: %(error)s"
msgstr "Kezeletlen kivétel: %(e)s: %(error)s"
#: common/models.py:147
#: common/models.py:148
#: dashboard/templates/dashboard/instanceactivity_detail.html:28
msgid "activity code"
msgstr "tevékenységkód"
#: common/models.py:150
#: common/models.py:151
msgid "human readable name"
msgstr "olvasható név"
#: common/models.py:151
#: common/models.py:152
msgid "Human readable name of activity."
msgstr "A tevékenység neve olvasható formában."
#: common/models.py:155
#: common/models.py:156
msgid "Celery task unique identifier."
msgstr "Celery feladat egyedi azonosítója."
#: common/models.py:156
#: common/models.py:157
msgid "task_uuid"
msgstr "feladat uuid"
#: common/models.py:157
#: common/models.py:158
#: dashboard/templates/dashboard/instanceactivity_detail.html:37
#: firewall/models.py:284 vm/models/common.py:84 vm/models/instance.py:130
#: vm/models/instance.py:211
#: firewall/models.py:284 request/models.py:223 vm/models/common.py:84
#: vm/models/instance.py:130 vm/models/instance.py:211
msgid "user"
msgstr "felhasználó"
#: common/models.py:158
#: common/models.py:159
msgid "The person who started this activity."
msgstr "A tevékenységet indító felhasználó."
#: common/models.py:159
#: common/models.py:160
msgid "started at"
msgstr "indítás ideje"
#: common/models.py:161
#: common/models.py:162
msgid "Time of activity initiation."
msgstr "A tevékenység megkezdésének időpontja."
#: common/models.py:162
#: common/models.py:163
msgid "finished at"
msgstr "befejezés ideje"
#: common/models.py:164
#: common/models.py:165
msgid "Time of activity finalization."
msgstr "A tevékenység befejeztének ideje."
#: common/models.py:166
#: common/models.py:167
msgid "True, if the activity has finished successfully."
msgstr "Igaz, ha a tevékenység sikeresen befejeződött."
#: common/models.py:168
#: common/models.py:169
#: dashboard/templates/dashboard/instanceactivity_detail.html:56
msgid "result"
msgstr "eredmény"
#: common/models.py:170
#: common/models.py:171
msgid "Human readable result of activity."
msgstr "A tevékenység eredménye olvasható formában."
#: common/models.py:535
#: common/models.py:536
msgid "Permission Denied"
msgstr "Hozzáférés megtagadva"
#: common/models.py:537
#: common/models.py:538
msgid "Unknown error"
msgstr "Ismeretlen hiba"
#: common/models.py:538
#: common/models.py:539
#, python-format
msgid "Unknown error: %(ex)s"
msgstr "Ismeretlen hiba: %(ex)s"
......@@ -139,12 +140,12 @@ msgid "realtime"
msgstr "valós idejű"
#: dashboard/forms.py:93 dashboard/forms.py:810 dashboard/forms.py:900
#: dashboard/forms.py:1351 dashboard/tables.py:268
#: dashboard/forms.py:1351 dashboard/tables.py:270
#: dashboard/templates/dashboard/_vm-create-2.html:20
#: dashboard/templates/dashboard/vm-detail/home.html:9
#: dashboard/templates/dashboard/vm-list.html:62 firewall/models.py:296
#: network/templates/network/index.html:24
#: network/templates/network/switch-port-edit.html:45
#: network/templates/network/switch-port-edit.html:45 request/models.py:57
msgid "Name"
msgstr "Név"
......@@ -195,6 +196,8 @@ msgstr ""
#: network/templates/network/switch-port-create.html:8
#: network/templates/network/vlan-create.html:8
#: network/templates/network/vlan-group-create.html:8
#: request/templates/request/lease-type-form.html:7
#: request/templates/request/template-type-form.html:7
msgid "Create"
msgstr "Létrehozás"
......@@ -212,6 +215,7 @@ msgstr "Létrehozás"
#: network/forms.py:86 network/forms.py:100 network/forms.py:122
#: network/forms.py:162 network/forms.py:187 network/forms.py:226
#: network/forms.py:247 network/forms.py:298 network/forms.py:323
#: request/forms.py:38 request/forms.py:54
msgid "Save"
msgstr "Mentés"
......@@ -223,7 +227,7 @@ msgstr "Gép"
#: dashboard/forms.py:383 dashboard/forms.py:781 dashboard/forms.py:991
#: dashboard/templates/dashboard/node-detail.html:5
#: dashboard/templates/dashboard/vm-detail/home.html:117
#: dashboard/templates/dashboard/vm-detail/home.html:118
#: dashboard/templates/dashboard/vm-list.html:87
msgid "Node"
msgstr "Csomópont"
......@@ -483,6 +487,7 @@ msgstr "összes"
#: dashboard/templates/dashboard/index-templates.html:40
#: dashboard/templates/dashboard/index-users.html:28
#: dashboard/templates/dashboard/index-vm.html:64
#: dashboard/templates/dashboard/storage/detail.html:91
#: network/templates/network/host-list.html:39
msgid "Search..."
msgstr "Keresés..."
......@@ -521,8 +526,8 @@ msgstr "elérés módja"
msgid "Type of the remote access method."
msgstr "Távoli elérési mód típusa."
#: dashboard/models.py:121 firewall/models.py:528 firewall/models.py:554
#: firewall/models.py:936 firewall/models.py:975 firewall/models.py:995
#: dashboard/models.py:121 firewall/models.py:533 firewall/models.py:564
#: firewall/models.py:951 firewall/models.py:995 firewall/models.py:1020
#: storage/models.py:49 storage/models.py:120 vm/models/common.py:65
#: vm/models/common.py:89 vm/models/common.py:165 vm/models/instance.py:134
#: vm/models/instance.py:224 vm/models/node.py:121
......@@ -545,69 +550,69 @@ msgstr ""
"Sablon a csatlakozási parancshoz. Elérhető paraméterek: username, password, "
"host, port."
#: dashboard/models.py:137
#: dashboard/models.py:140
msgid "preferred language"
msgstr "választott nyelv"
#: dashboard/models.py:143 dashboard/models.py:228
#: dashboard/models.py:146 dashboard/models.py:232
msgid "Unique identifier of the person, e.g. a student number."
msgstr "A személy egyedi azonosítója, például hallgatói azonosító."
#: dashboard/models.py:146
#: dashboard/models.py:149
msgid "Use Gravatar"
msgstr "Gravatar használata"
#: dashboard/models.py:147
#: dashboard/models.py:150
msgid "Whether to use email address as Gravatar profile image"
msgstr "Használható-e az e-mail cím a Gravatar profilkép betöltésére"
#: dashboard/models.py:149
#: dashboard/models.py:152
msgid "Email notifications"
msgstr "E-mail értesítések"
#: dashboard/models.py:150
#: dashboard/models.py:153
msgid "Whether user wants to get digested email notifications."
msgstr "A felhasználó kéri-e tömbösített e-mail értesítések küldését."
#: dashboard/models.py:153
#: dashboard/models.py:156
msgid "Samba password"
msgstr "Samba jelszó"
#: dashboard/models.py:155
#: dashboard/models.py:158
msgid "Generated password for accessing store from virtual machines."
msgstr "A tárhely virtuális gépekről való eléréséhez generált jelszó."
#: dashboard/models.py:160
#: dashboard/models.py:163
msgid "disk quota"
msgstr "lemezkvóta"
#: dashboard/models.py:162
#: dashboard/models.py:165
msgid "Disk quota in mebibytes."
msgstr "Lemezkvóta mebibyte-okban."
#: dashboard/models.py:222
#: dashboard/models.py:226
msgid "Can use autocomplete."
msgstr "Használhat automatikus kiegészítést."
#: dashboard/models.py:240 firewall/models.py:285 vm/models/common.py:85
#: vm/models/instance.py:131 vm/models/instance.py:212
#: dashboard/models.py:245 firewall/models.py:285 request/models.py:224
#: vm/models/common.py:85 vm/models/instance.py:131 vm/models/instance.py:212
msgid "operator"
msgstr "operátor"
#: dashboard/models.py:241 firewall/models.py:105 firewall/models.py:390
#: firewall/models.py:537 firewall/models.py:559 firewall/models.py:623
#: firewall/models.py:976 firewall/models.py:1004 vm/models/common.py:86
#: dashboard/models.py:246 firewall/models.py:105 firewall/models.py:390
#: firewall/models.py:542 firewall/models.py:569 firewall/models.py:638
#: firewall/models.py:996 firewall/models.py:1029 vm/models/common.py:86
#: vm/models/instance.py:132 vm/models/instance.py:213
msgid "owner"
msgstr "tulajdonos"
#: dashboard/models.py:247
#: dashboard/models.py:252
msgid "Unique identifier of the group at the organization."
msgstr "A csoport egyedi szervezeti azonosítója."
#. Translators: [T] as Template
#: dashboard/tables.py:53 dashboard/tables.py:308
#: dashboard/templates/dashboard/vm-detail/home.html:130
#: dashboard/tables.py:53 dashboard/tables.py:310
#: dashboard/templates/dashboard/vm-detail/home.html:131
msgid "Template"
msgstr "Sablon"
......@@ -616,7 +621,8 @@ msgid "[T]"
msgstr "[S]"
#. Translators: [VM] as Virtual Machine
#: dashboard/tables.py:56
#: dashboard/tables.py:56 request/templates/request/request-lease.html:17
#: request/templates/request/request-resource.html:20
msgid "Virtual machine"
msgstr "Virtuális gép"
......@@ -628,7 +634,8 @@ msgstr ""
msgid "Overcommit"
msgstr "Túlfoglalás"
#: dashboard/tables.py:73
#: dashboard/tables.py:73 request/tables.py:35
#: request/templates/request/detail.html:71
msgid "Status"
msgstr "Állapot"
......@@ -649,35 +656,36 @@ msgstr "Elérhető minionok"
msgid "Number of users"
msgstr "Felhasználók száma"
#: dashboard/tables.py:134 dashboard/templates/dashboard/base.html:25
#: dashboard/tables.py:134 dashboard/templates/dashboard/base.html:27
msgid "Admin"
msgstr "Adminisztráció"
#: dashboard/tables.py:141 dashboard/tables.py:218 dashboard/tables.py:249
#: dashboard/tables.py:283 dashboard/tables.py:312 network/tables.py:272
#: dashboard/tables.py:141 dashboard/tables.py:220 dashboard/tables.py:251
#: dashboard/tables.py:285 dashboard/tables.py:314 network/tables.py:272
msgid "Actions"
msgstr "Műveletek"
#: dashboard/tables.py:163 dashboard/templates/dashboard/profile.html:37
#: dashboard/tables.py:164 dashboard/templates/dashboard/profile.html:37
msgid "Organization ID"
msgstr "Címtári azonosító"
#: dashboard/tables.py:168
#: dashboard/tables.py:169
msgid "<abbr data-placement=\"left\" title=\"Superuser status\">SU</abbr>"
msgstr "<abbr data-placement=\"left\" title=\"Rendszergazda státusz\">SU</abbr>"
#: dashboard/tables.py:188 dashboard/templates/dashboard/_vm-create-2.html:38
#: dashboard/tables.py:190 dashboard/templates/dashboard/_vm-create-2.html:38
#: dashboard/templates/dashboard/node-detail.html:72
#: dashboard/templates/dashboard/vm-detail.html:200
msgid "Resources"
msgstr "Erőforrások"
#: dashboard/tables.py:194 dashboard/templates/dashboard/vm-list.html:74
#: dashboard/tables.py:196 dashboard/templates/dashboard/vm-list.html:74
#: request/forms.py:85 request/models.py:148 request/tables.py:63
#: vm/models/instance.py:104
msgid "Lease"
msgstr "Bérlet"
#: dashboard/tables.py:205 dashboard/templates/dashboard/template-edit.html:85
#: dashboard/tables.py:207 dashboard/templates/dashboard/template-edit.html:85
#: dashboard/templates/dashboard/template-edit.html:133
#: dashboard/templates/dashboard/vm-detail/access.html:2
#: dashboard/templates/dashboard/vm-detail/access.html:37
......@@ -685,31 +693,31 @@ msgstr "Bérlet"
msgid "Owner"
msgstr "Tulajdonos"
#: dashboard/tables.py:210 dashboard/tables.py:278
#: dashboard/tables.py:212 dashboard/tables.py:280
msgid "Created at"
msgstr "Létrehozva"
#: dashboard/tables.py:214
#: dashboard/tables.py:216
msgid "Running"
msgstr "Fut"
#: dashboard/tables.py:261
#: dashboard/tables.py:263
msgid "No available leases."
msgstr "Nincs elérhető bérlési mód."
#: dashboard/tables.py:273
#: dashboard/tables.py:275
msgid "Fingerprint"
msgstr "Ujjlenyomat"
#: dashboard/tables.py:294
#: dashboard/tables.py:296
msgid "You haven't added any public keys yet."
msgstr "Még nem adott meg publikus kulcsot."
#: dashboard/tables.py:304
#: dashboard/tables.py:306
msgid "Access method"
msgstr "Elérés módja"
#: dashboard/tables.py:325
#: dashboard/tables.py:327
msgid ""
"You don't have any custom connection commands yet. You can specify commands "
"to be displayed on VM detail pages instead of the defaults."
......@@ -717,18 +725,25 @@ msgstr ""
"Még nincs egyedi csatlakozási parancsa. Az itt megadott parancsok fognak "
"megjelenni a VM-részletező oldalon az alapértelmezettek helyett."
#: dashboard/tables.py:334 dashboard/templates/dashboard/vm-list.html:58
#: dashboard/tables.py:336 dashboard/templates/dashboard/vm-list.html:58
#: request/tables.py:31 request/tables.py:61 request/tables.py:77
msgid "ID"
msgstr "ID"
#: dashboard/tables.py:339 dashboard/templates/dashboard/storage/disk.html:18
#: dashboard/tables.py:341 dashboard/templates/dashboard/storage/disk.html:18
msgid "Appliance"
msgstr "Felhasználás"
#: dashboard/tables.py:343
#: dashboard/tables.py:345
msgid "ready"
msgstr "kész"
#: dashboard/tables.py:356
#, fuzzy
#| msgid "No related rules found."
msgid "No disk found."
msgstr "Nincs kapcsolódó szabály."
#: dashboard/tasks/local_periodic_tasks.py:60
#, python-format
msgid "%d new notification"
......@@ -789,10 +804,11 @@ msgstr ""
" "
#: dashboard/templates/dashboard/_client-check.html:23
#: dashboard/templates/dashboard/_vm-renew.html:9
#: dashboard/templates/dashboard/confirm/ajax-delete.html:19
#: dashboard/templates/dashboard/confirm/base-delete.html:33
#: dashboard/templates/dashboard/mass-operate.html:33
#: dashboard/templates/dashboard/operate.html:21
#: dashboard/templates/dashboard/operate.html:22
#: dashboard/templates/dashboard/store/remove.html:34
msgid "Cancel"
msgstr "Mégsem"
......@@ -949,14 +965,14 @@ msgstr "Memória"
#: dashboard/templates/dashboard/_vm-create-1.html:39
#: dashboard/templates/dashboard/_vm-create-2.html:49
#: dashboard/templates/dashboard/storage/detail.html:68
#: dashboard/templates/dashboard/vm-detail/resources.html:25
#: dashboard/templates/dashboard/storage/detail.html:70
#: dashboard/templates/dashboard/vm-detail/resources.html:48
msgid "Disks"
msgstr "Lemezek"
#: dashboard/templates/dashboard/_vm-create-1.html:46
#: dashboard/templates/dashboard/_vm-create-2.html:65
#: dashboard/templates/dashboard/base.html:34
#: dashboard/templates/dashboard/base.html:40
#: dashboard/templates/dashboard/vm-detail.html:214
#: dashboard/views/graph.py:198 dashboard/views/graph.py:221
#: network/forms.py:142 network/templates/network/base.html:7
......@@ -964,7 +980,7 @@ msgid "Network"
msgstr "Hálózat"
#: dashboard/templates/dashboard/_vm-create-1.html:52
#: network/templates/network/index.html:46
#: network/templates/network/index.html:46 request/tables.py:43
msgid "Type"
msgstr "Típus"
......@@ -978,19 +994,39 @@ msgstr "Testreszabás"
msgid "Start"
msgstr "Indítás"
#: dashboard/templates/dashboard/_vm-create-1.html:82
#: dashboard/templates/dashboard/_vm-create-1.html:83
msgid ""
"You can't start new virtual machines because no templates are shared with "
"you."
msgstr ""
"Még nem tud virtuális gépet indítani, mivel egy sablonhoz sincs hozzáférése."
#: dashboard/templates/dashboard/_vm-create-1.html:85
#| msgid " new virtual machines because no templates are shared with ."
msgid ""
"You can't start new virtual machines because no templates are shared with "
"you however you can request them via the form below."
msgstr ""
"Még nem tud virtuális gépet indítani, mivel egy sablonhoz sincs hozzáférése "
"azonban a lenti űrlap segítségével igényelhet."
#: dashboard/templates/dashboard/_vm-create-1.html:96
#, python-format
#| msgid " owner of this template is <a href=\"%(url)s\">ame)s er)s)</a>.\n"
msgid ""
"\n"
" Need other templates? Submit a new <a href=\"%(url)s\">request</a>.\n"
" "
msgstr ""
"\n"
"Másfajta sablonra van szüksége? <a href=\"%(url)s\">Igényeljen</a>."
#: dashboard/templates/dashboard/_vm-create-2.html:30
msgid "Amount"
msgstr "Mennyiség"
#: dashboard/templates/dashboard/_vm-create-2.html:56
#: dashboard/templates/dashboard/vm-detail/resources.html:35
#: dashboard/templates/dashboard/vm-detail/resources.html:58
msgid "No disks are added."
msgstr "Egy lemez sincs hozzáadva."
......@@ -1043,10 +1079,14 @@ msgid "Node traits"
msgstr "Csomópontjellemzők"
#: dashboard/templates/dashboard/_vm-migrate.html:46
#: dashboard/templates/dashboard/vm-detail/resources.html:52
#: dashboard/templates/dashboard/vm-detail/resources.html:75
msgid "Required traits"
msgstr "Elvárt jellemzők"
#: dashboard/templates/dashboard/_vm-renew.html:14
msgid "Request longer lease"
msgstr "Hosszabb bérlet igénylése"
#: dashboard/templates/dashboard/_vm-save.html:7
msgid ""
"\n"
......@@ -1059,28 +1099,35 @@ msgstr ""
msgid "Name of template"
msgstr "Sablon neve"
#: dashboard/templates/dashboard/base.html:30
#: dashboard/templates/dashboard/base.html:34
#: dashboard/templates/dashboard/storage/detail.html:7
#: dashboard/templates/dashboard/storage/disk.html:7
msgid "Storage"
msgstr "Tárhely"
#: dashboard/templates/dashboard/base.html:45
#: dashboard/templates/dashboard/base.html:46
#: request/templates/request/list.html:6
#: request/templates/request/list.html:17
#| msgid "Required traits"
msgid "Requests"
msgstr "Igénylések"
#: dashboard/templates/dashboard/base.html:58
msgid "Log out"
msgstr "Kijelentkezés"
#: dashboard/templates/dashboard/base.html:50
#: dashboard/templates/dashboard/base.html:60
#: dashboard/templates/dashboard/base.html:63
#: dashboard/templates/dashboard/base.html:73
#: dashboard/templates/dashboard/notifications.html:4
#: dashboard/templates/dashboard/notifications.html:24
msgid "Notifications"
msgstr "Értesítések"
#: dashboard/templates/dashboard/base.html:68
#: dashboard/templates/dashboard/base.html:81
msgid "Loading..."
msgstr "Betöltés..."
#: dashboard/templates/dashboard/base.html:74
#: dashboard/templates/dashboard/base.html:87
msgid "Log in "
msgstr "Bejelentkezés"
......@@ -1114,6 +1161,8 @@ msgstr ""
#: dashboard/templates/dashboard/template-list/column-lease-actions.html:5
#: dashboard/templates/dashboard/template-list/column-template-actions.html:9
#: dashboard/templates/dashboard/userkey-list/column-userkey-actions.html:5
#: request/templates/request/lease-type-form.html:21
#: request/templates/request/template-type-form.html:21
msgid "Delete"
msgstr "Törlés"
......@@ -1200,6 +1249,9 @@ msgstr "Parancssablon létrehozása"
#: network/forms.py:87 network/forms.py:101 network/forms.py:123
#: network/forms.py:163 network/forms.py:188 network/forms.py:227
#: network/forms.py:248 network/forms.py:299 network/forms.py:324
#: request/templates/request/detail.html:17
#: request/templates/request/lease-type-form.html:25
#: request/templates/request/template-type-form.html:25
msgid "Back"
msgstr "Vissza"
......@@ -1362,8 +1414,8 @@ msgstr ""
#: dashboard/templates/dashboard/index-templates.html:7
#: dashboard/templates/dashboard/template-list.html:6
#: dashboard/templates/dashboard/template-list.html:17
#: templates/info/help.html:156
#: dashboard/templates/dashboard/template-list.html:17 request/models.py:162
#: request/tables.py:81 templates/info/help.html:156
msgid "Templates"
msgstr "Sablonok"
......@@ -1515,7 +1567,7 @@ msgid "time"
msgstr "idő"
#: dashboard/templates/dashboard/instanceactivity_detail.html:40
#: firewall/models.py:1000 network/tables.py:181
#: firewall/models.py:1025 network/tables.py:181
msgid "type"
msgstr "típus"
......@@ -1557,6 +1609,7 @@ msgid "failed"
msgstr "meghiúsult"
#: dashboard/templates/dashboard/instanceactivity_detail.html:78
#: dashboard/views/storage.py:59
msgid "none"
msgstr "nincs"
......@@ -1629,6 +1682,16 @@ msgstr "Kezdőoldal"
msgid "Virtual Machines"
msgstr "Virtuális gépek"
#: dashboard/templates/dashboard/node-detail/_activity-timeline.html:47
#: dashboard/templates/dashboard/vm-detail/_activity-timeline.html:65
msgid "Show less activities"
msgstr "Kevesebb tevékenység megjelenítése"
#: dashboard/templates/dashboard/node-detail/_activity-timeline.html:49
#: dashboard/templates/dashboard/vm-detail/_activity-timeline.html:67
msgid "Show all activities"
msgstr "Összes tevékenység megjelenítése"
#: dashboard/templates/dashboard/node-detail/home.html:4
msgid "Traits the node provides"
msgstr "A csomópont által biztosított jellemzők"
......@@ -1646,7 +1709,7 @@ msgid "CPU cores"
msgstr "CPU-magok"
#: dashboard/templates/dashboard/node-detail/resources.html:7
#: vm/models/common.py:43
#: request/models.py:175 vm/models/common.py:43
msgid "RAM size"
msgstr "RAM-méret"
......@@ -1663,6 +1726,7 @@ msgid "Host online"
msgstr "Gép elérhető"
#: dashboard/templates/dashboard/node-detail/resources.html:13
#: request/templates/request/detail.html:79
msgid "Priority"
msgstr "Prioritás"
......@@ -1840,7 +1904,7 @@ msgid "disk objects without images files"
msgstr "lemezkép nélküli lemez objektumok"
#: dashboard/templates/dashboard/storage/detail.html:47
#: dashboard/templates/dashboard/storage/detail.html:57
#: dashboard/templates/dashboard/storage/detail.html:59
msgid "None"
msgstr "Nincs"
......@@ -1852,6 +1916,19 @@ msgstr "Árva lemezek"
msgid "image files without disk object in the database"
msgstr ""
#: dashboard/templates/dashboard/storage/detail.html:76
#: network/templates/network/record-list.html:21
msgid "Filter by type"
msgstr "Típus szerinti szűrés"
#: dashboard/templates/dashboard/storage/detail.html:78
#: network/templates/network/host-list.html:26
#: network/templates/network/record-list.html:22
#: network/templates/network/rule-list.html:23
#: request/templates/request/list.html:22
msgid "ALL"
msgstr "MIND"
#: dashboard/templates/dashboard/store/_list-box.html:9
#: dashboard/templates/dashboard/store/_list-box.html:27
#: dashboard/templates/dashboard/store/upload.html:4
......@@ -1943,7 +2020,7 @@ msgstr "Felsorolás"
#: dashboard/templates/dashboard/store/list.html:5
#: dashboard/templates/dashboard/store/upload.html:4
#: dashboard/templates/dashboard/vm-detail/home.html:147
#: dashboard/templates/dashboard/vm-detail/home.html:148
msgid "Store"
msgstr "Tárhely"
......@@ -2009,7 +2086,8 @@ msgid "Currently uploading to"
msgstr "Feltöltés helye:"
#: dashboard/templates/dashboard/template-edit.html:7
#: vm/models/instance.py:157 vm/models/instance.py:230 vm/models/network.py:44
#: dashboard/views/storage.py:58 vm/models/instance.py:157
#: vm/models/instance.py:230 vm/models/network.py:44
msgid "template"
msgstr "sablon"
......@@ -2049,7 +2127,7 @@ msgid "Access level rights"
msgstr "Hozzáférési jogosultsági szintek"
#: dashboard/templates/dashboard/template-edit.html:121
#: dashboard/templates/dashboard/vm-detail/access.html:27
#: dashboard/templates/dashboard/vm-detail/access.html:27 request/tables.py:39
msgid "User"
msgstr "Felhasználó"
......@@ -2283,14 +2361,6 @@ msgstr "Hozzáférés"
msgid "Abort"
msgstr "Megszakítás"
#: dashboard/templates/dashboard/vm-detail/_activity-timeline.html:65
msgid "Show less activities"
msgstr "Kevesebb tevékenység megjelenítése"
#: dashboard/templates/dashboard/vm-detail/_activity-timeline.html:67
msgid "Show all activities"
msgstr "Összes tevékenység megjelenítése"
#: dashboard/templates/dashboard/vm-detail/_network-port-add.html:17
msgid "Add"
msgstr "Hozzáadás"
......@@ -2379,23 +2449,23 @@ msgstr "Frissítés"
msgid "Expiration"
msgstr "Lejárat"
#: dashboard/templates/dashboard/vm-detail/home.html:70
#: dashboard/templates/dashboard/vm-detail/home.html:71
msgid "Suspended at:"
msgstr "Felfüggesztve:"
#: dashboard/templates/dashboard/vm-detail/home.html:76
#: dashboard/templates/dashboard/vm-detail/home.html:77
msgid "Destroyed at:"
msgstr "Megsemmisítve:"
#: dashboard/templates/dashboard/vm-detail/home.html:85
#: dashboard/templates/dashboard/vm-detail/home.html:86
msgid "Tags"
msgstr "Címkék"
#: dashboard/templates/dashboard/vm-detail/home.html:98
#: dashboard/templates/dashboard/vm-detail/home.html:99
msgid "No tag added."
msgstr "Nincs címke."
#: dashboard/templates/dashboard/vm-detail/home.html:110
#: dashboard/templates/dashboard/vm-detail/home.html:111
msgid "Add tag"
msgstr "Címke hozzáadása"
......@@ -2416,12 +2486,12 @@ msgid "edit"
msgstr "szerkesztés"
#: dashboard/templates/dashboard/vm-detail/network.html:37
#: firewall/models.py:595
#: firewall/models.py:610
msgid "IPv4 address"
msgstr "IPv4 cím"
#: dashboard/templates/dashboard/vm-detail/network.html:38
#: firewall/models.py:605
#: firewall/models.py:620
msgid "IPv6 address"
msgstr "IPv6 cím"
......@@ -2452,15 +2522,41 @@ msgstr "A VM-nek nincs IPv6 címe."
msgid "Edit raw data"
msgstr "Nyers adat szerkesztése"
#: dashboard/templates/dashboard/vm-detail/resources.html:13
#: dashboard/templates/dashboard/vm-detail/resources.html:7
#| msgid "Change resources"
msgid "Modify the resources"
msgstr "Módosítsa az erőforrásokat"
#: dashboard/templates/dashboard/vm-detail/resources.html:17
msgid "Save resources"
msgstr "Erőforrások mentése"
#: dashboard/templates/dashboard/vm-detail/resources.html:17
#: dashboard/templates/dashboard/vm-detail/resources.html:21
msgid "Stop your VM to change resources."
msgstr "Állítsa le a VM-et az erőforrások módosításához."
#: dashboard/templates/dashboard/vm-detail/resources.html:64
#: dashboard/templates/dashboard/vm-detail/resources.html:26
msgid ""
"Changing resources is only possible on virtual machines with STOPPED state. "
"We suggest to turn off the VM after submitting the request otherwise it will"
" be automatically stopped in the future when the request is accepted."
msgstr ""
"Erőforrás módosítás csak LEÁLLÍTVA állapotú gépen lehetséges. A virtuális "
"gépet ajánlott leállítani a kérés beküldése után másképpen valamikor a "
"jövőben, a kérés elfogadásakor a lesz automatikusan leállítva."
#: dashboard/templates/dashboard/vm-detail/resources.html:29
#: request/forms.py:79 request/models.py:82
#| msgid "RAM usage"
msgid "Message"
msgstr "Üzenet"
#: dashboard/templates/dashboard/vm-detail/resources.html:38
#| msgid "Save resources"
msgid "Request resources"
msgstr "Erőforrások igénylése"
#: dashboard/templates/dashboard/vm-detail/resources.html:87
msgid "Raw data"
msgstr "Nyers adat"
......@@ -2511,6 +2607,8 @@ msgid ""
" %(current)s/%(total)s\n"
" "
msgstr ""
"\n"
"%(current)s/%(total)s"
#: dashboard/validators.py:74
msgid "Invalid template string."
......@@ -2569,26 +2667,35 @@ msgstr "A csoport létrehozásra került."
msgid "Group is successfully updated."
msgstr "A csoport frissítésre került."
#: dashboard/views/node.py:127
#: dashboard/views/node.py:128
msgid "Node successfully renamed."
msgstr "A csomópont átnevezésre került."
#: dashboard/views/node.py:217
#: dashboard/views/node.py:218
msgid "Create a node"
msgstr "Új csomópont hozzáadása"
#: dashboard/views/node.py:241
#: dashboard/views/node.py:242
msgid "Node successfully created."
msgstr "A csomópont létrehozásra került."
#: dashboard/views/node.py:252
#: dashboard/views/node.py:253
msgid "Node successfully deleted."
msgstr "A csomópont törlésre került."
#: dashboard/views/node.py:288
#: dashboard/views/node.py:289
msgid "Trait successfully added to node."
msgstr "A csomópontjellemző hozzáadásra került."
#: dashboard/views/storage.py:51
msgid "The DataStore is offline."
msgstr "Az adattár nem elérhető."
#: dashboard/views/storage.py:57
#| msgid "Virtual machine"
msgid "virtual machine"
msgstr "virtuális gép"
#: dashboard/views/store.py:73
msgid "No store."
msgstr "Nincs tárhely."
......@@ -2863,65 +2970,65 @@ msgstr "%(instance)s gépre vonatkozó átruházási ajánlatát elfogadta %(own
msgid "Only the owners can delete the selected object."
msgstr "Csak a tulajdonos törölheti a kiválasztott objektumot."
#: dashboard/views/vm.py:88
#: dashboard/views/vm.py:90
msgid "console access"
msgstr "konzolhozzáférés"
#: dashboard/views/vm.py:197
#: dashboard/views/vm.py:199
msgid "VM successfully renamed."
msgstr "A virtuális gép átnevezésre került."
#: dashboard/views/vm.py:221
#: dashboard/views/vm.py:223
msgid "VM description successfully updated."
msgstr "A VM leírása megváltoztatásra került."
#: dashboard/views/vm.py:609
#: dashboard/views/vm.py:611
msgid "The token has expired."
msgstr "A token lejárt."
#: dashboard/views/vm.py:827
#: dashboard/views/vm.py:836
#, python-format
msgid "Failed to execute %(op)s operation on instance %(instance)s."
msgstr "%(op)s végrehajtása meghiúsult a következőn: %(instance)s."
#: dashboard/views/vm.py:843
#: dashboard/views/vm.py:852
#, python-format
msgid "You are not permitted to execute %(op)s on instance %(instance)s."
msgstr "Nem engedélyezett a(z) %(op)s végrehajtása a(z) %(instance)s gépen."
#: dashboard/views/vm.py:1035
#: dashboard/views/vm.py:1044
msgid "Customize VM"
msgstr "VM testreszabása"
#: dashboard/views/vm.py:1043
#: dashboard/views/vm.py:1052
msgid "Create a VM"
msgstr "VM létrehozása"
#: dashboard/views/vm.py:1096
#: dashboard/views/vm.py:1107
#, python-format
msgid "Successfully created %(count)d VM."
msgid_plural "Successfully created %(count)d VMs."
msgstr[0] "%(count)d VM létrehozásra került."
msgstr[1] "%(count)d VM létrehozásra került."
#: dashboard/views/vm.py:1101
#: dashboard/views/vm.py:1112
msgid "VM successfully created."
msgstr "VM létrehozásra került."
#: dashboard/views/vm.py:1132
#: dashboard/views/vm.py:1143
#, python-format
msgid "Instance limit (%d) exceeded."
msgstr "A példányok létrehozási korlátját (%d) túllépte."
#: dashboard/views/vm.py:1200
#: dashboard/views/vm.py:1211
msgid "About CIRCLE Client"
msgstr "A CIRCLE kliensről"
#: dashboard/views/vm.py:1290
#: dashboard/views/vm.py:1301
msgid "transfer ownership"
msgstr "tulajdon átruházása"
#: dashboard/views/vm.py:1300
#: dashboard/views/vm.py:1311
#, python-format
msgid ""
"%(owner)s offered you to take the ownership of his/her virtual machine called"
......@@ -3024,9 +3131,9 @@ msgstr "irány"
msgid "If the rule matches egress or ingress packets."
msgstr "A szabály kimenő vagy bejövő csomagokra illeszkedik."
#: firewall/models.py:73 firewall/models.py:345 firewall/models.py:534
#: firewall/models.py:556 firewall/models.py:612 firewall/models.py:982
#: firewall/models.py:1005 firewall/models.py:1074 vm/models/instance.py:136
#: firewall/models.py:73 firewall/models.py:345 firewall/models.py:539
#: firewall/models.py:566 firewall/models.py:627 firewall/models.py:1002
#: firewall/models.py:1030 firewall/models.py:1101 vm/models/instance.py:136
#: vm/models/instance.py:226
msgid "description"
msgstr "leírás"
......@@ -3114,17 +3221,17 @@ msgstr "Célport számának átírása a megadottra NAT esetén."
msgid "external IPv4 address"
msgstr "külső IPv4 cím"
#: firewall/models.py:123 firewall/models.py:388 firewall/models.py:539
#: firewall/models.py:561 firewall/models.py:631
#: firewall/models.py:123 firewall/models.py:388 firewall/models.py:544
#: firewall/models.py:571 firewall/models.py:646
msgid "created at"
msgstr "létrehozva"
#: firewall/models.py:126 firewall/models.py:392 firewall/models.py:541
#: firewall/models.py:563 firewall/models.py:633
#: firewall/models.py:126 firewall/models.py:392 firewall/models.py:546
#: firewall/models.py:573 firewall/models.py:648
msgid "modified at"
msgstr "módosítva"
#: firewall/models.py:129 firewall/models.py:620
#: firewall/models.py:129 firewall/models.py:395 firewall/models.py:635
#: network/templates/network/vlan-create.html:8
#: network/templates/network/vlan-edit.html:8 vm/models/network.py:39
#: vm/models/network.py:67
......@@ -3135,7 +3242,8 @@ msgstr "vlan"
msgid "Vlan the rule applies to (if type is vlan)."
msgstr "Erre a vlanra vonatkozik a szabály (ha a típus vlan)."
#: firewall/models.py:134 network/templates/network/vlan-group-create.html:8
#: firewall/models.py:134 firewall/models.py:549
#: network/templates/network/vlan-group-create.html:8
#: network/templates/network/vlan-group-edit.html:8
msgid "vlan group"
msgstr "vlan-csoport"
......@@ -3144,7 +3252,7 @@ msgstr "vlan-csoport"
msgid "Group of vlans the rule applies to (if type is vlan)."
msgstr "Erre a vlan-csoportra vonatkozik a szabály (ha a típus vlan)."
#: firewall/models.py:138 firewall/models.py:998 firewall/models.py:1115
#: firewall/models.py:138 firewall/models.py:1023 firewall/models.py:1152
#: network/templates/network/host-create.html:8
#: network/templates/network/host-edit.html:8 vm/models/network.py:69
#: vm/models/node.py:126
......@@ -3155,7 +3263,8 @@ msgstr "gép"
msgid "Host the rule applies to (if type is host)."
msgstr "Erre a gépre vonatkozik a szabály (ha a típus gép)."
#: firewall/models.py:142 network/templates/network/group-create.html:8
#: firewall/models.py:142 firewall/models.py:576
#: network/templates/network/group-create.html:8
#: network/templates/network/group-edit.html:8
msgid "host group"
msgstr "gépcsoport"
......@@ -3164,7 +3273,8 @@ msgstr "gépcsoport"
msgid "Group of hosts the rule applies to (if type is host)."
msgstr "Erre a gépcsoportra vonatkozik a szabály (ha a típus gép)."
#: firewall/models.py:146 network/templates/network/firewall-create.html:6
#: firewall/models.py:146 firewall/models.py:954
#: network/templates/network/firewall-create.html:6
#: network/templates/network/firewall-edit.html:7
msgid "firewall"
msgstr "tűzfal"
......@@ -3350,52 +3460,62 @@ msgstr ""
"tiltásához adja meg a „manual” értéket, engedélyezéséhez az első és utolsó "
"érvényes címet szóközzel elválasztva."
#: firewall/models.py:399
#: firewall/models.py:396 firewall/models.py:536
msgid "vlans"
msgstr "vlanok"
#: firewall/models.py:404
msgid "You cannot specify an IPv6 template if there is no IPv6 network set."
msgstr "Nem adhat meg IPv6 sablont, ha nincs IPv6 hálózat beállítva."
#: firewall/models.py:405
#: firewall/models.py:410
#, python-format
msgid "%(ip6)s (translated from %(ip4)s) is outside of the IPv6 network."
msgstr "%(ip6)s (ebből képezve: %(ip4)s) kívül esik az IPv6 hálózaton."
#: firewall/models.py:449
#: firewall/models.py:454
msgid "IPv6 network is too small to map IPv4 addresses to it."
msgstr "Az IPv6 hálózat túl kicsi az IPv4 címek leképezéséhez."
#: firewall/models.py:506
#: firewall/models.py:511
msgid "All IP addresses are already in use."
msgstr "Minden IP cím használatban van."
#: firewall/models.py:529 firewall/models.py:555
#: firewall/models.py:534 firewall/models.py:565
msgid "The name of the group."
msgstr "A csoport neve."
#: firewall/models.py:531
msgid "vlans"
msgstr "vlanok"
#: firewall/models.py:532
#: firewall/models.py:537
msgid "The vlans which are members of the group."
msgstr "A csoport tagjait képező vlanok."
#: firewall/models.py:535 firewall/models.py:557
#: firewall/models.py:540 firewall/models.py:567
msgid "Description of the group."
msgstr "A csoport leírása."
#: firewall/models.py:578 network/tables.py:139 storage/models.py:52
#: firewall/models.py:550
#| msgid "vlan group"
msgid "vlan groups"
msgstr "vlan-csoportok"
#: firewall/models.py:577
#| msgid "host group"
msgid "host groups"
msgstr "gépcsoportok"
#: firewall/models.py:593 network/tables.py:139 storage/models.py:52
msgid "hostname"
msgstr "gépnév"
#: firewall/models.py:579
#: firewall/models.py:594
msgid "The alphanumeric hostname of the host, the first part of the FQDN."
msgstr "A gép alfanumerikus gépneve, az FQDN első része."
#: firewall/models.py:585
#: firewall/models.py:600
msgid "reverse"
msgstr "reverz"
#: firewall/models.py:586
#: firewall/models.py:601
msgid ""
"The fully qualified reverse hostname of the host, if different than "
"hostname.domain."
......@@ -3403,137 +3523,169 @@ msgstr ""
"A gép teljes reverz tartományneve, amennyiben különbözik ettől: "
"gépnév.tartomány."
#: firewall/models.py:590 network/tables.py:138
#: firewall/models.py:605 network/tables.py:138
msgid "MAC address"
msgstr "MAC cím"
#: firewall/models.py:591
#: firewall/models.py:606
msgid ""
"The MAC (Ethernet) address of the network interface. For example: "
"99:AA:BB:CC:DD:EE."
msgstr "A hálózati interfész MAC (Ethernet) címe. Például 99:AA:BB:CC:DD:EE."
#: firewall/models.py:596
#: firewall/models.py:611
msgid "The real IPv4 address of the host, for example 10.5.1.34."
msgstr "A gép valódi IPv4 címe, például 10.5.1.34."
#: firewall/models.py:600
#: firewall/models.py:615
msgid "WAN IPv4 address"
msgstr "WAN IPv4 cím"
#: firewall/models.py:601
#: firewall/models.py:616
msgid ""
"The public IPv4 address of the host on the wide area network, if different."
msgstr "A gép nyilvános IPv4 címe a nagy kiterjedésű hálózaton, ha eltér."
#: firewall/models.py:606
#: firewall/models.py:621
msgid "The global IPv6 address of the host, for example 2001:db:88:200::10."
msgstr "A gép globális IPv6 címe, például 2001:db:88:200::10."
#: firewall/models.py:608
#: firewall/models.py:623
msgid "shared IP"
msgstr "osztott IP"
#: firewall/models.py:610
#: firewall/models.py:625
msgid "If the given WAN IPv4 address is used by multiple hosts."
msgstr "A WAN IPv4 címet több gép használja-e."
#: firewall/models.py:613
#: firewall/models.py:628
msgid "What is this host for, what kind of machine is it."
msgstr "Mi a gép célja, milyen gép ez."
#: firewall/models.py:616
#: firewall/models.py:631
msgid "Notes"
msgstr "Jegyzetek"
#: firewall/models.py:617
#: firewall/models.py:632
msgid "location"
msgstr "elhelyezés"
#: firewall/models.py:619
#: firewall/models.py:634
msgid "The physical location of the machine."
msgstr "A gép fizikai helye."
#: firewall/models.py:622
#: firewall/models.py:637
msgid "Vlan network that the host is part of."
msgstr "Az a vlan hálózat, amelynek a gép része."
#: firewall/models.py:625
#: firewall/models.py:640
msgid "The person responsible for this host."
msgstr "A gépért felelős személy."
#: firewall/models.py:627
#: firewall/models.py:642
msgid "groups"
msgstr "csoportok"
#: firewall/models.py:629
#: firewall/models.py:644
msgid "Host groups the machine is part of."
msgstr "Gépcsoportok, amelyeknek tagja a gép."
#: firewall/models.py:682
#: firewall/models.py:697
msgid "If shared_ip has been checked, external_ipv4 has to be unique."
msgstr ""
"Amennyiben az osztott IP mező igaz, a külső IPv4 cím mező egyedi kell "
"legyen."
#: firewall/models.py:685
#: firewall/models.py:700
msgid "You can't use another host's NAT'd address as your own IPv4."
msgstr "Nem használható másik gép NAT-olt címe saját IPv4 címként."
#: firewall/models.py:790
#: firewall/models.py:805
#, python-format
msgid "All %s ports are already in use."
msgstr "Minden %s port használatban van."
#: firewall/models.py:808
#: firewall/models.py:823
#, python-format
msgid "Port %(proto)s %(public)s is already in use."
msgstr "A(z) %(public)s %(proto)s port használatban van."
#: firewall/models.py:978 firewall/models.py:1007 firewall/models.py:1076
#: firewall/models.py:1103 firewall/models.py:1124
#: firewall/models.py:955
#| msgid "firewall"
msgid "firewalls"
msgstr "tűzfalak"
#: firewall/models.py:998 firewall/models.py:1032 firewall/models.py:1103
#: firewall/models.py:1135 firewall/models.py:1161
msgid "created_at"
msgstr "létrehozva"
#: firewall/models.py:980 firewall/models.py:1009 firewall/models.py:1078
#: firewall/models.py:1105 firewall/models.py:1126
#: firewall/models.py:1000 firewall/models.py:1034 firewall/models.py:1105
#: firewall/models.py:1137 firewall/models.py:1163
msgid "modified_at"
msgstr "módosítva"
#: firewall/models.py:981 firewall/models.py:1003
#: firewall/models.py:1001 firewall/models.py:1028
msgid "ttl"
msgstr "ttl"
#: firewall/models.py:996 network/templates/network/domain-create.html:8
#: firewall/models.py:1005 firewall/models.py:1021
#: network/templates/network/domain-create.html:8
#: network/templates/network/domain-edit.html:8
msgid "domain"
msgstr "tartomány"
#: firewall/models.py:1002
#: firewall/models.py:1006
#| msgid "domain"
msgid "domains"
msgstr "tartományok"
#: firewall/models.py:1027
msgid "address"
msgstr "cím"
#: firewall/models.py:1024
#: firewall/models.py:1049
msgid "Address must be specified!"
msgstr "A cím megadása kötelező."
#: firewall/models.py:1037
#: firewall/models.py:1062
msgid "Unknown record type."
msgstr "Ismeretlen rekordtípus."
#: firewall/models.py:1070
#: firewall/models.py:1086 network/templates/network/record-create.html:8
#: network/templates/network/record-edit.html:8
msgid "record"
msgstr "rekord"
#: firewall/models.py:1087
#| msgid "record"
msgid "records"
msgstr "rekordok"
#: firewall/models.py:1097
msgid "untagged vlan"
msgstr "untagged vlan"
#: firewall/models.py:1073
#: firewall/models.py:1100
msgid "tagged vlans"
msgstr "tagged vlanok"
#: firewall/models.py:1095
#: firewall/models.py:1108 firewall/models.py:1133
#: network/templates/network/switch-port-create.html:8
#: network/templates/network/switch-port-edit.html:8
msgid "switch port"
msgstr "switch port"
#: firewall/models.py:1109
#| msgid "switch port"
msgid "switch ports"
msgstr "switch portok"
#: firewall/models.py:1127
msgid "interface"
msgstr "interfész"
#: firewall/models.py:1096
#: firewall/models.py:1128
msgid ""
"The name of network interface the gateway should serve this network on. For "
"example eth2."
......@@ -3541,39 +3693,44 @@ msgstr ""
"Azon hálózati interfész nevve, amelyen az útválasztó ezt a hálózatot "
"kiszolgálja. Például eth2."
#: firewall/models.py:1101 network/templates/network/switch-port-create.html:8
#: network/templates/network/switch-port-edit.html:8
msgid "switch port"
msgstr "switch port"
#: firewall/models.py:1140
#, fuzzy
#| msgid "No ethernet device"
msgid "ethernet device"
msgstr "Nincs ethernet-eszköz"
#: firewall/models.py:1141
#, fuzzy
#| msgid "No ethernet device"
msgid "ethernet devices"
msgstr "Nincs ethernet-eszköz"
#: firewall/models.py:1117
#: firewall/models.py:1154
msgid "reason"
msgstr "indok"
#: firewall/models.py:1119
#: firewall/models.py:1156
msgid "short message"
msgstr "rövid üzenet"
#: firewall/models.py:1122
#: firewall/models.py:1159
msgid "whitelisted"
msgstr ""
#: firewall/models.py:1128
#| msgid "Expiration"
#: firewall/models.py:1165
msgid "expires at"
msgstr "lejár"
#: firewall/models.py:1138
#: firewall/models.py:1175
msgid "blacklist item"
msgstr "tiltólista eleme"
#: firewall/models.py:1139 network/templates/network/blacklist-create.html:8
#: network/templates/network/blacklist-edit.html:8
msgid "blacklist"
msgstr "tiltólista"
#: firewall/models.py:1176
#| msgid "blacklist item"
msgid "blacklist items"
msgstr "tiltólista elemek"
#: firewall/views.py:79
#| msgid "Enter a valid IP address. %s"
msgid "Invalid IP address."
msgstr "Érvénytelen IP cím."
......@@ -3661,6 +3818,11 @@ msgstr "Nincs kapcsolódó szabály."
msgid "dashboard"
msgstr "műszerfal"
#: network/templates/network/blacklist-create.html:8
#: network/templates/network/blacklist-edit.html:8
msgid "blacklist"
msgstr "tiltólista"
#: network/templates/network/blacklist-create.html:12
msgid "Create a blacklist item"
msgstr "Tiltólista elemének létrehozása"
......@@ -3887,12 +4049,6 @@ msgstr "összes gép"
msgid "Filter by vlans"
msgstr "Vlan szerinti szűrés"
#: network/templates/network/host-list.html:26
#: network/templates/network/record-list.html:22
#: network/templates/network/rule-list.html:23
msgid "ALL"
msgstr "MIND"
#: network/templates/network/index.html:11 templates/info/help.html:32
msgid "Dashboard"
msgstr "Műszerfal"
......@@ -3930,15 +4086,11 @@ msgstr "Legutóbbi tiltólisták"
msgid "IP"
msgstr "IP"
#: network/templates/network/index.html:45
#: network/templates/network/index.html:45 request/models.py:83
#: request/templates/request/detail.html:127
msgid "Reason"
msgstr "Indok"
#: network/templates/network/record-create.html:8
#: network/templates/network/record-edit.html:8
msgid "record"
msgstr "rekord"
#: network/templates/network/record-create.html:12
#: network/templates/network/record-list.html:11
msgid "Create a new record"
......@@ -3952,10 +4104,6 @@ msgstr "Rekord törlése"
msgid "list of all records"
msgstr "összes rekord"
#: network/templates/network/record-list.html:21
msgid "Filter by type"
msgstr "Típus szerinti szűrés"
#: network/templates/network/rule-create.html:12
#: network/templates/network/rule-list.html:12
msgid "Create a new rule"
......@@ -4026,35 +4174,29 @@ msgstr "összes vlan"
#: network/views.py:140
#, python-format
#| msgid "Successfully modified blacklist item%(ipv4)s - %(type)s!"
msgid "Successfully modified blacklist item %(ipv4)s."
msgstr "Tiltólista eleme sikeresen módosítva (%(ipv4)s)."
#: network/views.py:157
#, python-format
#| msgid "Successfully created blacklist item %(ipv4)s - %(type)s!"
msgid "Successfully created blacklist item %(ipv4)s"
msgstr "Tiltólista eleme sikeresen létrehozva (%(ipv4)s)."
#: network/views.py:192
#, python-format
#| msgid "Successfully modified domain %(name)s!"
msgid "Successfully modified domain %(name)s."
msgstr "A(z) %(name)s tartománynév módosításra került."
#: network/views.py:219
#, python-format
#| msgid "Successfully created domain %(name)s!"
msgid "Successfully created domain %(name)s."
msgstr "A(z) %(name)s tartománynév létrehozásra került."
#: network/views.py:236 network/views.py:563 network/views.py:845
#| msgid "Object name does not match!"
msgid "Object name does not match."
msgstr "Az objektum neve nem egyezik."
#: network/views.py:240
#| msgid "Domain successfully deleted!"
msgid "Domain successfully deleted."
msgstr "A tartománynév törlésre került."
......@@ -4072,40 +4214,33 @@ msgstr "A tűzfal létrehozásra került."
#: network/views.py:350
#, python-format
#| msgid "Successfully created host group %(name)s!"
msgid "Successfully created host group %(name)s."
msgstr "%(name)s gépcsoport létrehozásra került."
#: network/views.py:358
#, python-format
#| msgid "Successfully modified host group %(name)s!"
msgid "Successfully modified host group %(name)s."
msgstr "%(name)s gépcsoport módosításra került."
#: network/views.py:442
#, python-format
#| msgid "Successfully modified host %(hostname)s!"
msgid "Successfully modified host %(hostname)s."
msgstr "%(hostname)s gép módosításra került."
#: network/views.py:515
#, python-format
#| msgid "Successfully created host %(hostname)s!"
msgid "Successfully created host %(hostname)s."
msgstr "%(hostname)s gép létrehozásra került."
#: network/views.py:567
#| msgid "Host successfully deleted!"
msgid "Host successfully deleted."
msgstr "A gép törlésre került."
#: network/views.py:597
#| msgid "Successfully modified record!"
msgid "Successfully modified record."
msgstr "A rekord módosításra került."
#: network/views.py:616
#| msgid "Successfully created record!"
msgid "Successfully created record."
msgstr "A rekord létrehozásra került."
......@@ -4122,69 +4257,57 @@ msgid "Firewall"
msgstr "Tűzfal"
#: network/views.py:682
#| msgid "Successfully modified rule!"
msgid "Successfully modified rule."
msgstr "A szabály módosításra került."
#: network/views.py:702
#| msgid "Successfully created rule!"
msgid "Successfully created rule."
msgstr "A szabály létrehozásra került."
#: network/views.py:738
#| msgid "Succesfully modified switch port!"
msgid "Succesfully modified switch port."
msgstr "A switch-port módosításra került."
#: network/views.py:757
#| msgid "Successfully created switch port!"
msgid "Successfully created switch port."
msgstr "A switch-port létrehozásra került."
#: network/views.py:804
#, python-format
#| msgid "Succesfully modified vlan %(name)s!"
msgid "Succesfully modified vlan %(name)s."
msgstr "A(z) %(name)s vlan módosításra került."
#: network/views.py:824
#, python-format
#| msgid "Successfully created vlan %(name)s!"
msgid "Successfully created vlan %(name)s."
msgstr "A(z) %(name)s vlan létrehozásra került."
#: network/views.py:849
#| msgid "Vlan successfully deleted!"
msgid "Vlan successfully deleted."
msgstr "A vlan törlésre került."
#: network/views.py:891
#, python-format
#| msgid "Successfully modified vlan group %(name)s!"
msgid "Successfully modified vlan group %(name)s."
msgstr "A(z) %(name)s vlan-csoport módosításra került."
#: network/views.py:904
#, python-format
#| msgid "Successfully created vlan group %(name)s!"
msgid "Successfully created vlan group %(name)s."
msgstr "A(z) %(name)s vlan-csoport módosításra került."
#: network/views.py:936
#, python-format
#| msgid "Successfully removed %(host)s from %(group)s group!"
msgid "Successfully removed %(host)s from %(group)s group."
msgstr "A(z) %(host)s csoport törlésre került a(z) %(group)s csoportból."
#: network/views.py:952
#, python-format
#| msgid "Successfully added %(host)s to group %(group)s!"
msgid "Successfully added %(host)s to group %(group)s."
msgstr "A(z) %(host)s csoport hozzáadásra került a(z) %(group)s csoporthoz."
#: network/views.py:971
#, python-format
#| msgid "Successfully deleted ethernet device %(name)s!"
msgid "Successfully deleted ethernet device %(name)s."
msgstr "A(z) %(name)s ethernet-eszköz törlésre került."
......@@ -4194,15 +4317,310 @@ msgid "Successfully added %(name)s to this switch port"
msgstr "%(name)s hozzáadásra került a switch-porthoz."
#: network/views.py:996
#| msgid "Ethernet device name cannot be empty!"
msgid "Ethernet device name cannot be empty."
msgstr "Az ethernet-eszköz megadása kötelező."
#: network/views.py:999
#| msgid "There is already an ethernet device with that name!"
msgid "There is already an ethernet device with that name."
msgstr "Már létezik a megadott nevű ethernet-eszköz."
#: request/forms.py:76
#| msgid "Templates"
msgid "Template share"
msgstr "Sablon megosztás"
#: request/models.py:68 vm/models/instance.py:221
msgid "pending"
msgstr "függő"
#: request/models.py:69
#| msgid "accept"
msgid "accepted"
msgstr "elfogadott"
#: request/models.py:70
msgid "declined"
msgstr "elutasított"
#: request/models.py:77
#| msgid "source port"
msgid "resource request"
msgstr "erőforrás igénylés"
#: request/models.py:78
msgid "lease request"
msgstr "bérlet igénylés"
#: request/models.py:79
#| msgid "Template successfully deleted."
msgid "template access request"
msgstr "sablon hozzáférés igénylés"
#: request/models.py:126
#| msgid "Ownership accepted"
msgid "Request accepted"
msgstr "Kérés elfogadva"
#: request/models.py:137
#, python-format
msgid ""
"Your <a href=\"%(url)s\">request</a> was declined because of the following "
"reason: %(reason)s"
msgstr ""
"Az <a href=\"%(url)s\">igénylése</a> el lett utasítva az alábbi indokkal: "
"%(reason)s"
#: request/models.py:142
msgid "Request declined"
msgstr "Igénylés elutasítva"
#: request/models.py:151 vm/models/common.py:154
#, python-format
msgid "%(name)s (suspend: %(s)s, remove: %(r)s)"
msgstr "%(name)s (felfüggesztés: %(s)s, törlés: %(r)s)"
#: request/models.py:171 vm/models/common.py:39
msgid "number of cores"
msgstr "magok száma"
#: request/models.py:172 vm/models/common.py:40
msgid "Number of virtual CPU cores available to the virtual machine."
msgstr "A virtuális gép számára elérhető CPU-magok száma."
#: request/models.py:176 vm/models/common.py:44
msgid "Mebibytes of memory."
msgstr "Memória mebibyte-okban."
#: request/models.py:178 vm/models/common.py:52 vm/models/node.py:124
msgid "priority"
msgstr "prioritás"
#: request/models.py:179 vm/models/common.py:53
msgid "CPU priority."
msgstr "CPU prioritás."
#: request/models.py:188
#, python-format
msgid ""
"The resources of <a href=\"%(url)s\">%(name)s</a> were changed. Number of "
"cores: %(num_cores)d, RAM size: <span class=\"nowrap\">%(ram_size)d "
"MiB</span>, CPU priority: %(priority)d/100."
msgstr ""
"<a href=\"%(url)s\">%(name)s</a> erőforrásai módosultak. Magok száma: "
"%(num_cores)d, RAM-mennyiség: <span class=\"nowrap\">%(ram_size)d "
"MiB</span>, CPU prioritás: %(priority)d/100."
#: request/models.py:212
#, python-format
msgid ""
"The lease of <a href=\"%(url)s\">%(name)s</a> got extended. (suspend: "
"%(suspend)s, remove: %(remove)s)"
msgstr ""
"<a href=\"%(url)s\">%(name)s</a> bérlete meghosszabbítva. (felfüggesztés: "
"%(suspend)s, törlés: %(remove)s)"
#: request/models.py:240
#, python-format
msgid "You got access to the following template: %s"
msgid_plural "You got access to the following templates: %s"
msgstr[0] "Az alábbi sablonhoz szerzett hozzáférést: %s"
msgstr[1] "Az alábbi sablonokhoz szerzett hozzáférést: %s"
#: request/models.py:251
#, python-format
msgid ""
"A new <a href=\"%(request_url)s\">%(request_type)s</a> was submitted by <a "
"href=\"%(user_url)s\">%(display_name)s</a>."
msgstr ""
"Egy új <a href=\"%(request_url)s\">%(request_type)s</a> lett beküldve <a "
"href=\"%(user_url)s\">%(display_name)s</a> által."
#: request/models.py:262
#, python-format
msgid "New %(request_type)s"
msgstr "Új %(request_type)s"
#: request/models.py:266
msgid "Request submitted"
msgstr "Igénylés beküldve"
#: request/models.py:267
#, python-format
msgid ""
"You can view the request's status at this <a "
"href=\"%(request_url)s\">link</a>."
msgstr ""
"Az igénylés állapota megtekinthető az alábbi <a "
"href=\"%(request_url)s\">linken</a>."
#: request/tables.py:53
#| msgid "No more networks."
msgid "No more requests."
msgstr "Nincs több igénylés."
#: request/templates/request/_request-template-form.html:9
#: request/templates/request/detail.html:64
msgid "Level"
msgstr "Szint"
#: request/templates/request/_request-template-form.html:16
msgid "For users who want to share the template with others."
msgstr ""
"Azon felhasználók számára akik a sablonokat meg szeretnék osztani másokkal."
#: request/templates/request/_request-template-form.html:18
#| msgid "This user have no access to any virtual machine."
msgid "For users who want to start a virtual machine."
msgstr "Azon felhasználók számára akik virtuális gépet akarnak indítani."
#: request/templates/request/detail.html:7
#| msgid "requested IP"
msgid "Request"
msgstr "Igénylés"
#: request/templates/request/detail.html:42
#: request/templates/request/detail.html:69
#| msgid "name"
msgid "VM name"
msgstr "Virtuális gép neve"
#: request/templates/request/detail.html:44
#: request/templates/request/detail.html:76
#| msgid "description"
msgid "VM description"
msgstr "Virtuális gép leírása"
#: request/templates/request/detail.html:46
#| msgid "Create lease"
msgid "Current lease"
msgstr "Jelenlegi bérlet"
#: request/templates/request/detail.html:48
#| msgid "requested IP"
msgid "Requested lease"
msgstr "Igényelt bérlet"
#: request/templates/request/detail.html:54
#| msgid "Template"
msgid "Template type"
msgstr "Sablon típus"
#: request/templates/request/detail.html:80
msgid "(old values in parentheses)"
msgstr "(régi értékek zárójelben)"
#: request/templates/request/detail.html:83
#| msgid "number of cores"
msgid "Number of cores"
msgstr "Magok száma"
#: request/templates/request/detail.html:85
#| msgid "RAM size"
msgid "Ram size"
msgstr "RAM-méret"
#: request/templates/request/detail.html:99
msgid "Reason (sent to the user if the request is declined)"
msgstr "Indok (elutasítás esetén a felhasználó megkapja)"
#: request/templates/request/detail.html:103
#| msgid "Online"
msgid "Decline"
msgstr "Elutasít"
#: request/templates/request/detail.html:107
msgid "You can't accept this request because of the VM's state."
msgstr "A virtuális gép állapota miatt a kérés nem elfogadható."
#: request/templates/request/detail.html:114
msgid "Accept"
msgstr "Elfogadás"
#: request/templates/request/detail.html:122
#, python-format
#| msgid " subactivity of <a href=\"%(url)s\">%(name)s</a>\n"
msgid ""
"\n"
" Closed %(closed)s by <a href=\"%(user.profile.get_absolute_url)s\">%(user)s</a>\n"
" "
msgstr ""
"\n"
"Lezárva <a href=\"%(user.profile.get_absolute_url)s\">%(user)s</a> által %(closed)s"
#: request/templates/request/lease-type-form.html:8
msgid "lease type"
msgstr "bérlet típus"
#: request/templates/request/lease-type-form.html:33
#| msgid "new lease"
msgid "New lease type"
msgstr "Új bérlet típus"
#: request/templates/request/list.html:15
#: request/templates/request/type-list.html:6
#: request/templates/request/type-list.html:24
msgid "Request types"
msgstr "Kérés típusok"
#: request/templates/request/list.html:21
#| msgid "Filter by vlans"
msgid "Filter by status"
msgstr "Állapot szerinti szűrés"
#: request/templates/request/request-lease.html:12
#| msgid "new lease"
msgid "Request new lease"
msgstr "Új bérlet igénylése"
#: request/templates/request/request-resource.html:13
#: request/templates/request/request-resource.html:29
#| msgid "Change resources"
msgid "Request new resources"
msgstr "Új erőforrások igénylése"
#: request/templates/request/request-template.html:12
#| msgid "Delete template"
msgid "Request template access"
msgstr "Sablon hozzáférés igénylése"
#: request/templates/request/template-type-form.html:8
#| msgid "Template successfully deleted."
msgid "template access type"
msgstr "sablon hozzáférés típus"
#: request/templates/request/template-type-form.html:33
#| msgid "Template successfully deleted."
msgid "New Template Access type"
msgstr "Új sablon hozzáférés típus"
#: request/templates/request/type-list.html:17
#| msgid "new lease"
msgid "new lease type"
msgstr "új bérlet típus"
#: request/templates/request/type-list.html:21
#| msgid "new template"
msgid "new template access type"
msgstr "új sablon hozzáférés típus"
#: request/templates/request/type-list.html:28
#, fuzzy
#| msgid "The system cannot be used for illegal activites.\n"
msgid ""
"\n"
" Lease types are used for sharing leases. User can request longer ones via these.\n"
" "
msgstr ""
"\n"
"A rendszer nem használható jogszerűtlen célokra."
#: request/templates/request/type-list.html:37
msgid ""
"\n"
" Using template access types users can request multiple templates with user with operator or user level access.\n"
" "
msgstr ""
#: storage/models.py:50
msgid "path"
msgstr "útvonal"
......@@ -4909,18 +5327,6 @@ msgstr ""
"A menedzser újraindítása miatt a tevékenység lezárásra került. Próbálja "
"újra."
#: vm/models/common.py:39
msgid "number of cores"
msgstr "magok száma"
#: vm/models/common.py:40
msgid "Number of virtual CPU cores available to the virtual machine."
msgstr "A virtuális gép számára elérhető CPU-magok száma."
#: vm/models/common.py:44
msgid "Mebibytes of memory."
msgstr "Memória mebibyte-okban."
#: vm/models/common.py:46
msgid "maximal RAM size"
msgstr "maximális RAM-méret"
......@@ -4933,14 +5339,6 @@ msgstr "Felső memóriaméret-korlát ballooning esetén."
msgid "architecture"
msgstr "architektúra"
#: vm/models/common.py:52 vm/models/node.py:124
msgid "priority"
msgstr "prioritás"
#: vm/models/common.py:53
msgid "CPU priority."
msgstr "CPU prioritás."
#: vm/models/common.py:66
msgid "Name of base resource configuration."
msgstr "Alap erőforráskonfiguráció neve."
......@@ -4969,11 +5367,6 @@ msgstr "Létrehozhat bérlési módot."
msgid "never"
msgstr "soha"
#: vm/models/common.py:154
#, python-format
msgid "%(name)s (suspend: %(s)s, remove: %(r)s)"
msgstr "%(name)s (felfüggesztés: %(s)s, törlés: %(r)s)"
#: vm/models/instance.py:99
msgid "Primary remote access method."
msgstr "Elsődleges távoli elérési mód."
......@@ -5083,10 +5476,6 @@ msgstr "felfüggesztve"
msgid "error"
msgstr "hiba"
#: vm/models/instance.py:221
msgid "pending"
msgstr "függő"
#: vm/models/instance.py:222
msgid "destroyed"
msgstr "megsemmisítve"
......@@ -5455,73 +5844,73 @@ msgstr ""
msgid "virtual machine successfully deployed to node: %(node)s"
msgstr "a virtuális gép sikeresen elindítva a következő csomóponton: %(node)s"
#: vm/operations.py:389 vm/operations.py:564 vm/operations.py:930
#: vm/operations.py:394 vm/operations.py:572 vm/operations.py:938
msgid "deploy network"
msgstr "hálózati kapcsolat létrehozása"
#: vm/operations.py:401 vm/operations.py:582 vm/operations.py:681
#: vm/operations.py:406 vm/operations.py:590 vm/operations.py:689
msgid "wait operating system loading"
msgstr "várakozás az operációs rendszer betöltésére"
#: vm/operations.py:406
#: vm/operations.py:411
msgid "deploy vm"
msgstr "vm indítása"
#: vm/operations.py:407
#: vm/operations.py:412
msgid "Deploy virtual machine."
msgstr "Virtuális gép létrehozása."
#: vm/operations.py:416
#: vm/operations.py:421
msgid "deploy virtual machine"
msgstr "virtuális gép létrehozása"
#: vm/operations.py:417
#: vm/operations.py:422
#, python-format
msgid "deploy vm to %(node)s"
msgstr "vm létrehozása: %(node)s"
#: vm/operations.py:423
#: vm/operations.py:428
msgid "deploy disks"
msgstr "lemez létrehozása"
#: vm/operations.py:424
#: vm/operations.py:429
msgid "Deploy all associated disks."
msgstr "Csatolt lemezek létrehozása."
#: vm/operations.py:441
#: vm/operations.py:446
msgid "boot virtual machine"
msgstr "virtuális gép indítása"
#: vm/operations.py:449
#: vm/operations.py:454
msgid "destroy"
msgstr "megsemmisítés"
#: vm/operations.py:450
#: vm/operations.py:455
msgid "Permanently destroy virtual machine, its network settings and disks."
msgstr ""
"Virtuális gép és lemezeinek, hálózati beállításainak végleges eltávolítása."
#: vm/operations.py:459
#: vm/operations.py:467
msgid "destroy network"
msgstr "hálózat megsemmisítése"
#: vm/operations.py:470
#: vm/operations.py:478
msgid "destroy disks"
msgstr "lemez megsemmisítése"
#: vm/operations.py:489
#: vm/operations.py:497
msgid "destroy virtual machine"
msgstr "virtuális gép megsemmisítése"
#: vm/operations.py:497
#: vm/operations.py:505
msgid "removing memory dump"
msgstr "memóriamentés törlése"
#: vm/operations.py:511
#: vm/operations.py:519
msgid "migrate"
msgstr "migrálás"
#: vm/operations.py:512
#: vm/operations.py:520
msgid ""
"Move a running virtual machine to an other worker node keeping its full "
"state."
......@@ -5529,39 +5918,39 @@ msgstr ""
"A virtuális gép mozgatása egy másik számítási csomópontra állapotának "
"megtartásával."
#: vm/operations.py:529
#: vm/operations.py:537
msgid "redeploy network (rollback)"
msgstr "hálózati kapcsolat újraépítése (visszagörgetés)"
#: vm/operations.py:536
#: vm/operations.py:544
msgid "schedule"
msgstr "ütemezés"
#: vm/operations.py:543
#: vm/operations.py:551
#, python-format
msgid "migrate to %(node)s"
msgstr "migrálás %(node)s csomópontra"
#: vm/operations.py:554 vm/operations.py:879
#: vm/operations.py:562 vm/operations.py:887
msgid "shutdown network"
msgstr "hálózati kapcsolat leállítása"
#: vm/operations.py:571
#: vm/operations.py:579
msgid "reboot"
msgstr "újraindítás"
#: vm/operations.py:572
#: vm/operations.py:580
msgid ""
"Warm reboot virtual machine by sending Ctrl+Alt+Del signal to its console."
msgstr ""
"Virtuális gép újraindítása a konzoljára a Ctrl+Alt+Del kombináció "
"küldésével."
#: vm/operations.py:588
#: vm/operations.py:596
msgid "remove interface"
msgstr "interfész törlése"
#: vm/operations.py:589
#: vm/operations.py:597
msgid ""
"Remove the specified network interface and erase IP address allocations, "
"related firewall rules and hostnames."
......@@ -5569,68 +5958,68 @@ msgstr ""
"A kiválasztott hálózati interfész eltávolítása, a foglalt IP címek, "
"tűzfalszabályok és gépnevek törlése."
#: vm/operations.py:605
#: vm/operations.py:613
#, python-format
msgid "remove %(vlan)s interface"
msgstr "%(vlan)s interfész törlése"
#: vm/operations.py:612
#: vm/operations.py:620
msgid "close port"
msgstr "port bezárása"
#: vm/operations.py:613
#: vm/operations.py:621
msgid "Close the specified port."
msgstr "A megadott port bezárása."
#: vm/operations.py:622
#: vm/operations.py:630
#, python-format
msgid "close %(proto)s/%(port)d on %(host)s"
msgstr "%(proto)s/%(port)d bezárása ezen: %(host)s"
#: vm/operations.py:630
#: vm/operations.py:638
msgid "open port"
msgstr "port nyitása"
#: vm/operations.py:631
#: vm/operations.py:639
msgid "Open the specified port."
msgstr "A megadott port kinyitása."
#: vm/operations.py:640
#: vm/operations.py:648
#, python-format
msgid "open %(proto)s/%(port)d on %(host)s"
msgstr "%(proto)s/%(port)d kinyitása ezen: %(host)s"
#: vm/operations.py:647
#: vm/operations.py:655
msgid "remove disk"
msgstr "lemez eltávolítása"
#: vm/operations.py:648
#: vm/operations.py:656
msgid ""
"Remove the specified disk from the virtual machine, and destroy the data."
msgstr "A megadott lemez eltávolítása a virtuális gépből és az adat törlése."
#: vm/operations.py:658
#: vm/operations.py:666
msgid "destroy disk"
msgstr "lemez megsemmisítése"
#: vm/operations.py:664
#: vm/operations.py:672
#, python-format
msgid "remove disk %(name)s"
msgstr "%(name)s lemez eltávolítása"
#: vm/operations.py:671 vm/operations.py:1082
#: vm/operations.py:679 vm/operations.py:1090
msgid "reset"
msgstr "reset"
#: vm/operations.py:672
#: vm/operations.py:680
msgid "Cold reboot virtual machine (power cycle)."
msgstr "Virtuális gép hideg újraindítása (hálózati tápellátás megszakítása)."
#: vm/operations.py:687
#: vm/operations.py:695
msgid "save as template"
msgstr "mentés sablonként"
#: vm/operations.py:688
#: vm/operations.py:696
msgid ""
"Save virtual machine as a template so they can be shared with users and "
"groups. Anyone who has access to a template (and to the networks it uses) "
......@@ -5640,16 +6029,16 @@ msgstr ""
"felhasználókkal és csoportokkal. Mindenki, aki hozzáférést kap egy sablonhoz"
" (és az általa használt hálózatokhoz), képes lesz egy példányát elindítani."
#: vm/operations.py:764
#: vm/operations.py:772
#, python-format
msgid "saving disk %(name)s"
msgstr "%(name)s lemez mentése"
#: vm/operations.py:796
#: vm/operations.py:804
msgid "shutdown"
msgstr "leállítás"
#: vm/operations.py:797
#: vm/operations.py:805
msgid ""
"Try to halt virtual machine by a standard ACPI signal, allowing the "
"operating system to keep a consistent state. The operation will fail if the "
......@@ -5659,7 +6048,7 @@ msgstr ""
"operációs rendszer számár a szabályos leállást. A művelet meghiúsul, ha a "
"gép nem áll le."
#: vm/operations.py:816
#: vm/operations.py:824
msgid ""
"The virtual machine did not switch off in the provided time limit. Most of "
"the time this is caused by incorrect ACPI settings. You can also try to "
......@@ -5669,11 +6058,11 @@ msgstr ""
" ez a nem megfelelő ACPI beállítások miatt van. Megpróbálhatja a gépet az "
"operációs rendszerből, kézzel leállítani."
#: vm/operations.py:828
#: vm/operations.py:836
msgid "shut off"
msgstr "kikapcsolás"
#: vm/operations.py:829
#: vm/operations.py:837
msgid ""
"Forcibly halt a virtual machine without notifying the operating system. This"
" operation will even work in cases when shutdown does not, but the operating"
......@@ -5686,11 +6075,11 @@ msgstr ""
"rendszer és a fájlrendszer sérülhet, adatvesztés történhet. A művelet hatása"
" hasonló, mint egy fizikai gép tápellátásának megszüntetése."
#: vm/operations.py:852
#: vm/operations.py:860
msgid "sleep"
msgstr "altatás"
#: vm/operations.py:853
#: vm/operations.py:861
msgid ""
"Suspend virtual machine. This means the machine is stopped and its memory is"
" saved to disk, so if the machine is waked up, all the applications will "
......@@ -5706,15 +6095,15 @@ msgstr ""
"megállhatnak visszaállítás után. A felfüggesztés ideje alatt a virtuális gép"
" csak tárterületet és hálózati erőforrásokat foglal."
#: vm/operations.py:887
#: vm/operations.py:895
msgid "suspend virtual machine"
msgstr "virtuális gép felfüggesztése"
#: vm/operations.py:901
#: vm/operations.py:909
msgid "wake up"
msgstr "virtuális gép ébresztése"
#: vm/operations.py:902
#: vm/operations.py:910
msgid ""
"Wake up sleeping (suspended) virtual machine. This will load the saved "
"memory of the system and start the virtual machine from this state."
......@@ -5722,15 +6111,15 @@ msgstr ""
"Alvó (felfüggesztett) gép ébresztése: az elmentett memóriatartalom "
"visszatöltése és a virtuális gép indítása ebből a mentett állapotból."
#: vm/operations.py:941
#: vm/operations.py:949
msgid "resume virtual machine"
msgstr "virtuális gép ébresztése"
#: vm/operations.py:955
#: vm/operations.py:963
msgid "renew"
msgstr "megújítás"
#: vm/operations.py:956
#: vm/operations.py:964
msgid ""
"Virtual machines are suspended and destroyed after they expire. This "
"operation renews expiration times according to the lease type. If the "
......@@ -5740,7 +6129,7 @@ msgstr ""
" a művelet megújítja a bérletet a kiválasztott típusnak megfelelően. Ha egy "
"gép közeledik a lejárathoz, a tulajdonost értesítjük."
#: vm/operations.py:969
#: vm/operations.py:977
msgid ""
"Renewing the machine with the selected lease would result in its suspension "
"time get earlier than before."
......@@ -5748,7 +6137,7 @@ msgstr ""
"A gép megújítása a kiválasztott bérleti mód mellett a felfüggesztési időt "
"korábbra állította volna, mint a jelenlegi érték."
#: vm/operations.py:974
#: vm/operations.py:982
msgid ""
"Renewing the machine with the selected lease would result in its delete time"
" get earlier than before."
......@@ -5756,17 +6145,17 @@ msgstr ""
"A gép megújítása a kiválasztott bérleti mód mellett a törlési időt korábbra "
"állította volna, mint a jelenlegi érték."
#: vm/operations.py:982
#: vm/operations.py:990
#, python-format
msgid "Renewed to suspend at %(suspend)s and destroy at %(delete)s."
msgstr ""
"Megújítás után felfüggesztés ideje: %(suspend)s, a törlésé: %(delete)s."
#: vm/operations.py:989
#: vm/operations.py:997
msgid "emergency state change"
msgstr "vész-állapotváltás"
#: vm/operations.py:990
#: vm/operations.py:998
msgid ""
"Change the virtual machine state to NOSTATE. This should only be used if "
"manual intervention was needed in the virtualization layer, and the machine "
......@@ -5777,15 +6166,15 @@ msgstr ""
"rétegben, és úgy szeretné a gépet újból elindítani, hogy ne vesszenek el "
"lemezei vagy hálózati erőforrásai."
#: vm/operations.py:1003
#: vm/operations.py:1011
msgid "Activity is forcibly interrupted."
msgstr "A tevékenység erőszakos megszakításra került."
#: vm/operations.py:1018
#: vm/operations.py:1026
msgid "redeploy"
msgstr "újbóli létrehozás"
#: vm/operations.py:1019
#: vm/operations.py:1027
msgid ""
"Change the virtual machine state to NOSTATE and redeploy the VM. This "
"operation allows starting machines formerly running on a failed node."
......@@ -5794,52 +6183,58 @@ msgstr ""
"létrehozása. Ez a művelet lehetővé teszi olyan gépek elindítását, amelyek "
"korábban egy meghibásodott csomóponton futnak."
#: vm/operations.py:1055
#: vm/operations.py:1063
msgid "You cannot call this operation on an offline node."
msgstr "Nem hívható ez a művelet elérhetetlen csomópontra."
#: vm/operations.py:1083
#: vm/operations.py:1091
msgid "Disable missing node and redeploy all instances on other ones."
msgstr "Hiányzó csomópont letiltása és az összes példány elindítása a többin."
#: vm/operations.py:1093
#: vm/operations.py:1101
msgid "You cannot reset a disabled or online node."
msgstr "Tiltott vagy elérhető csomópont resetelése nem lehetséges."
#: vm/operations.py:1101 vm/operations.py:1121
#, python-format
msgid "migrate %(instance)s (%(pk)s)"
#: vm/operations.py:1106
#, fuzzy, python-format
#| msgid "migrate %(instance)s (%(pk)s)"
msgid "redeploy %(instance)s (%(pk)s)"
msgstr "%(instance)s (%(pk)s) migrálása"
#: vm/operations.py:1110
#: vm/operations.py:1119
msgid "flush"
msgstr "ürítés"
#: vm/operations.py:1111
#: vm/operations.py:1120
msgid "Passivate node and move all instances to other ones."
msgstr ""
"A csomópont passzívra állítása és az összes példány másikakra mozgatása."
#: vm/operations.py:1130
#, python-format
msgid "migrate %(instance)s (%(pk)s)"
msgstr "%(instance)s (%(pk)s) migrálása"
#: vm/operations.py:1139
msgid "activate"
msgstr "aktiválás"
#: vm/operations.py:1131
#: vm/operations.py:1140
msgid ""
"Make node active, i.e. scheduler is allowed to deploy virtual machines to "
"it."
msgstr ""
"Csomópont aktívvá tétele: az ütemező indíthat virtuális gépeket rajta."
#: vm/operations.py:1139
#: vm/operations.py:1148
msgid "You cannot activate an active node."
msgstr "Aktív csomópont aktiválása nem lehetséges."
#: vm/operations.py:1151
#: vm/operations.py:1160
msgid "passivate"
msgstr "passziválás"
#: vm/operations.py:1152
#: vm/operations.py:1161
msgid ""
"Make node passive, i.e. scheduler is denied to deploy virtual machines to "
"it, but remaining instances and the ones manually migrated will continue "
......@@ -5848,31 +6243,31 @@ msgstr ""
"Csomópont passzívvá tétele: az ütemező nem indíthat rajta virtuális gépeket,"
" azonban a megmaradt példányok és a kézzel idemigráltak tovább működnek."
#: vm/operations.py:1160
#: vm/operations.py:1169
msgid "You cannot passivate a passive node."
msgstr "Passzív csomópont passziválása nem lehetséges."
#: vm/operations.py:1173
#: vm/operations.py:1182
msgid "disable"
msgstr "tiltás"
#: vm/operations.py:1174
#: vm/operations.py:1183
msgid "Disable node."
msgstr "Csomópont tiltása."
#: vm/operations.py:1181
#: vm/operations.py:1190
msgid "You cannot disable a disabled node."
msgstr "Tiltott csomópont tiltása nem lehetséges."
#: vm/operations.py:1184
#: vm/operations.py:1193
msgid "You cannot disable a node which is hosting instances."
msgstr "Nem tiltható le olyan csomópont, amelyen még futnak példányok."
#: vm/operations.py:1197
#: vm/operations.py:1206
msgid "update node"
msgstr "csomópont frissítése"
#: vm/operations.py:1198
#: vm/operations.py:1207
msgid ""
"Upgrade or install node software (vmdriver, agentdriver, monitor-client) "
"with Salt."
......@@ -5880,41 +6275,41 @@ msgstr ""
"Csomópont frissítése vagy telepítése (vmdriver, agentdriver, monitor-client)"
" Salt segítségével."
#: vm/operations.py:1216
#: vm/operations.py:1225
#, python-format
msgid "No minions matched the target (%(target)s). Data: (%(data)s)"
msgstr ""
#: vm/operations.py:1221 vm/operations.py:1232
#: vm/operations.py:1230 vm/operations.py:1241
#, python-format
msgid "Unhandled exception: %(msg)s"
msgstr "Kezeletlen kivétel: %(msg)s"
#: vm/operations.py:1228
#: vm/operations.py:1237
msgid "upgrade packages"
msgstr "csomagok frissítése"
#: vm/operations.py:1243
#: vm/operations.py:1252
#, python-format
msgid "Upgraded: %(upgraded)s, Installed: %(installed)s, Removed: %(removed)s"
msgstr ""
"Frissítve: %(upgraded)s, Telepítve: %(installed)s, Törölve: %(removed)s"
#: vm/operations.py:1256
#: vm/operations.py:1265
#, python-format
msgid "Changes: %(changes)s Comment: %(comment)s"
msgstr ""
#: vm/operations.py:1264
#: vm/operations.py:1273
#, python-format
msgid "Failed: %(failed)s"
msgstr "Meghiúsult: %(failed)s"
#: vm/operations.py:1270
#: vm/operations.py:1279
msgid "screenshot"
msgstr "képernyőkép"
#: vm/operations.py:1271
#: vm/operations.py:1280
msgid ""
"Get a screenshot about the virtual machine's console. A key will be pressed "
"on the keyboard to stop screensaver."
......@@ -5922,11 +6317,11 @@ msgstr ""
"Képernyőkép készítése a virtuális gép konzoljáról. Egy billentyűnyomást "
"követően készül a kép a képernyővédő miatt."
#: vm/operations.py:1283
#: vm/operations.py:1292
msgid "recover"
msgstr "visszaállítás"
#: vm/operations.py:1284
#: vm/operations.py:1293
msgid ""
"Try to recover virtual machine disks from destroyed state. Network resources"
" (allocations) are already lost, so you will have to manually add interfaces"
......@@ -5936,19 +6331,19 @@ msgstr ""
"hálózati erőforrások foglalásai már végleg elvesztek, így az interfészeket "
"kézzel kell a visszaállítás után pótolni."
#: vm/operations.py:1301
#: vm/operations.py:1310
msgid "recover instance"
msgstr "példány helyreállítása"
#: vm/operations.py:1324
#: vm/operations.py:1333
msgid "resources change"
msgstr "erőforrások módosítása"
#: vm/operations.py:1325
#: vm/operations.py:1334
msgid "Change resources of a stopped virtual machine."
msgstr "Leállított virtuális gép erőforrásainak változtatása."
#: vm/operations.py:1342
#: vm/operations.py:1350
#, python-format
msgid ""
"Priority: %(priority)s, Num cores: %(num_cores)s, Ram size: %(ram_size)s"
......@@ -5956,11 +6351,16 @@ msgstr ""
"Prioritás: %(priority)s, magok száma: %(num_cores)s, memória mérete: "
"%(ram_size)s"
#: vm/operations.py:1351
#: vm/operations.py:1359
#| msgid "resources change"
msgid "resources request"
msgstr "erőforrás igénylés"
#: vm/operations.py:1385
msgid "password reset"
msgstr "jelszó visszaállítása"
#: vm/operations.py:1352
#: vm/operations.py:1386
msgid ""
"Generate and set a new login password on the virtual machine. This operation"
" requires the agent running. Resetting the password is not warranted to "
......@@ -5970,52 +6370,52 @@ msgstr ""
"művelet megköveteli az ügynök futását. A jelszó átállítása nem garantálja a "
"sikeres belépést, mivel más beállítások is megakadályozhatják ezt."
#: vm/operations.py:1376
#: vm/operations.py:1410
msgid "agent"
msgstr "ügynök"
#: vm/operations.py:1417
#: vm/operations.py:1451
msgid "starting"
msgstr "indítás"
#: vm/operations.py:1435
#: vm/operations.py:1469
msgid "wait agent restarting"
msgstr "várakozás az ügynök újraindulására"
#: vm/operations.py:1452
#: vm/operations.py:1486
msgid "cleanup"
msgstr "takarítás"
#: vm/operations.py:1458
#: vm/operations.py:1492
msgid "set time"
msgstr "óra beállítása"
#: vm/operations.py:1469
#: vm/operations.py:1503
msgid "set hostname"
msgstr "gépnév beállítása"
#: vm/operations.py:1480
#: vm/operations.py:1514
msgid "restart networking"
msgstr "hálózat újratöltése"
#: vm/operations.py:1486
#: vm/operations.py:1520
msgid "change ip"
msgstr "IP cím beállítása"
#: vm/operations.py:1501
#: vm/operations.py:1535
msgid "update agent"
msgstr "ügynök frissítése"
#: vm/operations.py:1507
#: vm/operations.py:1541
#, python-format
msgid "update agent to %(version)s"
msgstr "ügynökfrissítés erre: %(version)s"
#: vm/operations.py:1590
#: vm/operations.py:1624
msgid "mount store"
msgstr "tárhely csatolása"
#: vm/operations.py:1592
#: vm/operations.py:1626
msgid ""
"This operation attaches your personal file store. Other users who have "
"access to this machine can see these files as well."
......@@ -6023,28 +6423,28 @@ msgstr ""
"Ez a művelet csatolja az ön személyes tárhelyét. A gép más felhasználói is "
"elérhetik fájljait."
#: vm/operations.py:1626
#: vm/operations.py:1660
msgid "attach disk"
msgstr "lemez csatolása"
#: vm/operations.py:1637
#: vm/operations.py:1671
msgid "Resource was not found."
msgstr "Nem található az erőforrás."
#: vm/operations.py:1638
#: vm/operations.py:1672
#, python-format
msgid "Resource was not found. %(exception)s"
msgstr "Nem található az erőforrás. %(exception)s"
#: vm/operations.py:1647
#: vm/operations.py:1681
msgid "detach disk"
msgstr "lemez leválasztása"
#: vm/operations.py:1662
#: vm/operations.py:1696
msgid "attach network"
msgstr "hálózat csatolása"
#: vm/operations.py:1669
#: vm/operations.py:1703
msgid "detach network"
msgstr "hálózat lecsatolása"
......@@ -6080,7 +6480,7 @@ msgstr ""
"<a href=\"%(url)s\">%(instance)s</a> gépe felfüggesztésre került, mivel "
"lejárt. Felébresztheti vagy megsemmisítheti."
#: vm/tests/test_models.py:219
#: vm/tests/test_models.py:221
msgid "x"
msgstr "x"
......@@ -6339,9 +6739,6 @@ msgstr "x"
#~ msgid "Recover virtual machine from destroyed state."
#~ msgstr "Megsemmisített virtuális gép visszaállítása."
#~ msgid "Change resources"
#~ msgstr "Erőforrások módosítása"
#~ msgid "VM successfully deleted."
#~ msgstr "A VM törlésre került."
......@@ -6397,9 +6794,6 @@ msgstr "x"
#~ msgid "Are you sure?"
#~ msgstr "Biztos benne?"
#~ msgid "Accept"
#~ msgstr "Elfogadás"
#~ msgid ""
#~ "\n"
#~ "Please, either <a href=\"%(token)s\">renew</a> or <a href=\"%(url)s\">destroy</a>\n"
......
# Copyright 2014 Budapest University of Technology and Economics (BME IK)
#
# This file is part of CIRCLE Cloud.
#
# CIRCLE is free software: you can redistribute it and/or modify it under
# the terms of the GNU General Public License as published by the Free
# Software Foundation, either version 3 of the License, or (at your option)
# any later version.
#
# CIRCLE is distributed in the hope that it will be useful, but WITHOUT ANY
# WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
# FOR A PARTICULAR PURPOSE. See the GNU General Public License for more
# details.
#
# You should have received a copy of the GNU General Public License along
# with CIRCLE. If not, see <http://www.gnu.org/licenses/>.
from django.forms import (
ModelForm, ModelChoiceField, ChoiceField, Form, CharField, RadioSelect,
Textarea,
)
from django.utils.translation import ugettext_lazy as _
from django.template import RequestContext
from django.template.loader import render_to_string
from crispy_forms.helper import FormHelper
from crispy_forms.layout import Submit
from request.models import (
LeaseType, TemplateAccessType, TemplateAccessAction,
)
from dashboard.forms import VmResourcesForm
class LeaseTypeForm(ModelForm):
@property
def helper(self):
helper = FormHelper()
helper.add_input(Submit("submit", _("Save"),
css_class="btn btn-success", ))
return helper
class Meta:
model = LeaseType
fields = ["name", "lease", ]
class TemplateAccessTypeForm(ModelForm):
def __init__(self, *args, **kwargs):
super(TemplateAccessTypeForm, self).__init__(*args, **kwargs)
@property
def helper(self):
helper = FormHelper()
helper.add_input(Submit("submit", _("Save"),
css_class="btn btn-success", ))
return helper
class Meta:
model = TemplateAccessType
fields = ["name", "templates", ]
class InitialFromFileMixin(object):
def __init__(self, *args, **kwargs):
request = kwargs.pop("request", None)
super(InitialFromFileMixin, self).__init__(*args, **kwargs)
self.initial['message'] = render_to_string(
self.initial_template,
RequestContext(request, {}),
)
class TemplateRequestForm(InitialFromFileMixin, Form):
template = ModelChoiceField(TemplateAccessType.objects.all(),
label=_("Template share"))
level = ChoiceField(TemplateAccessAction.LEVELS, widget=RadioSelect,
initial=TemplateAccessAction.LEVELS.user)
message = CharField(widget=Textarea, label=_("Message"))
initial_template = "request/initials/template.html"
class LeaseRequestForm(InitialFromFileMixin, Form):
lease = ModelChoiceField(LeaseType.objects.all(), label=_("Lease"))
message = CharField(widget=Textarea)
initial_template = "request/initials/lease.html"
class ResourceRequestForm(InitialFromFileMixin, VmResourcesForm):
message = CharField(widget=Textarea)
initial_template = "request/initials/resources.html"
# -*- coding: utf-8 -*-
from __future__ import unicode_literals
from django.db import models, migrations
import django.utils.timezone
from django.conf import settings
import model_utils.fields
import django.core.validators
class Migration(migrations.Migration):
dependencies = [
migrations.swappable_dependency(settings.AUTH_USER_MODEL),
('contenttypes', '0001_initial'),
('vm', '0002_interface_model'),
]
operations = [
migrations.CreateModel(
name='ExtendLeaseAction',
fields=[
('id', models.AutoField(verbose_name='ID', serialize=False, auto_created=True, primary_key=True)),
('instance', models.ForeignKey(to='vm.Instance')),
],
options={
'abstract': False,
},
bases=(models.Model,),
),
migrations.CreateModel(
name='LeaseType',
fields=[
('id', models.AutoField(verbose_name='ID', serialize=False, auto_created=True, primary_key=True)),
('name', models.CharField(max_length=25)),
('lease', models.ForeignKey(to='vm.Lease')),
],
options={
'abstract': False,
},
bases=(models.Model,),
),
migrations.CreateModel(
name='Request',
fields=[
('id', models.AutoField(verbose_name='ID', serialize=False, auto_created=True, primary_key=True)),
('created', model_utils.fields.AutoCreatedField(default=django.utils.timezone.now, verbose_name='created', editable=False)),
('modified', model_utils.fields.AutoLastModifiedField(default=django.utils.timezone.now, verbose_name='modified', editable=False)),
('status', models.CharField(default=b'PENDING', max_length=10, choices=[(b'PENDING', 'pending'), (b'ACCEPTED', 'accepted'), (b'DECLINED', 'declined')])),
('type', models.CharField(max_length=10, choices=[(b'resource', 'resource request'), (b'lease', 'lease request'), (b'template', 'template access')])),
('message', models.TextField(verbose_name='Message')),
('reason', models.TextField(verbose_name='Reason')),
('object_id', models.IntegerField()),
('closed_by', models.ForeignKey(related_name='closed_by', to=settings.AUTH_USER_MODEL, null=True)),
('content_type', models.ForeignKey(to='contenttypes.ContentType')),
('user', models.ForeignKey(related_name='user', to=settings.AUTH_USER_MODEL)),
],
options={
'abstract': False,
},
bases=(models.Model,),
),
migrations.CreateModel(
name='ResourceChangeAction',
fields=[
('id', models.AutoField(verbose_name='ID', serialize=False, auto_created=True, primary_key=True)),
('num_cores', models.IntegerField(help_text='Number of virtual CPU cores available to the virtual machine.', verbose_name='number of cores', validators=[django.core.validators.MinValueValidator(0)])),
('ram_size', models.IntegerField(help_text='Mebibytes of memory.', verbose_name='RAM size', validators=[django.core.validators.MinValueValidator(0)])),
('priority', models.IntegerField(help_text='CPU priority.', verbose_name='priority', validators=[django.core.validators.MinValueValidator(0)])),
('instance', models.ForeignKey(to='vm.Instance')),
],
options={
'abstract': False,
},
bases=(models.Model,),
),
migrations.CreateModel(
name='TemplateAccessAction',
fields=[
('id', models.AutoField(verbose_name='ID', serialize=False, auto_created=True, primary_key=True)),
('level', models.CharField(default=b'user', max_length=10, choices=[(b'user', 'user'), (b'operator', 'operator')])),
],
options={
'abstract': False,
},
bases=(models.Model,),
),
migrations.CreateModel(
name='TemplateAccessType',
fields=[
('id', models.AutoField(verbose_name='ID', serialize=False, auto_created=True, primary_key=True)),
('name', models.CharField(max_length=25)),
('templates', models.ManyToManyField(to='vm.InstanceTemplate')),
],
options={
'abstract': False,
},
bases=(models.Model,),
),
migrations.AddField(
model_name='templateaccessaction',
name='template_type',
field=models.ForeignKey(to='request.TemplateAccessType'),
preserve_default=True,
),
migrations.AddField(
model_name='templateaccessaction',
name='user',
field=models.ForeignKey(to=settings.AUTH_USER_MODEL),
preserve_default=True,
),
migrations.AddField(
model_name='extendleaseaction',
name='lease_type',
field=models.ForeignKey(to='request.LeaseType'),
preserve_default=True,
),
]
# -*- coding: utf-8 -*-
from __future__ import unicode_literals
from django.db import models, migrations
class Migration(migrations.Migration):
dependencies = [
('request', '0001_initial'),
]
operations = [
migrations.AlterField(
model_name='leasetype',
name='lease',
field=models.ForeignKey(verbose_name='Lease', to='vm.Lease'),
preserve_default=True,
),
migrations.AlterField(
model_name='leasetype',
name='name',
field=models.CharField(max_length=25, verbose_name='Name'),
preserve_default=True,
),
migrations.AlterField(
model_name='templateaccesstype',
name='name',
field=models.CharField(max_length=25, verbose_name='Name'),
preserve_default=True,
),
migrations.AlterField(
model_name='templateaccesstype',
name='templates',
field=models.ManyToManyField(to='vm.InstanceTemplate', verbose_name='Templates'),
preserve_default=True,
),
]
# Copyright 2014 Budapest University of Technology and Economics (BME IK)
#
# This file is part of CIRCLE Cloud.
#
# CIRCLE is free software: you can redistribute it and/or modify it under
# the terms of the GNU General Public License as published by the Free
# Software Foundation, either version 3 of the License, or (at your option)
# any later version.
#
# CIRCLE is distributed in the hope that it will be useful, but WITHOUT ANY
# WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
# FOR A PARTICULAR PURPOSE. See the GNU General Public License for more
# details.
#
# You should have received a copy of the GNU General Public License along
# with CIRCLE. If not, see <http://www.gnu.org/licenses/>.
import json
import logging
from django.db.models import (
Model, CharField, IntegerField, TextField, ForeignKey, ManyToManyField,
)
from django.db.models.signals import post_save
from django.conf import settings
from django.contrib.contenttypes.fields import GenericForeignKey
from django.contrib.contenttypes.models import ContentType
from django.contrib.auth.models import User
from django.core.validators import MinValueValidator
from django.utils.translation import (
ugettext_lazy as _, ugettext_noop, ungettext
)
from django.core.urlresolvers import reverse
import requests
from model_utils.models import TimeStampedModel
from model_utils import Choices
from vm.models import Instance, InstanceTemplate, Lease
logger = logging.getLogger(__name__)
class RequestAction(Model):
def accept(self):
raise NotImplementedError
@property
def accept_msg(self):
raise NotImplementedError
class Meta:
abstract = True
class RequestType(Model):
name = CharField(max_length=25, verbose_name=_("Name"))
def __unicode__(self):
return self.name
class Meta:
abstract = True
class Request(TimeStampedModel):
STATUSES = Choices(
('PENDING', _('pending')),
('ACCEPTED', _('accepted')),
('DECLINED', _('declined')),
)
status = CharField(choices=STATUSES, default=STATUSES.PENDING,
max_length=10)
user = ForeignKey(User, related_name="user")
closed_by = ForeignKey(User, related_name="closed_by", null=True)
TYPES = Choices(
('resource', _('resource request')),
('lease', _("lease request")),
('template', _("template access request")),
)
type = CharField(choices=TYPES, max_length=10)
message = TextField(verbose_name=_("Message"))
reason = TextField(verbose_name=_("Reason"))
content_type = ForeignKey(ContentType)
object_id = IntegerField()
action = GenericForeignKey("content_type", "object_id")
def get_absolute_url(self):
return reverse("request.views.request-detail", kwargs={'pk': self.pk})
def get_readable_status(self):
return self.STATUSES[self.status]
def get_readable_type(self):
return self.TYPES[self.type]
def get_request_icon(self):
return {
'resource': "tasks",
'lease': "clock-o",
'template': "puzzle-piece"
}.get(self.type)
def get_effect(self):
return {
"PENDING": "warning",
"ACCEPTED": "success",
"DECLINED": "danger",
}.get(self.status)
def get_status_icon(self):
return {
"PENDING": "exclamation-triangle",
"ACCEPTED": "check",
"DECLINED": "times",
}.get(self.status)
def accept(self, user):
self.action.accept(user)
self.status = "ACCEPTED"
self.closed_by = user
self.save()
self.user.profile.notify(
ugettext_noop("Request accepted"),
self.action.accept_msg
)
def decline(self, user, reason):
self.status = "DECLINED"
self.closed_by = user
self.reason = reason
self.save()
decline_msg = ugettext_noop(
'Your <a href="%(url)s">request</a> was declined because of the '
'following reason: %(reason)s'
)
self.user.profile.notify(
ugettext_noop("Request declined"),
decline_msg, url=self.get_absolute_url(), reason=self.reason,
)
class LeaseType(RequestType):
lease = ForeignKey(Lease, verbose_name=_("Lease"))
def __unicode__(self):
return _("%(name)s (suspend: %(s)s, remove: %(r)s)") % {
'name': self.name,
's': self.lease.get_readable_suspend_time(),
'r': self.lease.get_readable_delete_time()}
def get_absolute_url(self):
return reverse("request.views.lease-type-detail",
kwargs={'pk': self.pk})
class TemplateAccessType(RequestType):
templates = ManyToManyField(InstanceTemplate, verbose_name=_("Templates"))
def get_absolute_url(self):
return reverse("request.views.template-type-detail",
kwargs={'pk': self.pk})
class ResourceChangeAction(RequestAction):
instance = ForeignKey(Instance)
num_cores = IntegerField(verbose_name=_('number of cores'),
help_text=_('Number of virtual CPU cores '
'available to the virtual machine.'),
validators=[MinValueValidator(0)])
ram_size = IntegerField(verbose_name=_('RAM size'),
help_text=_('Mebibytes of memory.'),
validators=[MinValueValidator(0)])
priority = IntegerField(verbose_name=_('priority'),
help_text=_('CPU priority.'),
validators=[MinValueValidator(0)])
def accept(self, user):
self.instance.resources_change.async(
user=user, num_cores=self.num_cores, ram_size=self.ram_size,
max_ram_size=self.ram_size, priority=self.priority,
with_shutdown=True)
@property
def accept_msg(self):
return _(
'The resources of <a href="%(url)s">%(name)s</a> were changed. '
'Number of cores: %(num_cores)d, RAM size: '
'<span class="nowrap">%(ram_size)d MiB</span>, '
'CPU priority: %(priority)d/100.'
) % {
'url': self.instance.get_absolute_url(),
'name': self.instance.name,
'num_cores': self.num_cores,
'ram_size': self.ram_size,
'priority': self.priority,
}
class ExtendLeaseAction(RequestAction):
instance = ForeignKey(Instance)
lease_type = ForeignKey(LeaseType)
def accept(self, user):
self.instance.renew(lease=self.lease_type.lease, save=True, force=True,
user=user)
@property
def accept_msg(self):
return _(
'The lease of <a href="%(url)s">%(name)s</a> got extended. '
'(suspend: %(suspend)s, remove: %(remove)s)'
) % {'name': self.instance.name,
'url': self.instance.get_absolute_url(),
'suspend': self.lease_type.lease.get_readable_suspend_time(),
'remove': self.lease_type.lease.get_readable_delete_time(), }
class TemplateAccessAction(RequestAction):
template_type = ForeignKey(TemplateAccessType)
LEVELS = Choices(
('user', _('user')),
('operator', _('operator')),
)
level = CharField(choices=LEVELS, default=LEVELS.user,
max_length=10)
user = ForeignKey(User)
def get_readable_level(self):
return self.LEVELS[self.level]
def accept(self, user):
for t in self.template_type.templates.all():
t.set_user_level(self.user, self.level)
@property
def accept_msg(self):
return ungettext(
"You got access to the following template: %s",
"You got access to the following templates: %s",
self.template_type.templates.count()
) % ", ".join([x.name for x in self.template_type.templates.all()])
def send_notifications(sender, instance, created, **kwargs):
if not created:
return
notification_msg = ugettext_noop(
'A new <a href="%(request_url)s">%(request_type)s</a> was submitted '
'by <a href="%(user_url)s">%(display_name)s</a>.')
context = {
'display_name': instance.user.profile.get_display_name(),
'user_url': instance.user.profile.get_absolute_url(),
'request_url': instance.get_absolute_url(),
'request_type': u"%s" % instance.get_readable_type()
}
for u in User.objects.filter(is_superuser=True):
u.profile.notify(
ugettext_noop("New %(request_type)s"), notification_msg, context
)
instance.user.profile.notify(
ugettext_noop("Request submitted"),
ugettext_noop('You can view the request\'s status at this '
'<a href="%(request_url)s">link</a>.'), context
)
if settings.REQUEST_HOOK_URL:
context.update({
'object_kind': "request",
'site_url': settings.DJANGO_URL,
})
try:
r = requests.post(settings.REQUEST_HOOK_URL, timeout=3,
data=json.dumps(context, indent=2))
r.raise_for_status()
except requests.RequestException as e:
logger.warning("Error in HTTP POST: %s. url: %s params: %s",
str(e), settings.REQUEST_HOOK_URL, context)
else:
logger.info("Successful HTTP POST. url: %s params: %s",
settings.REQUEST_HOOK_URL, context)
post_save.connect(send_notifications, sender=Request)
# Copyright 2014 Budapest University of Technology and Economics (BME IK)
#
# This file is part of CIRCLE Cloud.
#
# CIRCLE is free software: you can redistribute it and/or modify it under
# the terms of the GNU General Public License as published by the Free
# Software Foundation, either version 3 of the License, or (at your option)
# any later version.
#
# CIRCLE is distributed in the hope that it will be useful, but WITHOUT ANY
# WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
# FOR A PARTICULAR PURPOSE. See the GNU General Public License for more
# details.
#
# You should have received a copy of the GNU General Public License along
# with CIRCLE. If not, see <http://www.gnu.org/licenses/>.
from django.utils.translation import ugettext_lazy as _
from django_tables2 import Table, A
from django_tables2.columns import (
Column, TemplateColumn, LinkColumn
)
from request.models import Request, LeaseType, TemplateAccessType
class RequestTable(Table):
pk = LinkColumn(
'request.views.request-detail',
args=[A('pk')],
verbose_name=_("ID"),
)
status = TemplateColumn(
template_name="request/columns/status.html",
verbose_name=_("Status"),
)
user = TemplateColumn(
template_name="request/columns/user.html",
verbose_name=_("User"),
)
type = TemplateColumn(
template_name="request/columns/type.html",
verbose_name=_("Type"),
)
class Meta:
model = Request
template = "django_tables2/with_pagination.html"
attrs = {'class': ('table table-bordered table-striped table-hover'),
'id': "request-list-table"}
fields = ("pk", "status", "type", "user", )
order_by = ("-pk", )
empty_text = _("No more requests.")
per_page = 10
class LeaseTypeTable(Table):
pk = LinkColumn(
'request.views.lease-type-detail',
args=[A('pk')],
verbose_name=_("ID"),
)
lease = Column(verbose_name=_("Lease"))
class Meta:
model = LeaseType
attrs = {'class': "table table-bordered table-striped table-hover"}
fields = ('pk', 'name', 'lease', )
prefix = "lease-"
template = "django_tables2/with_pagination.html"
class TemplateAccessTypeTable(Table):
pk = LinkColumn(
'request.views.template-type-detail',
args=[A('pk')],
verbose_name=_("ID"),
)
templates = TemplateColumn(
template_name="request/columns/templates.html",
verbose_name=_("Templates"),
)
class Meta:
model = TemplateAccessType
attrs = {'class': "table table-bordered table-striped table-hover"}
fields = ('pk', 'name', 'templates', )
prefix = "template-"
template = "django_tables2/with_pagination.html"
{% load i18n %}
{% load crispy_forms_tags %}
<form action="{% url "request.views.request-lease" vm_pk=vm.pk %}" method="POST">
{% include "display-form-errors.html" %}
{% csrf_token %}
{{ form.lease|as_crispy_field }}
{{ form.message|as_crispy_field }}
<input type="submit" class="btn btn-primary"/>
</form>
{% load i18n %}
{% load crispy_forms_tags %}
<form action="{% url "request.views.request-template" %}" method="POST">
{% include "display-form-errors.html" %}
{% csrf_token %}
{{ form.template|as_crispy_field }}
<div style="font-weight: bold;">{% trans "Level" %}*</div>
{% for radio in form.level %}
<div class="myradio" style="display: inline-block; padding-left: 20px;">
<label>
{{ radio }}
<div class="text-muted" style="padding-left: 16px; font-weight: normal;">
{% if forloop.last %}
{% trans "For users who want to share the template with others." %}
{% else %}
{% trans "For users who want to start a virtual machine." %}
{% endif %}
</div>
</label>
</div>
{% endfor %}
{{ form.message|as_crispy_field }}
<input type="submit" class="btn btn-primary"/>
</form>
<span class="label label-{{ record.get_effect }}" style="font-size: 1.2em;">
<i class="fa fa-{{ record.get_status_icon }}"></i>
{{ record.get_readable_status|upper }}
</span>
{% for t in record.templates.all %}
<a href="{% url "dashboard.views.template-detail" pk=t.pk %}">
{{ t.name }}</a>
{% if not forloop.last %} | {% endif %}
{% endfor %}
<i class="fa fa-{{ record.get_request_icon }}"></i>
{{ record.get_readable_type|capfirst }}
<img src="{{ record.user.profile.get_avatar_url }}" width="20" height="20"/>
<a href="{{ record.user.profile.get_absolute_url }}">
{{ record.user.profile.get_display_name }}
</a>
{% extends "dashboard/base.html" %}
{% load staticfiles %}
{% load i18n %}
{% load render_table from django_tables2 %}
{% load arrowfilter %}
{% block title-page %}{% trans "Request" %}{% endblock %}
{% block content %}
<div class="row">
<div class="col-md-12">
<div class="panel panel-default">
<div class="panel-heading">
{% if request.user.is_superuser %}
<a href="{% url "request.views.request-list" %}" class="btn btn-default btn-xs pull-right">
{% trans "Back" %}
</a>
{% endif %}
<h3 class="no-margin">
<i class="fa fa-{{ object.get_request_icon }}"></i>
{{ object.get_readable_type|capfirst }}
</h3>
</div>
<div class="panel-body">
<div class="label label-{{ object.get_effect }} pull-right" style="font-size: 1.5em; margin-top: 10px;">
<i class="fa fa-{{ object.get_status_icon }}"></i>
{{ object.get_readable_status|upper }}
</div>
<p>
<img src="{{ object.user.profile.get_avatar_url }}" width="50" height="50"/>
<a href="{{ object.user.profile.get_absolute_url }}">
{{ object.user.profile.get_display_name }}
</a>
</p>
<p>
<pre>{{ object.message }}</pre>
</p>
<hr />
{% if object.type == "lease" %}
<dl>
<dt>{% trans "VM name" %}</dt>
<dd><a href="{{ action.instance.get_absolute_url }}">{{ action.instance.name }}</a></dd>
<dt>{% trans "VM description" %}</dt>
<dd>{{ action.instance.description }}</dd>
<dt>{% trans "Current lease" %}</dt>
<dd>{{ action.instance.lease }}</dd>
<dt>{% trans "Requested lease" %}</dt>
<dd>{{ action.lease_type.lease }}</dd>
</dl>
{% elif object.type == "template" %}
<dl>
<dt>
{% trans "Template type" %}:
<span style="font-weight: normal;">{{ action.template_type.name }}</span>
</dt>
<dd>
<ul>
{% for t in action.template_type.templates.all %}
<li><a href="{{ t.get_absolute_url }}">{{ t }}</a></li>
{% endfor %}
</ul>
</dd>
<dt>{% trans "Level" %}<dt>
<dd>{{ action.get_readable_level }}</dd>
</dl>
{% elif object.type == "resource" %}
<dl>
<dt>{% trans "VM name" %}</dt>
<dd><a href="{{ action.instance.get_absolute_url }}">{{ action.instance.name }}</a></dd>
<dt>{% trans "Status" %}</dt>
<dd>
<i class="fa {{ action.instance.get_status_icon }}"></i>
{{ action.instance.get_status_display|upper }}
</dd>
<dt>{% trans "VM description" %}</dt>
<dd>{{ action.instance.description }}</dd>
<dt>
{% trans "Priority" %}
<span class="text-muted" style="font-weight: normal;">{% trans "(old values in parentheses)" %}</span>
</dt>
<dd>{{ action.priority }} ({{ action.instance.priority }})</dd>
<dt>{% trans "Number of cores" %}</dt>
<dd>{{ action.num_cores }} ({{ action.instance.num_cores }})</dd>
<dt>{% trans "Ram size" %}</dt>
<dd>{{ action.ram_size }} ({{ action.instance.ram_size }}) MiB</dd>
</dl>
{% else %}
hacks!!!
{% endif %}
{% if object.status == "PENDING" and request.user.is_superuser %}
<hr />
<div class="pull-right" id="request-buttons">
<form method="POST">
{% csrf_token %}
<p>
<textarea class="form-control" placeholder="{% trans "Reason (sent to the user if the request is declined)" %}" name="reason"></textarea>
</p>
<button class="btn btn-danger" type="submit">
<i class="fa fa-thumbs-down"></i>
{% trans "Decline" %}
</button>
</form>
{% if object.type == "resource" and action.instance.status not in accept_states %}
{% trans "You can't accept this request because of the VM's state." %}
{% else %}
<form method="POST">
{% csrf_token %}
<input type="hidden" name="accept" value="1"/>
<button class="btn btn-success">
<i class="fa fa-thumbs-up"></i>
{% trans "Accept" %}
</button>
</form>
{% endif %}
</div>
{% endif %}
{% if object.status != "PENDING" %}
<div class="text-right">
{% blocktrans with closed=object.modified|arrowfilter:LANGUAGE_CODE user=object.closed_by.profile.get_display_name %}
Closed {{ closed }} by <a href="{{ user.profile.get_absolute_url }}">{{ user }}</a>
{% endblocktrans %}
{% if object.status == "DECLINED" %}
<p>
<strong>{% trans "Reason" %}:</strong> {{ object.reason }}
</p>
{% endif %}
</div>
{% endif %}
</div><!-- .panel-body -->
</div>
</div>
</div>
{% endblock %}
{% spaceless %}
{% if LANGUAGE_CODE == "en" %}
Why do you need this lease?
{% else %} {# place your translations here #}
Why do you need this lease?
{% endif %}
{% endspaceless %}
{% spaceless %}
{% if LANGUAGE_CODE == "en" %}
Why do you need these resources?
{% else %} {# place your translations here #}
Why do you need these resources?
{% endif %}
{% endspaceless %}
{% spaceless %}
{% if LANGUAGE_CODE == "en" %}
Why do you need this template?
{% else %} {# place your translations here #}
Why do you need this template?
{% endif %}
{% endspaceless %}
{% extends "dashboard/base.html" %}
{% load i18n %}
{% load crispy_forms_tags %}
{% load render_table from django_tables2 %}
{% block title-page %}
{% if form.instance.pk %}{{ form.instance.name }}{% else %}{% trans "Create" %}{% endif %}
| {% trans "lease type" %}
{% endblock %}
{% block content %}
<div class="row">
<div class="col-md-12">
<div class="panel panel-default">
<div class="panel-heading">
<div class="pull-right">
{% if object.pk %}
<a class="btn btn-xs btn-danger"
href="{% url "request.views.lease-type-delete" pk=object.pk %}">
<i class="fa fa-times"></i> {% trans "Delete" %}
</a>
{% endif %}
<a class="btn btn-xs btn-default" href="{% url "request.views.type-list" %}">
{% trans "Back" %}
</a>
</div>
<h3 class="no-margin">
<i class="fa fa-clock-o"></i>
{% if form.instance.pk %}
{{ form.instance.name }}
{% else %}
{% trans "New lease type" %}
{% endif %}
</h3>
</div>
<div class="panel-body">
<div class="row">
<div class="col-md-8">
{% crispy form %}
</div>
</div>
</div>
</div>
</div>
</div>
{% endblock %}
{% extends "dashboard/base.html" %}
{% load staticfiles %}
{% load i18n %}
{% load render_table from django_tables2 %}
{% block title-page %}{% trans "Requests" %}{% endblock %}
{% block content %}
<div class="row">
<div class="col-md-12">
<div class="panel panel-default">
<div class="panel-heading">
<a class="btn btn-xs btn-primary pull-right "href="{% url "request.views.type-list" %}">
{% trans "Request types" %}
</a>
<h3 class="no-margin"><i class="fa fa-phone"></i> {% trans "Requests" %}</h3>
</div>
<div class="panel-body">
<div class="panel-body">
{% trans "Filter by status" %}:
<a href="{{ request.path }}">{% trans "ALL" %}</a>
{% for s in statuses %}
<a href="?status={{ s.0 }}">{{ s.1|upper }}</a>
{% endfor %}
<div class="table-responsive">
{% render_table table %}
</div>
</div>
</div><!-- .panel-body -->
</div>
</div>
</div>
{% endblock %}
{% extends "dashboard/base.html" %}
{% load i18n %}
{% block content %}
<div class="row">
<div class="col-md-12">
<div class="panel panel-default">
<div class="panel-heading">
<h3 class="no-margin">
<i class="fa fa-puzzle-piece"></i> {% trans "Request new lease" %}
</h3>
</div>
<div class="panel-body">
<div class="form-group">
<label>{% trans "Virtual machine" %}</label>
<div class="controls">
<a href="{{ vm.get_absolute_url }}">{{ vm.name }}</a>
</div>
</div>
{% include "request/_request-lease-form.html" %}
</div>
</div>
</div>
</div>
{% endblock %}
{% extends "dashboard/base.html" %}
{% load i18n %}
{% load crispy_forms_tags %}
{% block content %}
<div class="row">
<div class="col-md-12">
<div class="panel panel-default">
<div class="panel-heading">
<h3 class="no-margin">
<i class="fa fa-tasks"></i> {% trans "Request new resources" %}
</h3>
</div>
<div class="panel-body">
<form action="{% url "request.views.request-resource" vm_pk=vm.pk %}" method="POST">
{% csrf_token %}
<div class="form-group">
<label>{% trans "Virtual machine" %}</label>
<div class="controls">
<a href="{{ vm.get_absolute_url }}">{{ vm.name }}</a>
</div>
</div>
{% include "display-form-errors.html" %}
{% include "dashboard/_resources-sliders.html" with field_priority=form.priority field_num_cores=form.num_cores field_ram_size=form.ram_size %}
{{ form.message|as_crispy_field }}
<button type="submit" class="btn btn-success">
{% trans "Request new resources" %}
</button>
</form>
</div>
</div>
</div>
</div>
{% endblock %}
{% extends "dashboard/base.html" %}
{% load i18n %}
{% block content %}
<div class="row">
<div class="col-md-12">
<div class="panel panel-default">
<div class="panel-heading">
<h3 class="no-margin">
<i class="fa fa-puzzle-piece"></i> {% trans "Request template access" %}
</h3>
</div>
<div class="panel-body">
{% include "request/_request-template-form.html" %}
</div>
</div>
</div>
</div>
{% endblock %}
{% extends "dashboard/base.html" %}
{% load i18n %}
{% load crispy_forms_tags %}
{% load render_table from django_tables2 %}
{% block title-page %}
{% if form.instance.pk %}{{ form.instance.name }}{% else %}{% trans "Create" %}{% endif %}
| {% trans "template access type" %}
{% endblock %}
{% block content %}
<div class="row">
<div class="col-md-12">
<div class="panel panel-default">
<div class="panel-heading">
<div class="pull-right">
{% if object.pk %}
<a class="btn btn-xs btn-danger"
href="{% url "request.views.template-type-delete" pk=object.pk %}">
<i class="fa fa-times"></i> {% trans "Delete" %}
</a>
{% endif %}
<a class="btn btn-xs btn-default" href="{% url "request.views.type-list" %}">
{% trans "Back" %}
</a>
</div>
<h3 class="no-margin">
<i class="fa fa-puzzle-piece"></i>
{% if form.instance.pk %}
{{ form.instance.name }}
{% else %}
{% trans "New Template Access type" %}
{% endif %}
</h3>
</div>
<div class="panel-body">
<div class="row">
<div class="col-md-8">
{% crispy form %}
</div>
</div>
</div>
</div>
</div>
</div>
{% endblock %}
{% extends "dashboard/base.html" %}
{% load staticfiles %}
{% load i18n %}
{% load render_table from django_tables2 %}
{% block title-page %}{% trans "Request types" %}{% endblock %}
{% block content %}
<div class="row">
<div class="col-md-12">
<div class="panel panel-default">
<div class="panel-heading">
<div class="pull-right">
<a class="btn btn-xs btn-success" href="{% url "request.views.lease-type-create" %}">
<i class="fa fa-plus-circle"></i>
{% trans "new lease type" %}
</a>
<a class="btn btn-xs btn-success" href="{% url "request.views.template-type-create" %}">
<i class="fa fa-plus-circle"></i>
{% trans "new template access type" %}
</a>
</div>
<h3 class="no-margin"><i class="fa fa-phone"></i> {% trans "Request types" %}</h3>
</div>
<div class="panel-body">
<div class="text-muted little-margin-bottom">
{% blocktrans %}
Lease types are used for sharing leases. User can request longer ones via these.
{% endblocktrans %}
</div>
<div class="table-responsive">
{% render_table lease_table %}
</div>
<div class="text-muted little-margin-bottom">
{% blocktrans %}
Using template access types users can request multiple templates with user with operator or user level access.
{% endblocktrans %}
</div>
<div class="table-responsive">
{% render_table template_table %}
</div>
</div><!-- .panel-body -->
</div>
</div>
</div>
{% endblock %}
# Copyright 2014 Budapest University of Technology and Economics (BME IK)
#
# This file is part of CIRCLE Cloud.
#
# CIRCLE is free software: you can redistribute it and/or modify it under
# the terms of the GNU General Public License as published by the Free
# Software Foundation, either version 3 of the License, or (at your option)
# any later version.
#
# CIRCLE is distributed in the hope that it will be useful, but WITHOUT ANY
# WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
# FOR A PARTICULAR PURPOSE. See the GNU General Public License for more
# details.
#
# You should have received a copy of the GNU General Public License along
# with CIRCLE. If not, see <http://www.gnu.org/licenses/>.
from django.test import TestCase
from django.test.client import Client
from django.contrib.auth.models import User, Permission
from mock import Mock, patch
from common.tests.celery_mock import MockCeleryMixin
from vm.models import Instance, InstanceTemplate, Lease
from dashboard.models import Profile
from request.models import Request, LeaseType, TemplateAccessType
from dashboard.tests.test_views import LoginMixin
from vm.operations import ResourcesOperation
class RequestTest(LoginMixin, MockCeleryMixin, TestCase):
fixtures = ['test-vm-fixture.json', 'node.json']
def setUp(self):
Instance.get_remote_queue_name = Mock(return_value='test')
self.u1 = User.objects.create(username='user1')
self.u1.set_password('password')
self.u1.save()
self.us = User.objects.create(username='superuser', is_superuser=True)
self.us.set_password('password')
self.us.save()
self.u1.user_permissions.add(Permission.objects.get(
codename='create_vm'))
# superusers are notified uppon
for u in User.objects.filter(is_superuser=True):
p = Profile(user=u)
p.save()
self.lease = Lease(name="new lease", suspend_interval_seconds=1,
delete_interval_seconds=1)
self.lease.save()
LeaseType(name="lease type #1", lease=self.lease).save()
tat = TemplateAccessType(name="a")
tat.save()
tat.templates.add(InstanceTemplate.objects.get(pk=1))
def tearDown(self):
super(RequestTest, self).tearDown()
self.u1.delete()
self.us.delete()
def test_resources_request(self):
c = Client()
self.login(c, "user1")
inst = Instance.objects.get(pk=1)
inst.set_level(self.u1, 'owner')
req_count = Request.objects.count()
resp = c.post("/request/resource/1/", {
'num_cores': 5,
'ram_size': 512,
'priority': 30,
'message': "szia",
})
self.assertEqual(resp.status_code, 302)
self.assertEqual(req_count + 1, Request.objects.count())
new_request = Request.objects.latest("pk")
self.assertEqual(new_request.status, "PENDING")
self.assertEqual(inst.num_cores, 2)
self.assertEqual(inst.ram_size, 200)
self.assertEqual(inst.priority, 10)
# workaround for NOSTATE
inst.emergency_change_state(new_state="STOPPED", system=True)
with patch.object(ResourcesOperation, 'async') as mock_method:
mock_method.side_effect = (
new_request.action.instance.resources_change)
new_request.accept(self.us)
inst = Instance.objects.get(pk=1)
self.assertEqual(inst.num_cores, 5)
self.assertEqual(inst.ram_size, 512)
self.assertEqual(inst.priority, 30)
new_request = Request.objects.latest("pk")
self.assertEqual(new_request.status, "ACCEPTED")
def test_template_access_request(self):
c = Client()
self.login(c, "user1")
template = InstanceTemplate.objects.get(pk=1)
self.assertFalse(template.has_level(self.u1, "user"))
req_count = Request.objects.count()
resp = c.post("/request/template/", {
'template': 1,
'level': "user",
'message': "szia",
})
self.assertEqual(resp.status_code, 302)
self.assertEqual(req_count + 1, Request.objects.count())
new_request = Request.objects.latest("pk")
self.assertEqual(new_request.status, "PENDING")
new_request.accept(self.us)
new_request = Request.objects.latest("pk")
self.assertEqual(new_request.status, "ACCEPTED")
self.assertTrue(template.has_level(self.u1, "user"))
def test_lease_request(self):
c = Client()
self.login(c, "user1")
inst = Instance.objects.get(pk=1)
inst.set_level(self.u1, 'owner')
req_count = Request.objects.count()
resp = c.post("/request/lease/1/", {
'lease': 1,
'message': "szia",
})
self.assertEqual(resp.status_code, 302)
self.assertEqual(req_count + 1, Request.objects.count())
new_request = Request.objects.latest("pk")
self.assertEqual(new_request.status, "PENDING")
new_request.accept(self.us)
inst = Instance.objects.get(pk=1)
new_request = Request.objects.latest("pk")
self.assertEqual(new_request.status, "ACCEPTED")
self.assertEqual(inst.lease, self.lease)
# Copyright 2014 Budapest University of Technology and Economics (BME IK)
#
# This file is part of CIRCLE Cloud.
#
# CIRCLE is free software: you can redistribute it and/or modify it under
# the terms of the GNU General Public License as published by the Free
# Software Foundation, either version 3 of the License, or (at your option)
# any later version.
#
# CIRCLE is distributed in the hope that it will be useful, but WITHOUT ANY
# WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
# FOR A PARTICULAR PURPOSE. See the GNU General Public License for more
# details.
#
# You should have received a copy of the GNU General Public License along
# with CIRCLE. If not, see <http://www.gnu.org/licenses/>.
from __future__ import absolute_import
from django.conf.urls import patterns, url
from .views import (
RequestList, RequestDetail, RequestTypeList,
LeaseTypeCreate, LeaseTypeDetail,
TemplateAccessTypeCreate, TemplateAccessTypeDetail,
TemplateRequestView, LeaseRequestView, ResourceRequestView,
LeaseTypeDelete, TemplateAccessTypeDelete,
)
urlpatterns = patterns(
'',
url(r'^list/$', RequestList.as_view(),
name="request.views.request-list"),
url(r'^(?P<pk>\d+)/$', RequestDetail.as_view(),
name="request.views.request-detail"),
url(r'^type/list/$', RequestTypeList.as_view(),
name="request.views.type-list"),
# request types
url(r'^type/lease/create/$', LeaseTypeCreate.as_view(),
name="request.views.lease-type-create"),
url(r'^type/lease/(?P<pk>\d+)/$', LeaseTypeDetail.as_view(),
name="request.views.lease-type-detail"),
url(r'^type/lease/delete/(?P<pk>\d+)/$', LeaseTypeDelete.as_view(),
name="request.views.lease-type-delete"),
url(r'^type/template/create/$', TemplateAccessTypeCreate.as_view(),
name="request.views.template-type-create"),
url(r'^type/template/(?P<pk>\d+)/$',
TemplateAccessTypeDetail.as_view(),
name="request.views.template-type-detail"),
url(r'^type/template/delete/(?P<pk>\d+)/$',
TemplateAccessTypeDelete.as_view(),
name="request.views.template-type-delete"),
# request views (visible for users)
url(r'template/$', TemplateRequestView.as_view(),
name="request.views.request-template"),
url(r'lease/(?P<vm_pk>\d+)/$', LeaseRequestView.as_view(),
name="request.views.request-lease"),
url(r'resource/(?P<vm_pk>\d+)/$', ResourceRequestView.as_view(),
name="request.views.request-resource"),
)
# Copyright 2014 Budapest University of Technology and Economics (BME IK)
#
# This file is part of CIRCLE Cloud.
#
# CIRCLE is free software: you can redistribute it and/or modify it under
# the terms of the GNU General Public License as published by the Free
# Software Foundation, either version 3 of the License, or (at your option)
# any later version.
#
# CIRCLE is distributed in the hope that it will be useful, but WITHOUT ANY
# WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
# FOR A PARTICULAR PURPOSE. See the GNU General Public License for more
# details.
#
# You should have received a copy of the GNU General Public License along
# with CIRCLE. If not, see <http://www.gnu.org/licenses/>.
from __future__ import unicode_literals, absolute_import
from django.views.generic import (
UpdateView, TemplateView, DetailView, CreateView, FormView, DeleteView,
)
from django.shortcuts import redirect, get_object_or_404
from django.core.exceptions import PermissionDenied, SuspiciousOperation
from django.core.urlresolvers import reverse
from braces.views import SuperuserRequiredMixin, LoginRequiredMixin
from django_tables2 import SingleTableView
from request.models import (
Request, TemplateAccessType, LeaseType, TemplateAccessAction,
ExtendLeaseAction, ResourceChangeAction,
)
from vm.models import Instance
from vm.operations import ResourcesOperation
from request.tables import (
RequestTable, TemplateAccessTypeTable, LeaseTypeTable,
)
from request.forms import (
LeaseTypeForm, TemplateAccessTypeForm, TemplateRequestForm,
LeaseRequestForm, ResourceRequestForm,
)
class RequestList(LoginRequiredMixin, SuperuserRequiredMixin, SingleTableView):
model = Request
table_class = RequestTable
template_name = "request/list.html"
def get_context_data(self, **kwargs):
context = super(RequestList, self).get_context_data(**kwargs)
context['statuses'] = Request.STATUSES
return context
def get_table_data(self):
data = Request.objects.all()
status = self.request.GET.get("status")
if status:
data = data.filter(status=status)
return data
class RequestDetail(LoginRequiredMixin, DetailView):
model = Request
template_name = "request/detail.html"
def post(self, *args, **kwargs):
user = self.request.user
request = self.get_object() # not self.request!
if not user.is_superuser:
raise SuspiciousOperation
if self.get_object().status == "PENDING":
accept = self.request.POST.get("accept")
reason = self.request.POST.get("reason")
if accept:
request.accept(user)
else:
request.decline(user, reason)
return redirect(request.get_absolute_url())
def get_context_data(self, **kwargs):
request = self.object
user = self.request.user
if not user.is_superuser and request.user != user:
raise SuspiciousOperation
context = super(RequestDetail, self).get_context_data(**kwargs)
context['action'] = request.action
context['accept_states'] = ResourcesOperation.accept_states
return context
class TemplateAccessTypeDetail(LoginRequiredMixin, SuperuserRequiredMixin,
UpdateView):
model = TemplateAccessType
template_name = "request/template-type-form.html"
form_class = TemplateAccessTypeForm
class TemplateAccessTypeCreate(LoginRequiredMixin, SuperuserRequiredMixin,
CreateView):
model = TemplateAccessType
template_name = "request/template-type-form.html"
form_class = TemplateAccessTypeForm
class TemplateAccessTypeDelete(LoginRequiredMixin, SuperuserRequiredMixin,
DeleteView):
model = TemplateAccessType
template_name = "dashboard/confirm/base-delete.html"
def get_success_url(self):
return reverse("request.views.type-list")
class LeaseTypeDetail(LoginRequiredMixin, SuperuserRequiredMixin, UpdateView):
model = LeaseType
template_name = "request/lease-type-form.html"
form_class = LeaseTypeForm
class LeaseTypeCreate(LoginRequiredMixin, SuperuserRequiredMixin, CreateView):
model = LeaseType
template_name = "request/lease-type-form.html"
form_class = LeaseTypeForm
class LeaseTypeDelete(LoginRequiredMixin, SuperuserRequiredMixin, DeleteView):
model = LeaseType
template_name = "dashboard/confirm/base-delete.html"
def get_success_url(self):
return reverse("request.views.type-list")
class RequestTypeList(LoginRequiredMixin, SuperuserRequiredMixin,
TemplateView):
template_name = "request/type-list.html"
def get_context_data(self, **kwargs):
context = super(RequestTypeList, self).get_context_data(**kwargs)
context['lease_table'] = LeaseTypeTable(
LeaseType.objects.all(), request=self.request)
context['template_table'] = TemplateAccessTypeTable(
TemplateAccessType.objects.all(), request=self.request)
return context
class TemplateRequestView(FormView):
form_class = TemplateRequestForm
template_name = "request/request-template.html"
def get_form_kwargs(self):
kwargs = super(TemplateRequestView, self).get_form_kwargs()
kwargs['request'] = self.request
return kwargs
def form_valid(self, form):
data = form.cleaned_data
user = self.request.user
ta = TemplateAccessAction(
template_type=data['template'],
level=data['level'],
user=user,
)
ta.save()
req = Request(
user=user,
message=data['message'],
type=Request.TYPES.template,
action=ta
)
req.save()
return redirect("/")
class VmRequestMixin(object):
def get_vm(self):
return get_object_or_404(Instance, pk=self.kwargs['vm_pk'])
def dispatch(self, *args, **kwargs):
vm = self.get_vm()
user = self.request.user
if not vm.has_level(user, self.user_level):
raise PermissionDenied()
return super(VmRequestMixin, self).dispatch(*args, **kwargs)
def get_context_data(self, **kwargs):
context = super(VmRequestMixin, self).get_context_data(**kwargs)
context['vm'] = self.get_vm()
return context
def get_form_kwargs(self):
kwargs = super(VmRequestMixin, self).get_form_kwargs()
kwargs['request'] = self.request
return kwargs
def form_valid(self, form):
raise NotImplementedError
class LeaseRequestView(VmRequestMixin, FormView):
form_class = LeaseRequestForm
template_name = "request/request-lease.html"
user_level = "operator"
def form_valid(self, form):
data = form.cleaned_data
user = self.request.user
vm = self.get_vm()
el = ExtendLeaseAction(
lease_type=data['lease'],
instance=vm,
)
el.save()
req = Request(
user=user,
message=data['message'],
type=Request.TYPES.lease,
action=el
)
req.save()
return redirect(vm.get_absolute_url())
class ResourceRequestView(VmRequestMixin, FormView):
form_class = ResourceRequestForm
template_name = "request/request-resource.html"
user_level = "user"
def get_form_kwargs(self):
kwargs = super(ResourceRequestView, self).get_form_kwargs()
kwargs['can_edit'] = True
kwargs['instance'] = self.get_vm()
return kwargs
def get_initial(self):
vm = self.get_vm()
initial = super(ResourceRequestView, self).get_initial()
initial['num_cores'] = vm.num_cores
initial['priority'] = vm.priority
initial['ram_size'] = vm.ram_size
return initial
def form_valid(self, form):
vm = self.get_vm()
data = form.cleaned_data
user = self.request.user
rc = ResourceChangeAction(
instance=vm,
num_cores=data['num_cores'],
priority=data['priority'],
ram_size=data['ram_size'],
)
rc.save()
req = Request(
user=user,
message=data['message'],
type=Request.TYPES.resource,
action=rc
)
req.save()
return redirect(vm.get_absolute_url())
......@@ -1334,10 +1334,20 @@ class ResourcesOperation(InstanceOperation):
description = _("Change resources of a stopped virtual machine.")
acl_level = "owner"
required_perms = ('vm.change_resources', )
accept_states = ('STOPPED', 'PENDING', )
accept_states = ('STOPPED', 'PENDING', 'RUNNING')
def _operation(self, user, activity,
num_cores, ram_size, max_ram_size, priority):
num_cores, ram_size, max_ram_size, priority,
with_shutdown=False, task=None):
if self.instance.status == 'RUNNING' and not with_shutdown:
raise Instance.WrongStateError(self.instance)
try:
self.instance.shutdown(parent_activity=activity, task=task)
except Instance.WrongStateError:
pass
self.instance._update_status()
self.instance.num_cores = num_cores
self.instance.ram_size = ram_size
......
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