Skip to content
Toggle navigation
P
Projects
G
Groups
S
Snippets
Help
Gelencsér Szabolcs
/
circlestack
This project
Loading...
Sign in
Toggle navigation
Go to a project
Project
Repository
Issues
0
Merge Requests
0
Pipelines
Wiki
Snippets
Members
Activity
Graph
Charts
Create a new issue
Jobs
Commits
Issue Boards
Files
Commits
Branches
Tags
Contributors
Graph
Compare
Charts
Commit
c8b6d787
authored
Jul 01, 2015
by
Kálmán Viktor
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
dashboard: disk resize messages
parent
11c3e46a
Show whitespace changes
Inline
Side-by-side
Showing
4 changed files
with
66 additions
and
21 deletions
+66
-21
circle/circle/urls.py
+2
-1
circle/request/models.py
+25
-9
circle/request/templates/request/detail.html
+21
-2
circle/request/views.py
+18
-9
No files found.
circle/circle/urls.py
View file @
c8b6d787
...
@@ -65,7 +65,8 @@ urlpatterns = patterns(
...
@@ -65,7 +65,8 @@ urlpatterns = patterns(
url
(
r'^info/support/$'
,
url
(
r'^info/support/$'
,
TemplateView
.
as_view
(
template_name
=
"info/support.html"
),
TemplateView
.
as_view
(
template_name
=
"info/support.html"
),
name
=
"info.support"
),
name
=
"info.support"
),
url
(
r'^info/resize-how-to/$'
,
ResizeHelpView
.
as_view
(),
name
=
"info.resize"
),
url
(
r'^info/resize-how-to/$'
,
ResizeHelpView
.
as_view
(),
name
=
"info.resize"
),
)
)
...
...
circle/request/models.py
View file @
c8b6d787
...
@@ -35,8 +35,10 @@ import requests
...
@@ -35,8 +35,10 @@ import requests
from
sizefield.models
import
FileSizeField
from
sizefield.models
import
FileSizeField
from
model_utils.models
import
TimeStampedModel
from
model_utils.models
import
TimeStampedModel
from
model_utils
import
Choices
from
model_utils
import
Choices
from
sizefield.utils
import
filesizeformat
from
vm.models
import
Instance
,
InstanceTemplate
,
Lease
from
vm.models
import
Instance
,
InstanceTemplate
,
Lease
from
vm.operations
import
ResourcesOperation
,
ResizeDiskOperation
from
storage.models
import
Disk
from
storage.models
import
Disk
logger
=
logging
.
getLogger
(
__name__
)
logger
=
logging
.
getLogger
(
__name__
)
...
@@ -51,6 +53,9 @@ class RequestAction(Model):
...
@@ -51,6 +53,9 @@ class RequestAction(Model):
def
accept_msg
(
self
):
def
accept_msg
(
self
):
raise
NotImplementedError
raise
NotImplementedError
def
is_acceptable
(
self
):
return
True
class
Meta
:
class
Meta
:
abstract
=
True
abstract
=
True
...
@@ -147,6 +152,10 @@ class Request(TimeStampedModel):
...
@@ -147,6 +152,10 @@ class Request(TimeStampedModel):
decline_msg
,
url
=
self
.
get_absolute_url
(),
reason
=
self
.
reason
,
decline_msg
,
url
=
self
.
get_absolute_url
(),
reason
=
self
.
reason
,
)
)
@property
def
is_acceptable
(
self
):
return
self
.
action
.
is_acceptable
()
class
LeaseType
(
RequestType
):
class
LeaseType
(
RequestType
):
lease
=
ForeignKey
(
Lease
,
verbose_name
=
_
(
"Lease"
))
lease
=
ForeignKey
(
Lease
,
verbose_name
=
_
(
"Lease"
))
...
@@ -204,6 +213,9 @@ class ResourceChangeAction(RequestAction):
...
@@ -204,6 +213,9 @@ class ResourceChangeAction(RequestAction):
'priority'
:
self
.
priority
,
'priority'
:
self
.
priority
,
}
}
def
is_acceptable
(
self
):
return
self
.
instance
.
status
in
ResourcesOperation
.
accept_states
class
ExtendLeaseAction
(
RequestAction
):
class
ExtendLeaseAction
(
RequestAction
):
instance
=
ForeignKey
(
Instance
)
instance
=
ForeignKey
(
Instance
)
...
@@ -255,19 +267,23 @@ class DiskResizeAction(RequestAction):
...
@@ -255,19 +267,23 @@ class DiskResizeAction(RequestAction):
disk
=
ForeignKey
(
Disk
)
disk
=
ForeignKey
(
Disk
)
size
=
FileSizeField
(
null
=
True
,
default
=
None
)
size
=
FileSizeField
(
null
=
True
,
default
=
None
)
def
get_readable_level
(
self
):
return
self
.
LEVELS
[
self
.
level
]
def
accept
(
self
,
user
):
def
accept
(
self
,
user
):
pass
self
.
instance
.
resize_disk
(
disk
=
self
.
disk
,
size
=
self
.
size
,
user
=
user
)
@property
@property
def
accept_msg
(
self
):
def
accept_msg
(
self
):
return
ungettext
(
return
_
(
"You got access to the following template:
%
s"
,
'The disk <em class="text-muted">
%(disk_name)
s (#
%(id)
d)</em> of '
"You got access to the following templates:
%
s"
,
'<a href="
%(url)
s">
%(vm_name)
s</a> got resized. '
self
.
template_type
.
templates
.
count
()
'The new size is:
%(bytes)
d bytes (
%(size)
s).'
)
%
", "
.
join
([
x
.
name
for
x
in
self
.
template_type
.
templates
.
all
()])
)
%
{
'disk_name'
:
self
.
disk
.
name
,
'id'
:
self
.
disk
.
id
,
'url'
:
self
.
instance
.
get_absolute_url
(),
'vm_name'
:
self
.
instance
.
name
,
'bytes'
:
self
.
size
,
'size'
:
filesizeformat
(
self
.
size
),
}
def
is_acceptable
(
self
):
return
self
.
instance
.
status
in
ResizeDiskOperation
.
accept_states
def
send_notifications
(
sender
,
instance
,
created
,
**
kwargs
):
def
send_notifications
(
sender
,
instance
,
created
,
**
kwargs
):
...
...
circle/request/templates/request/detail.html
View file @
c8b6d787
...
@@ -66,6 +66,15 @@
...
@@ -66,6 +66,15 @@
<dd>
{{ action.get_readable_level }}
</dd>
<dd>
{{ action.get_readable_level }}
</dd>
</dl>
</dl>
{% elif object.type == "resource" %}
{% elif object.type == "resource" %}
{% if not is_acceptable %}
<div
class=
"alert alert-warning"
>
{% blocktrans %}
To change the resources the virtual machine must be in one of the following states:
STOPPED, PENDING, RUNNING. If the virtual machine is running it will be
automatically stopped when accepting the request.
{% endblocktrans %}
</div>
{% endif %}
<dl>
<dl>
<dt>
{% trans "VM name" %}
</dt>
<dt>
{% trans "VM name" %}
</dt>
<dd><a
href=
"{{ action.instance.get_absolute_url }}"
>
{{ action.instance.name }}
</a></dd>
<dd><a
href=
"{{ action.instance.get_absolute_url }}"
>
{{ action.instance.name }}
</a></dd>
...
@@ -75,7 +84,7 @@
...
@@ -75,7 +84,7 @@
{{ action.instance.get_status_display|upper }}
{{ action.instance.get_status_display|upper }}
</dd>
</dd>
<dt>
{% trans "VM description" %}
</dt>
<dt>
{% trans "VM description" %}
</dt>
<dd>
{{ action.instance.description }}
</dd>
<dd>
{{ action.instance.description
|default:"-"
}}
</dd>
<dt>
<dt>
{% trans "Priority" %}
{% trans "Priority" %}
<span
class=
"text-muted"
style=
"font-weight: normal;"
>
{% trans "(old values in parentheses)" %}
</span>
<span
class=
"text-muted"
style=
"font-weight: normal;"
>
{% trans "(old values in parentheses)" %}
</span>
...
@@ -87,9 +96,19 @@
...
@@ -87,9 +96,19 @@
<dd>
{{ action.ram_size }} ({{ action.instance.ram_size }}) MiB
</dd>
<dd>
{{ action.ram_size }} ({{ action.instance.ram_size }}) MiB
</dd>
</dl>
</dl>
{% elif object.type == "resize" %}
{% elif object.type == "resize" %}
{% if not is_acceptable %}
<div
class=
"alert alert-warning"
>
{% trans "To resize the disk the virtual machine must be in RUNNING state." %}
</div>
{% endif %}
<dl>
<dl>
<dt>
{% trans "VM name" %}
</dt>
<dt>
{% trans "VM name" %}
</dt>
<dd><a
href=
"{{ action.instance.get_absolute_url }}"
>
{{ action.instance.name }}
</a></dd>
<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>
<dt>
{% trans "VM description" %}
</dt>
<dd>
{{ action.instance.description|default:"-" }}
</dd>
<dd>
{{ action.instance.description|default:"-" }}
</dd>
<dt>
{% trans "Disk" %}
</dt>
<dt>
{% trans "Disk" %}
</dt>
...
@@ -125,7 +144,7 @@
...
@@ -125,7 +144,7 @@
{% trans "Decline" %}
{% trans "Decline" %}
</button>
</button>
</form>
</form>
{% if
object.type == "resource" and action.instance.status not in accept_states
%}
{% if
not is_acceptable
%}
{% trans "You can't accept this request because of the VM's state." %}
{% trans "You can't accept this request because of the VM's state." %}
{% else %}
{% else %}
<form
method=
"POST"
>
<form
method=
"POST"
>
...
...
circle/request/views.py
View file @
c8b6d787
...
@@ -19,11 +19,13 @@ from __future__ import unicode_literals, absolute_import
...
@@ -19,11 +19,13 @@ from __future__ import unicode_literals, absolute_import
from
django.views.generic
import
(
from
django.views.generic
import
(
UpdateView
,
TemplateView
,
DetailView
,
CreateView
,
FormView
,
DeleteView
,
UpdateView
,
TemplateView
,
DetailView
,
CreateView
,
FormView
,
DeleteView
,
)
)
from
django.contrib
import
messages
from
django.contrib.messages.views
import
SuccessMessageMixin
from
django.contrib.messages.views
import
SuccessMessageMixin
from
django.shortcuts
import
redirect
,
get_object_or_404
from
django.shortcuts
import
redirect
,
get_object_or_404
from
django.core.exceptions
import
PermissionDenied
,
SuspiciousOperation
from
django.core.exceptions
import
PermissionDenied
,
SuspiciousOperation
from
django.core.urlresolvers
import
reverse
from
django.core.urlresolvers
import
reverse
from
django.utils.translation
import
ugettext
as
_
from
django.utils.translation
import
ugettext
as
_
from
django.http
import
JsonResponse
from
braces.views
import
SuperuserRequiredMixin
,
LoginRequiredMixin
from
braces.views
import
SuperuserRequiredMixin
,
LoginRequiredMixin
from
django_tables2
import
SingleTableView
from
django_tables2
import
SingleTableView
...
@@ -34,7 +36,6 @@ from request.models import (
...
@@ -34,7 +36,6 @@ from request.models import (
)
)
from
storage.models
import
Disk
from
storage.models
import
Disk
from
vm.models
import
Instance
from
vm.models
import
Instance
from
vm.operations
import
ResourcesOperation
from
request.tables
import
(
from
request.tables
import
(
RequestTable
,
TemplateAccessTypeTable
,
LeaseTypeTable
,
RequestTable
,
TemplateAccessTypeTable
,
LeaseTypeTable
,
)
)
...
@@ -94,7 +95,7 @@ class RequestDetail(LoginRequiredMixin, DetailView):
...
@@ -94,7 +95,7 @@ class RequestDetail(LoginRequiredMixin, DetailView):
context
=
super
(
RequestDetail
,
self
)
.
get_context_data
(
**
kwargs
)
context
=
super
(
RequestDetail
,
self
)
.
get_context_data
(
**
kwargs
)
context
[
'action'
]
=
request
.
action
context
[
'action'
]
=
request
.
action
context
[
'
accept_states'
]
=
ResourcesOperation
.
accept_states
context
[
'
is_acceptable'
]
=
request
.
is_acceptable
# workaround for http://git.io/vIIYi
# workaround for http://git.io/vIIYi
context
[
'request'
]
=
self
.
request
context
[
'request'
]
=
self
.
request
...
@@ -168,6 +169,7 @@ class RequestTypeList(LoginRequiredMixin, SuperuserRequiredMixin,
...
@@ -168,6 +169,7 @@ class RequestTypeList(LoginRequiredMixin, SuperuserRequiredMixin,
class
TemplateRequestView
(
LoginRequiredMixin
,
FormView
):
class
TemplateRequestView
(
LoginRequiredMixin
,
FormView
):
form_class
=
TemplateRequestForm
form_class
=
TemplateRequestForm
template_name
=
"request/request-template.html"
template_name
=
"request/request-template.html"
success_message
=
_
(
"Request successfully sent."
)
def
get_form_kwargs
(
self
):
def
get_form_kwargs
(
self
):
kwargs
=
super
(
TemplateRequestView
,
self
)
.
get_form_kwargs
()
kwargs
=
super
(
TemplateRequestView
,
self
)
.
get_form_kwargs
()
...
@@ -193,7 +195,8 @@ class TemplateRequestView(LoginRequiredMixin, FormView):
...
@@ -193,7 +195,8 @@ class TemplateRequestView(LoginRequiredMixin, FormView):
)
)
req
.
save
()
req
.
save
()
return
redirect
(
"/"
)
messages
.
success
(
self
.
request
,
self
.
success_message
)
return
redirect
(
reverse
(
"dashboard.index"
))
class
VmRequestMixin
(
LoginRequiredMixin
,
object
):
class
VmRequestMixin
(
LoginRequiredMixin
,
object
):
...
@@ -225,6 +228,7 @@ class LeaseRequestView(VmRequestMixin, FormView):
...
@@ -225,6 +228,7 @@ class LeaseRequestView(VmRequestMixin, FormView):
form_class
=
LeaseRequestForm
form_class
=
LeaseRequestForm
template_name
=
"request/request-lease.html"
template_name
=
"request/request-lease.html"
user_level
=
"operator"
user_level
=
"operator"
success_message
=
_
(
"Request successfully sent."
)
def
form_valid
(
self
,
form
):
def
form_valid
(
self
,
form
):
data
=
form
.
cleaned_data
data
=
form
.
cleaned_data
...
@@ -245,6 +249,7 @@ class LeaseRequestView(VmRequestMixin, FormView):
...
@@ -245,6 +249,7 @@ class LeaseRequestView(VmRequestMixin, FormView):
)
)
req
.
save
()
req
.
save
()
messages
.
success
(
self
.
request
,
self
.
success_message
)
return
redirect
(
vm
.
get_absolute_url
())
return
redirect
(
vm
.
get_absolute_url
())
...
@@ -252,6 +257,7 @@ class ResourceRequestView(VmRequestMixin, FormView):
...
@@ -252,6 +257,7 @@ class ResourceRequestView(VmRequestMixin, FormView):
form_class
=
ResourceRequestForm
form_class
=
ResourceRequestForm
template_name
=
"request/request-resource.html"
template_name
=
"request/request-resource.html"
user_level
=
"user"
user_level
=
"user"
success_message
=
_
(
"Request successfully sent."
)
def
get_form_kwargs
(
self
):
def
get_form_kwargs
(
self
):
kwargs
=
super
(
ResourceRequestView
,
self
)
.
get_form_kwargs
()
kwargs
=
super
(
ResourceRequestView
,
self
)
.
get_form_kwargs
()
...
@@ -288,6 +294,7 @@ class ResourceRequestView(VmRequestMixin, FormView):
...
@@ -288,6 +294,7 @@ class ResourceRequestView(VmRequestMixin, FormView):
)
)
req
.
save
()
req
.
save
()
messages
.
success
(
self
.
request
,
self
.
success_message
)
return
redirect
(
vm
.
get_absolute_url
())
return
redirect
(
vm
.
get_absolute_url
())
...
@@ -295,6 +302,7 @@ class ResizeRequestView(VmRequestMixin, FormView):
...
@@ -295,6 +302,7 @@ class ResizeRequestView(VmRequestMixin, FormView):
form_class
=
ResizeRequestForm
form_class
=
ResizeRequestForm
template_name
=
"request/_request-resize-form.html"
template_name
=
"request/_request-resize-form.html"
user_level
=
"owner"
user_level
=
"owner"
success_message
=
_
(
"Request successfully sent."
)
def
get_disk
(
self
,
*
args
,
**
kwargs
):
def
get_disk
(
self
,
*
args
,
**
kwargs
):
return
get_object_or_404
(
Disk
,
pk
=
self
.
kwargs
[
'disk_pk'
])
return
get_object_or_404
(
Disk
,
pk
=
self
.
kwargs
[
'disk_pk'
])
...
@@ -327,12 +335,13 @@ class ResizeRequestView(VmRequestMixin, FormView):
...
@@ -327,12 +335,13 @@ class ResizeRequestView(VmRequestMixin, FormView):
dra
=
DiskResizeAction
(
instance
=
vm
,
disk
=
disk
,
size
=
data
[
'size'
])
dra
=
DiskResizeAction
(
instance
=
vm
,
disk
=
disk
,
size
=
data
[
'size'
])
dra
.
save
()
dra
.
save
()
req
=
Request
(
req
=
Request
(
user
=
user
,
message
=
data
[
'message'
],
action
=
dra
,
user
=
user
,
type
=
Request
.
TYPES
.
resize
)
message
=
data
[
'message'
],
type
=
Request
.
TYPES
.
resize
,
action
=
dra
)
req
.
save
()
req
.
save
()
if
self
.
request
.
is_ajax
():
return
JsonResponse
({
'success'
:
True
,
'messages'
:
[
self
.
success_message
]})
else
:
messages
.
success
(
self
.
request
,
self
.
success_message
)
return
redirect
(
vm
.
get_absolute_url
())
return
redirect
(
vm
.
get_absolute_url
())
Write
Preview
Markdown
is supported
0%
Try again
or
attach a new file
Attach a file
Cancel
You are about to add
0
people
to the discussion. Proceed with caution.
Finish editing this message first!
Cancel
Please
register
or
sign in
to comment