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
df4f36a3
authored
Feb 27, 2014
by
Kálmán Viktor
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
dashboard: rework disk adding
parent
2fc3ff12
Hide whitespace changes
Inline
Side-by-side
Showing
6 changed files
with
125 additions
and
42 deletions
+125
-42
circle/dashboard/forms.py
+61
-15
circle/dashboard/templates/dashboard/template-edit.html
+13
-2
circle/dashboard/templates/dashboard/vm-detail/resources.html
+6
-3
circle/dashboard/urls.py
+4
-1
circle/dashboard/views.py
+37
-21
circle/vm/models/instance.py
+4
-0
No files found.
circle/dashboard/forms.py
View file @
df4f36a3
...
...
@@ -17,7 +17,9 @@ from sizefield.widgets import FileSizeWidget
from
firewall.models
import
Vlan
,
Host
from
storage.models
import
Disk
,
DataStore
from
vm.models
import
InstanceTemplate
,
Lease
,
InterfaceTemplate
,
Node
from
vm.models
import
(
InstanceTemplate
,
Lease
,
InterfaceTemplate
,
Node
,
Instance
)
VLANS
=
Vlan
.
objects
.
all
()
DISKS
=
Disk
.
objects
.
exclude
(
type
=
"qcow2-snap"
)
...
...
@@ -725,27 +727,59 @@ class LeaseForm(forms.ModelForm):
class
DiskAddForm
(
forms
.
Form
):
name
=
forms
.
CharField
()
size
=
forms
.
CharField
(
widget
=
FileSizeWidget
)
size
=
forms
.
CharField
(
widget
=
FileSizeWidget
,
required
=
False
)
url
=
forms
.
CharField
(
required
=
False
)
add_to
=
forms
.
CharField
()
object_pk
=
forms
.
CharField
()
def
__init__
(
self
,
*
args
,
**
kwargs
):
self
.
add_to
=
kwargs
.
pop
(
"add_to"
)
self
.
object_pk
=
kwargs
.
pop
(
"object_pk"
)
super
(
DiskAddForm
,
self
)
.
__init__
(
*
args
,
**
kwargs
)
self
.
initial
[
'add_to'
]
=
self
.
add_to
self
.
initial
[
'object_pk'
]
=
self
.
object_pk
def
clean_size
(
self
):
size_in_bytes
=
self
.
cleaned_data
.
get
(
"size"
)
if
not
size_in_bytes
.
isdigit
():
if
not
size_in_bytes
.
isdigit
()
and
len
(
size_in_bytes
)
>
0
:
raise
forms
.
ValidationError
(
_
(
"Invalid format, you can use "
" GB or MB!"
))
return
size_in_bytes
def
save
(
self
,
vm
,
commit
=
True
):
def
clean
(
self
):
cleaned_data
=
self
.
cleaned_data
size
=
cleaned_data
.
get
(
"size"
)
url
=
cleaned_data
.
get
(
"url"
)
if
not
size
and
not
url
:
msg
=
_
(
"You have to either specify size or URL"
)
self
.
_errors
[
_
(
"Global"
)]
=
self
.
error_class
([
msg
])
return
cleaned_data
def
save
(
self
,
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
)
if
data
[
'size'
]:
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
()
else
:
# TODO
d
=
None
if
self
.
add_to
==
"template"
:
vm_or_temp
=
InstanceTemplate
.
objects
.
get
(
pk
=
self
.
object_pk
)
else
:
vm_or_temp
=
Instance
.
objects
.
get
(
pk
=
self
.
object_pk
)
vm_or_temp
.
disks
.
add
(
d
)
return
d
@property
...
...
@@ -753,11 +787,23 @@ class DiskAddForm(forms.Form):
helper
=
FormHelper
()
helper
.
form_show_labels
=
False
helper
.
layout
=
Layout
(
Field
(
"add_to"
,
type
=
"hidden"
),
Field
(
"object_pk"
,
type
=
"hidden"
),
Field
(
"name"
,
placeholder
=
_
(
"Name"
)),
Field
(
"size"
,
placeholder
=
_
(
"Disk size (for example: 20GB, "
"1500MB)"
)),
Field
(
"url"
,
placeholder
=
_
(
"URL to an ISO image"
)),
AnyTag
(
"div"
,
HTML
(
_
(
"Either specify the size for an empty disk or a URL "
"to an ISO image!"
)
),
css_class
=
"alert alert-info"
,
style
=
"padding: 5px; text-align: justify;"
,
),
)
helper
.
add_input
(
Submit
(
"submit"
,
"Create new disk"
,
helper
.
add_input
(
Submit
(
"submit"
,
_
(
"Add"
)
,
css_class
=
"btn btn-success"
))
return
helper
...
...
circle/dashboard/templates/dashboard/template-edit.html
View file @
df4f36a3
...
...
@@ -64,8 +64,19 @@
</form>
</div>
</div>
</div>
</div>
<div
class=
"panel panel-default"
>
<div
class=
"panel-heading"
>
<h3
class=
"no-margin"
><i
class=
"icon-file"
></i>
{% trans "Create new disk" %}
</h3>
</div>
<div
class=
"panel-body"
>
<form
action=
"{% url "
dashboard
.
views
.
disk-add
"
%}"
method=
"POST"
>
{% crispy disk_add_form %}
</form>
</div>
</div>
</div>
<!-- .col-md-4 -->
</div>
<!-- .row -->
<style>
...
...
circle/dashboard/templates/dashboard/vm-detail/resources.html
View file @
df4f36a3
...
...
@@ -52,9 +52,12 @@
</a>
</div>
</h3>
<div
class=
"row"
id=
"vm-details-disk-add-for-form"
>
</div>
<div
class=
"row"
id=
"vm-details-disk-add-for-form"
></div>
{% if not instance.disks.all %}
{% trans "No disks are added!" %}
{% endif %}
{% 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.id }}) - {{ d.size|filesize }}
...
...
@@ -67,7 +70,7 @@
<div
class=
"col-md-12"
>
<div>
<hr
/>
<form
method=
"POST"
action=
"
"
style=
"max-width: 30
0px;"
>
<form
method=
"POST"
action=
"
{% url "
dashboard
.
views
.
disk-add
"
%}"
style=
"max-width: 35
0px;"
>
{% crispy forms.disk_add_form %}
</form>
<hr
/>
...
...
circle/dashboard/urls.py
View file @
df4f36a3
...
...
@@ -9,7 +9,7 @@ from .views import (
FavouriteView
,
NodeStatus
,
GroupList
,
TemplateDelete
,
LeaseDelete
,
VmGraphView
,
TemplateAclUpdateView
,
GroupDetailView
,
GroupDelete
,
GroupAclUpdateView
,
GroupUserDelete
,
NotificationView
,
NodeGraphView
,
VmMigrateView
,
VmMigrateView
,
DiskAddView
)
urlpatterns
=
patterns
(
...
...
@@ -87,4 +87,7 @@ urlpatterns = patterns(
url
(
r'^notifications/$'
,
NotificationView
.
as_view
(),
name
=
"dashboard.views.notifications"
),
url
(
r'^disk/add$'
,
DiskAddView
.
as_view
(),
name
=
"dashboard.views.disk-add"
),
)
circle/dashboard/views.py
View file @
df4f36a3
...
...
@@ -20,7 +20,7 @@ from django.views.generic import (TemplateView, DetailView, View, DeleteView,
UpdateView
,
CreateView
)
from
django.contrib
import
messages
from
django.utils.translation
import
ugettext
as
_
from
django.template.defaultfilters
import
title
from
django.template.defaultfilters
import
title
as
title_filter
from
django.template.loader
import
render_to_string
from
django.forms.models
import
inlineformset_factory
...
...
@@ -180,7 +180,9 @@ class VmDetailView(CheckedDetailView):
)
.
all
()
context
[
'acl'
]
=
get_vm_acl_data
(
instance
)
context
[
'forms'
]
=
{
'disk_add_form'
:
DiskAddForm
(
prefix
=
"disk"
),
'disk_add_form'
:
DiskAddForm
(
add_to
=
"instance"
,
object_pk
=
self
.
get_object
()
.
pk
,
prefix
=
"disk"
),
}
context
[
'os_type_icon'
]
=
instance
.
os_type
.
replace
(
"unknown"
,
"question"
)
...
...
@@ -199,7 +201,6 @@ class VmDetailView(CheckedDetailView):
'port'
:
self
.
__add_port
,
'new_network_vlan'
:
self
.
__new_network
,
'save_as'
:
self
.
__save_as
,
'disk-name'
:
self
.
__add_disk
,
'shut_down'
:
self
.
__shut_down
,
'sleep'
:
self
.
__sleep
,
'wake_up'
:
self
.
__wake_up
,
...
...
@@ -374,24 +375,6 @@ class VmDetailView(CheckedDetailView):
return
redirect
(
reverse_lazy
(
"dashboard.views.template-detail"
,
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
}))
def
__shut_down
(
self
,
request
):
self
.
object
=
self
.
get_object
()
if
not
self
.
object
.
has_level
(
request
.
user
,
'owner'
):
...
...
@@ -749,6 +732,11 @@ class TemplateDetail(LoginRequiredMixin, SuccessMessageMixin, UpdateView):
def
get_context_data
(
self
,
**
kwargs
):
context
=
super
(
TemplateDetail
,
self
)
.
get_context_data
(
**
kwargs
)
context
[
'acl'
]
=
get_vm_acl_data
(
self
.
get_object
())
context
[
'disk_add_form'
]
=
DiskAddForm
(
add_to
=
"template"
,
object_pk
=
self
.
get_object
()
.
pk
,
prefix
=
"disk"
,
)
return
context
def
get_success_url
(
self
):
...
...
@@ -1718,3 +1706,31 @@ class VmMigrateView(SuperuserRequiredMixin, TemplateView):
messages
.
error
(
self
.
request
,
_
(
"You didn't select a node!"
))
return
redirect
(
"
%
s#activity"
%
vm
.
get_absolute_url
())
class
DiskAddView
(
SuperuserRequiredMixin
,
TemplateView
):
def
post
(
self
,
*
args
,
**
kwargs
):
add_to
=
self
.
request
.
POST
.
get
(
"disk-add_to"
)
object_pk
=
self
.
request
.
POST
.
get
(
"disk-object_pk"
)
form
=
DiskAddForm
(
self
.
request
.
POST
,
add_to
=
add_to
,
object_pk
=
object_pk
,
prefix
=
"disk"
)
if
form
.
is_valid
():
messages
.
success
(
self
.
request
,
_
(
"Disk successfully added!"
))
form
.
save
()
else
:
error
=
"<br /> "
.
join
([
"<strong>
%
s</strong>:
%
s"
%
(
title_filter
(
i
[
0
]),
i
[
1
][
0
])
for
i
in
form
.
errors
.
items
()])
messages
.
error
(
self
.
request
,
error
)
if
add_to
==
"template"
:
r
=
InstanceTemplate
.
objects
.
get
(
pk
=
object_pk
)
.
get_absolute_url
()
else
:
r
=
Instance
.
objects
.
get
(
pk
=
object_pk
)
.
get_absolute_url
()
r
=
"
%
s#resources"
%
r
return
redirect
(
r
)
circle/vm/models/instance.py
View file @
df4f36a3
...
...
@@ -152,6 +152,10 @@ class InstanceTemplate(AclBase, VirtualMachineDescModel, TimeStampedModel):
if
is_new
:
self
.
set_level
(
self
.
owner
,
'owner'
)
@permalink
def
get_absolute_url
(
self
):
return
(
'dashboard.views.template-detail'
,
None
,
{
'pk'
:
self
.
pk
})
class
Instance
(
AclBase
,
VirtualMachineDescModel
,
TimeStampedModel
):
...
...
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