Skip to content
Toggle navigation
P
Projects
G
Groups
S
Snippets
Help
Gutyán Gábor
/
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
4ce5d3d5
authored
Feb 04, 2014
by
Kálmán Viktor
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
dashboard: add disk to instances
parent
0a3fc812
Hide whitespace changes
Inline
Side-by-side
Showing
6 changed files
with
137 additions
and
3 deletions
+137
-3
circle/dashboard/forms.py
+42
-1
circle/dashboard/static/dashboard/vm-details.js
+6
-0
circle/dashboard/templates/dashboard/base.html
+1
-1
circle/dashboard/templates/dashboard/vm-detail/resources.html
+40
-0
circle/dashboard/tests/test_views.py
+22
-0
circle/dashboard/views.py
+26
-1
No files found.
circle/dashboard/forms.py
View file @
4ce5d3d5
from
datetime
import
timedelta
from
datetime
import
timedelta
import
uuid
from
crispy_forms.helper
import
FormHelper
from
crispy_forms.helper
import
FormHelper
from
crispy_forms.layout
import
(
from
crispy_forms.layout
import
(
...
@@ -10,9 +11,10 @@ from django.forms.widgets import TextInput
...
@@ -10,9 +11,10 @@ from django.forms.widgets import TextInput
from
django.template
import
Context
from
django.template
import
Context
from
django.template.loader
import
render_to_string
from
django.template.loader
import
render_to_string
from
django.utils.translation
import
ugettext
as
_
from
django.utils.translation
import
ugettext
as
_
from
sizefield.widgets
import
FileSizeWidget
from
firewall.models
import
Vlan
,
Host
from
firewall.models
import
Vlan
,
Host
from
storage.models
import
Disk
from
storage.models
import
Disk
,
DataStore
from
vm.models
import
InstanceTemplate
,
Lease
,
InterfaceTemplate
,
Node
from
vm.models
import
InstanceTemplate
,
Lease
,
InterfaceTemplate
,
Node
...
@@ -695,6 +697,45 @@ class LeaseForm(forms.ModelForm):
...
@@ -695,6 +697,45 @@ class LeaseForm(forms.ModelForm):
model
=
Lease
model
=
Lease
class
DiskAddForm
(
forms
.
Form
):
name
=
forms
.
CharField
()
size
=
forms
.
CharField
(
widget
=
FileSizeWidget
)
def
clean_size
(
self
):
size_in_bytes
=
self
.
cleaned_data
.
get
(
"size"
)
if
not
size_in_bytes
.
isdigit
():
raise
forms
.
ValidationError
(
_
(
"Invalid format, you can use "
" GB or MB!"
))
return
size_in_bytes
def
save
(
self
,
vm
,
commit
=
True
):
data
=
self
.
cleaned_data
d
=
Disk
(
name
=
data
[
'name'
],
filename
=
str
(
uuid
.
uuid4
()),
datastore
=
DataStore
.
objects
.
all
()[
0
],
type
=
"qcow2-norm"
,
size
=
data
[
'size'
],
dev_num
=
"a"
,
)
d
.
save
()
vm
.
disks
.
add
(
d
)
return
d
@property
def
helper
(
self
):
helper
=
FormHelper
()
helper
.
form_show_labels
=
False
helper
.
layout
=
Layout
(
Field
(
"name"
,
placeholder
=
_
(
"Name"
)),
Field
(
"size"
,
placeholder
=
_
(
"Disk size (for example: 20GB, "
"1500MB)"
)),
)
helper
.
add_input
(
Submit
(
"submit"
,
"Create new disk"
,
css_class
=
"btn btn-success"
))
return
helper
class
LinkButton
(
BaseInput
):
class
LinkButton
(
BaseInput
):
"""
"""
...
...
circle/dashboard/static/dashboard/vm-details.js
View file @
4ce5d3d5
...
@@ -145,6 +145,12 @@ $(function() {
...
@@ -145,6 +145,12 @@ $(function() {
$
(
'input[name="new_network_managed"]'
).
tooltip
();
$
(
'input[name="new_network_managed"]'
).
tooltip
();
return
false
;
return
false
;
});
});
/* add disk button */
$
(
"#vm-details-disk-add"
).
click
(
function
()
{
$
(
"#vm-details-disk-add-for-form"
).
html
(
$
(
"#vm-details-disk-add-form"
).
html
());
return
false
;
});
});
});
...
...
circle/dashboard/templates/dashboard/base.html
View file @
4ce5d3d5
...
@@ -41,7 +41,7 @@
...
@@ -41,7 +41,7 @@
{% for message in messages %}
{% for message in messages %}
<div
class=
"alert
<div
class=
"alert
{% if message.tags %} alert-{% if message.tags == "
error
"
%}
danger
{%
else
%}{{
message
.
tags
}}{%
endif
%}{%
endif
%}"
>
{% if message.tags %} alert-{% if message.tags == "
error
"
%}
danger
{%
else
%}{{
message
.
tags
}}{%
endif
%}{%
endif
%}"
>
{{ message }}
{{ message
|safe
}}
</div>
</div>
{% endfor %}
{% endfor %}
{% endif %}
{% endif %}
...
...
circle/dashboard/templates/dashboard/vm-detail/resources.html
View file @
4ce5d3d5
{% load i18n %}
{% load i18n %}
{% load sizefieldtags %}
{% load crispy_forms_tags %}
<form
id=
"vm-details-resources-form"
method=
"POST"
action=
""
>
<form
id=
"vm-details-resources-form"
method=
"POST"
action=
""
>
{% csrf_token %}
{% csrf_token %}
<p
class=
"row"
>
<p
class=
"row"
>
...
@@ -36,8 +39,45 @@
...
@@ -36,8 +39,45 @@
</div>
</div>
</p>
</p>
</form>
</form>
<hr
/>
<div
class=
"row"
>
<div
class=
"col-sm-11"
>
<h3>
{% trans "Disks" %}
<div
class=
"pull-right"
>
<a
href=
"#"
id=
"vm-details-disk-add"
class=
"btn btn-success btn-xs"
>
<i
class=
"icon-plus"
></i>
{% trans "Add new disk" %}
</a>
</div>
</h3>
<div
class=
"row"
id=
"vm-details-disk-add-for-form"
>
</div>
{% for d in instance.disks.all %}
<h4
class=
"list-group-item-heading dashboard-vm-details-network-h3"
>
<i
class=
"icon-file"
></i>
{{ d.name }} - {{ d.size|filesize }}
</h4>
{% endfor %}
</div>
</div>
<div
class=
"js-hidden row"
id=
"vm-details-disk-add-form"
>
<div
class=
"col-md-12"
>
<div>
<hr
/>
<form
method=
"POST"
action=
""
style=
"max-width: 300px;"
>
{% crispy forms.disk_add_form %}
</form>
<hr
/>
</div>
</div>
</div>
{% block extra_js %}
{% block extra_js %}
<style>
<style>
label
{
padding-top
:
6px
;}
label
{
padding-top
:
6px
;}
.form-group
{
margin-bottom
:
8px
;}
</style>
</style>
{% endblock %}
{% endblock %}
circle/dashboard/tests/test_views.py
View file @
4ce5d3d5
...
@@ -202,3 +202,25 @@ class VmDetailTest(TestCase):
...
@@ -202,3 +202,25 @@ class VmDetailTest(TestCase):
# redirect to the login page
# redirect to the login page
self
.
assertEqual
(
response
.
status_code
,
302
)
self
.
assertEqual
(
response
.
status_code
,
302
)
self
.
assertEqual
(
leases
,
Lease
.
objects
.
count
())
self
.
assertEqual
(
leases
,
Lease
.
objects
.
count
())
def
test_unpermitted_vm_disk_add
(
self
):
c
=
Client
()
self
.
login
(
c
,
"user2"
)
inst
=
Instance
.
objects
.
get
(
pk
=
1
)
inst
.
set_level
(
self
.
u1
,
'owner'
)
disks
=
inst
.
disks
.
count
()
response
=
c
.
post
(
"/dashboard/vm/1/"
,
{
'disk-name'
:
"a"
,
'disk-size'
:
1
})
self
.
assertEqual
(
response
.
status_code
,
403
)
self
.
assertEqual
(
disks
,
inst
.
disks
.
count
())
def
test_permitted_vm_disk_add
(
self
):
c
=
Client
()
self
.
login
(
c
,
"user1"
)
inst
=
Instance
.
objects
.
get
(
pk
=
1
)
inst
.
set_level
(
self
.
u1
,
'owner'
)
disks
=
inst
.
disks
.
count
()
response
=
c
.
post
(
"/dashboard/vm/1/"
,
{
'disk-name'
:
"a"
,
'disk-size'
:
1
})
self
.
assertEqual
(
response
.
status_code
,
302
)
self
.
assertEqual
(
disks
+
1
,
inst
.
disks
.
count
())
circle/dashboard/views.py
View file @
4ce5d3d5
...
@@ -19,12 +19,15 @@ from django.views.generic import (TemplateView, DetailView, View, DeleteView,
...
@@ -19,12 +19,15 @@ from django.views.generic import (TemplateView, DetailView, View, DeleteView,
UpdateView
,
CreateView
)
UpdateView
,
CreateView
)
from
django.contrib
import
messages
from
django.contrib
import
messages
from
django.utils.translation
import
ugettext
as
_
from
django.utils.translation
import
ugettext
as
_
from
django.template.defaultfilters
import
title
from
django.forms.models
import
inlineformset_factory
from
django.forms.models
import
inlineformset_factory
from
django_tables2
import
SingleTableView
from
django_tables2
import
SingleTableView
from
braces.views
import
LoginRequiredMixin
,
SuperuserRequiredMixin
from
braces.views
import
LoginRequiredMixin
,
SuperuserRequiredMixin
from
.forms
import
VmCreateForm
,
TemplateForm
,
LeaseForm
,
NodeForm
,
HostForm
from
.forms
import
(
VmCreateForm
,
TemplateForm
,
LeaseForm
,
NodeForm
,
HostForm
,
DiskAddForm
,
)
from
.tables
import
(
VmListTable
,
NodeListTable
,
NodeVmListTable
,
from
.tables
import
(
VmListTable
,
NodeListTable
,
NodeVmListTable
,
TemplateListTable
,
LeaseListTable
,
GroupListTable
)
TemplateListTable
,
LeaseListTable
,
GroupListTable
)
from
vm.models
import
(
Instance
,
InstanceTemplate
,
InterfaceTemplate
,
from
vm.models
import
(
Instance
,
InstanceTemplate
,
InterfaceTemplate
,
...
@@ -150,6 +153,9 @@ class VmDetailView(CheckedDetailView):
...
@@ -150,6 +153,9 @@ class VmDetailView(CheckedDetailView):
context
[
'vlans'
]
=
Vlan
.
get_objects_with_level
(
context
[
'vlans'
]
=
Vlan
.
get_objects_with_level
(
'user'
,
self
.
request
.
user
)
.
all
()
'user'
,
self
.
request
.
user
)
.
all
()
context
[
'acl'
]
=
get_acl_data
(
instance
)
context
[
'acl'
]
=
get_acl_data
(
instance
)
context
[
'forms'
]
=
{
'disk_add_form'
:
DiskAddForm
(
prefix
=
"disk"
),
}
return
context
return
context
def
post
(
self
,
request
,
*
args
,
**
kwargs
):
def
post
(
self
,
request
,
*
args
,
**
kwargs
):
...
@@ -165,6 +171,7 @@ class VmDetailView(CheckedDetailView):
...
@@ -165,6 +171,7 @@ class VmDetailView(CheckedDetailView):
'port'
:
self
.
__add_port
,
'port'
:
self
.
__add_port
,
'new_network_vlan'
:
self
.
__new_network
,
'new_network_vlan'
:
self
.
__new_network
,
'save_as'
:
self
.
__save_as
,
'save_as'
:
self
.
__save_as
,
'disk-name'
:
self
.
__add_disk
,
}
}
for
k
,
v
in
options
.
iteritems
():
for
k
,
v
in
options
.
iteritems
():
...
@@ -333,6 +340,24 @@ class VmDetailView(CheckedDetailView):
...
@@ -333,6 +340,24 @@ class VmDetailView(CheckedDetailView):
return
redirect
(
reverse_lazy
(
"dashboard.views.template-detail"
,
return
redirect
(
reverse_lazy
(
"dashboard.views.template-detail"
,
kwargs
=
{
'pk'
:
template
.
pk
}))
kwargs
=
{
'pk'
:
template
.
pk
}))
def
__add_disk
(
self
,
request
):
self
.
object
=
self
.
get_object
()
if
not
self
.
object
.
has_level
(
request
.
user
,
'owner'
):
raise
PermissionDenied
()
form
=
DiskAddForm
(
request
.
POST
,
prefix
=
"disk"
)
if
form
.
is_valid
():
messages
.
success
(
request
,
_
(
"New disk successfully created!"
))
form
.
save
(
self
.
object
)
else
:
error
=
"<br /> "
.
join
([
"<strong>
%
s</strong>:
%
s"
%
(
title
(
i
[
0
]),
i
[
1
][
0
])
for
i
in
form
.
errors
.
items
()])
messages
.
error
(
request
,
error
)
return
redirect
(
"
%
s#resources"
%
reverse_lazy
(
"dashboard.views.detail"
,
kwargs
=
{
'pk'
:
self
.
object
.
pk
}))
class
NodeDetailView
(
LoginRequiredMixin
,
SuperuserRequiredMixin
,
DetailView
):
class
NodeDetailView
(
LoginRequiredMixin
,
SuperuserRequiredMixin
,
DetailView
):
template_name
=
"dashboard/node-detail.html"
template_name
=
"dashboard/node-detail.html"
...
...
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