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
e0ab1b77
authored
Dec 09, 2013
by
Kálmán Viktor
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
dashboard: vm create with django forms
parent
ab541167
Show whitespace changes
Inline
Side-by-side
Showing
5 changed files
with
369 additions
and
152 deletions
+369
-152
circle/dashboard/forms.py
+328
-0
circle/dashboard/static/dashboard/dashboard.css
+19
-0
circle/dashboard/templates/crispy_forms/anytag.html
+4
-0
circle/dashboard/templates/dashboard/vm-create.html
+4
-144
circle/dashboard/views.py
+14
-8
No files found.
circle/dashboard/forms.py
0 → 100644
View file @
e0ab1b77
from
django
import
forms
from
vm.models
import
InstanceTemplate
from
storage.models
import
Disk
from
firewall.models
import
Vlan
# from django.core.urlresolvers import reverse_lazy
from
crispy_forms.helper
import
FormHelper
from
crispy_forms.layout
import
(
Layout
,
Div
,
BaseInput
,
# Submit
Field
,
HTML
)
from
crispy_forms.layout
import
TEMPLATE_PACK
from
crispy_forms.utils
import
render_field
from
django.template
import
Context
from
django.template.loader
import
render_to_string
from
django.utils.translation
import
ugettext
as
_
# from crispy_forms.bootstrap import FormActions
VLANS
=
Vlan
.
objects
.
all
()
class
VmCreateForm
(
forms
.
Form
):
template
=
forms
.
ModelChoiceField
(
queryset
=
InstanceTemplate
.
objects
.
all
(),
empty_label
=
"Select pls"
)
cpu_priority
=
forms
.
IntegerField
()
cpu_count
=
forms
.
IntegerField
()
ram_size
=
forms
.
IntegerField
()
disks
=
forms
.
ModelMultipleChoiceField
(
queryset
=
Disk
.
objects
.
exclude
(
type
=
"qcow2-snap"
),
)
managed_networks
=
forms
.
ModelMultipleChoiceField
(
queryset
=
VLANS
)
unmanaged_networks
=
forms
.
ModelMultipleChoiceField
(
queryset
=
VLANS
)
def
__init__
(
self
,
*
args
,
**
kwargs
):
super
(
VmCreateForm
,
self
)
.
__init__
(
*
args
,
**
kwargs
)
self
.
helper
=
FormHelper
(
self
)
self
.
helper
.
form_show_labels
=
False
self
.
helper
.
layout
=
Layout
(
Div
(
Div
(
Field
(
'template'
,
id
=
"vm-create-template-select"
,
css_class
=
"select form-control"
),
css_class
=
"col-sm-10"
,
),
css_class
=
"row"
,
),
Div
(
# buttons
Div
(
AnyTag
(
"a"
,
HTML
(
"
%
s "
%
_
(
"Advanced"
)),
AnyTag
(
"i"
,
css_class
=
"vm-create-advanced-icon icon-caret-down"
),
css_class
=
"btn btn-info vm-create-advanced-btn"
,
),
css_class
=
"col-sm-5"
,
),
Div
(
AnyTag
(
# tip: don't try to use Button class
"button"
,
AnyTag
(
"i"
,
css_class
=
"icon-play"
),
HTML
(
" Start"
),
css_id
=
"vm-create-submit"
,
css_class
=
"btn btn-success"
,
),
css_class
=
"col-sm-5 text-right"
,
),
css_class
=
"row"
,
),
Div
(
# vm-create-advanced
Div
(
Div
(
AnyTag
(
'h2'
,
HTML
(
_
(
"Resources"
)),
),
css_class
=
"col-sm-12"
,
),
css_class
=
"row"
,
),
Div
(
# cpu priority
Div
(
HTML
(
'<label for="vm-cpu-priority-slider">'
'<i class="icon-trophy"></i> CPU priority'
'</label>'
),
css_class
=
"col-sm-3"
),
Div
(
Field
(
'cpu_priority'
,
id
=
"vm-cpu-priority-slider"
,
css_class
=
"vm-slider"
,
data_slider_min
=
"0"
,
data_slider_max
=
"100"
,
data_slider_step
=
"1"
,
data_slider_value
=
"20"
,
data_slider_handle
=
"square"
,
data_slider_tooltip
=
"hide"
),
css_class
=
"col-sm-9"
),
css_class
=
"row"
),
Div
(
# cpu count
Div
(
HTML
(
'<label for="cpu-count-slider">'
'<i class="icon-cogs"></i> CPU count'
'</label>'
),
css_class
=
"col-sm-3"
),
Div
(
Field
(
'cpu_count'
,
id
=
"vm-cpu-count-slider"
,
css_class
=
"vm-slider"
,
data_slider_min
=
"1"
,
data_slider_max
=
"8"
,
data_slider_step
=
"1"
,
data_slider_value
=
"2"
,
data_slider_handle
=
"square"
,
data_slider_tooltip
=
"hide"
),
css_class
=
"col-sm-9"
),
css_class
=
"row"
),
Div
(
# ram size
Div
(
HTML
(
'<label for="ram-slider">'
'<i class="icon-ticket"></i> RAM amount'
'</label>'
),
css_class
=
"col-sm-3"
),
Div
(
Field
(
'ram_size'
,
id
=
"vm-ram-size-slider"
,
css_class
=
"vm-slider"
,
data_slider_min
=
"128"
,
data_slider_max
=
"4096"
,
data_slider_step
=
"128"
,
data_slider_value
=
"512"
,
data_slider_handle
=
"square"
,
data_slider_tooltip
=
"hide"
),
css_class
=
"col-sm-9"
),
css_class
=
"row"
),
Div
(
# disks
Div
(
AnyTag
(
"h2"
,
HTML
(
"Disks"
)
),
css_class
=
"col-sm-4"
,
),
Div
(
Div
(
Field
(
"disks"
,
css_class
=
"form-control"
,
id
=
"vm-create-disk-add-form"
),
css_class
=
"js-hidden"
,
style
=
"padding-top: 15px; max-width: 450px;"
,
),
Div
(
AnyTag
(
"h3"
,
HTML
(
_
(
"No disks are added!"
)),
css_id
=
"vm-create-disk-list"
,
),
AnyTag
(
"h3"
,
Div
(
AnyTag
(
"select"
,
css_class
=
"form-control"
,
css_id
=
"vm-create-disk-add-select"
,
),
Div
(
AnyTag
(
"a"
,
AnyTag
(
"i"
,
css_class
=
"icon-plus-sign"
,
),
href
=
"#"
,
css_id
=
"vm-create-disk-add-button"
,
css_class
=
"btn btn-success"
,
),
css_class
=
"input-group-btn"
),
css_class
=
"input-group"
,
style
=
"max-width: 330px;"
,
),
css_id
=
"vm-create-disk-add"
,
),
css_class
=
"no-js-hidden"
,
),
css_class
=
"col-sm-8"
,
style
=
"padding-top: 3px;"
,
),
css_class
=
"row"
,
),
# end of disks
Div
(
# network
Div
(
AnyTag
(
"h2"
,
HTML
(
_
(
"Network"
)),
),
css_class
=
"col-sm-4"
,
),
Div
(
Div
(
# js-hidden
AnyTag
(
"h4"
,
HTML
(
_
(
"Managed networks"
)),
),
Field
(
"managed_networks"
,
css_class
=
"form-control"
,
id
=
"vm-create-network-add-managed"
,
),
AnyTag
(
"h4"
,
HTML
(
_
(
"Unmanaged networks"
)),
),
Field
(
"unmanaged_networks"
,
css_class
=
"form-control"
,
id
=
"vm-create-network-add-unmanaged"
,
),
css_class
=
"js-hidden"
,
style
=
"padding-top: 15px; max-width: 450px;"
,
),
Div
(
# no-js-hidden
AnyTag
(
"h3"
,
HTML
(
_
(
"Not added to any network!"
)),
css_id
=
"vm-create-network-list"
,
),
AnyTag
(
"h3"
,
Div
(
AnyTag
(
"select"
,
css_class
=
"form-control"
,
css_id
=
"vm-create-network-add-select"
,
),
AnyTag
(
"span"
,
WorkingBaseInput
(
""
,
""
,
css_id
=
(
"vm-create-network-add"
"checkbox-managed"
),
input_type
=
"checkbox"
,
title
=
""
,
data_original_title
=
(
_
(
"Managed network?"
)
),
checked
=
"checked"
,
),
css_class
=
"input-group-addon"
,
),
Div
(
AnyTag
(
"a"
,
AnyTag
(
"i"
,
css_class
=
"icon-plus-sign"
,
),
css_id
=
(
"vm-create-network-add"
"-button"
),
css_class
=
"btn btn-success"
,
),
css_class
=
"input-group-btn"
,
),
css_class
=
"input-group"
,
style
=
"max-width: 330px;"
,
),
css_class
=
"vm-create-network-add"
),
css_class
=
"no-js-hidden"
,
),
css_class
=
"col-sm-8"
,
style
=
"padding-top: 3px;"
,
),
css_class
=
"row"
),
# end of network
css_class
=
"vm-create-advanced"
),
)
class
LinkButton
(
BaseInput
):
"""
Used to create a link button descriptor for the {
%
crispy
%
} template tag::
back = LinkButton('back', 'Back', reverse_lazy('index'))
.. note:: The first argument is also slugified and turned into the id for
the submit button.
"""
template
=
"bootstrap/layout/linkbutton.html"
field_classes
=
'btn btn-default'
def
__init__
(
self
,
name
,
text
,
url
,
*
args
,
**
kwargs
):
self
.
href
=
url
super
(
LinkButton
,
self
)
.
__init__
(
name
,
text
,
*
args
,
**
kwargs
)
class
AnyTag
(
Div
):
template
=
"crispy_forms/anytag.html"
def
__init__
(
self
,
tag
,
*
fields
,
**
kwargs
):
self
.
tag
=
tag
super
(
AnyTag
,
self
)
.
__init__
(
*
fields
,
**
kwargs
)
def
render
(
self
,
form
,
form_style
,
context
,
template_pack
=
TEMPLATE_PACK
):
fields
=
''
for
field
in
self
.
fields
:
fields
+=
render_field
(
field
,
form
,
form_style
,
context
,
template_pack
=
template_pack
)
return
render_to_string
(
self
.
template
,
Context
({
'tag'
:
self
,
'fields'
:
fields
}))
class
WorkingBaseInput
(
BaseInput
):
def
__init__
(
self
,
name
,
value
,
input_type
=
"text"
,
**
kwargs
):
self
.
input_type
=
input_type
self
.
field_classes
=
""
# we need this for some reason
super
(
WorkingBaseInput
,
self
)
.
__init__
(
name
,
value
,
**
kwargs
)
circle/dashboard/static/dashboard/dashboard.css
View file @
e0ab1b77
...
@@ -208,3 +208,22 @@ body {
...
@@ -208,3 +208,22 @@ body {
.vm-details-network-port-add
.input-group-addon
,
.vm-details-network-port-add
.input-group-btn
{
.vm-details-network-port-add
.input-group-addon
,
.vm-details-network-port-add
.input-group-btn
{
width
:
inherit
;
width
:
inherit
;
}
}
/* vm-create */
a
.hover-black
{
color
:
white
;
}
.hover-black
:hover
{
color
:
black
/*#d9534f*/
;
text-decoration
:
none
;
}
.no-js-hidden
{
display
:
none
;
}
#vm-create-network-addcheckbox-managed
{
-webkit-transform
:
scale
(
1.3
,
1.3
);
margin-top
:
4px
;
}
/* --- */
circle/dashboard/templates/crispy_forms/anytag.html
0 → 100644
View file @
e0ab1b77
<
{{
tag
.
tag
}}
{%
if
tag
.
css_id
%}
id=
"{{ tag.css_id }}"
{%
endif
%}
{%
if
tag
.
css_class
%}
class=
"{{ tag.css_class }}"
{%
endif
%}
{{
tag
.
flat_attrs
|
safe
}}
>
{{ fields|safe }}
</
{{
tag
.tag
}}
>
circle/dashboard/templates/dashboard/vm-create.html
View file @
e0ab1b77
{% load crispy_forms_tags %}
<style>
<style>
.row
{
.row
{
margin-bottom
:
15px
;
margin-bottom
:
15px
;
}
}
</style>
</style>
<form
method=
"POST"
action=
"/dashboard/vm/create/"
>
{% csrf_token %}
<div
class=
"row"
>
<div
class=
"col-sm-10"
>
<select
class=
"select form-control"
id=
"vm-create-template-select"
name=
"template-pk"
>
<option
value=
"-1"
>
Choose a VM template
</option>
{% for template in templates %}
<option
value=
"{{ template.pk }}"
>
{{ template.name}}
</option>
{% endfor %}
</select>
</div>
</div>
<div
class=
"row"
>
<div
class=
"col-sm-5"
>
<a
class=
"btn btn-info vm-create-advanced-btn"
>
Advanced
<i
class=
"vm-create-advanced-icon icon-caret-down"
></i></a>
</div>
<div
class=
"col-sm-5 text-right"
>
<button
id=
"vm-create-submit"
type=
"submit"
class=
"btn btn-success "
><i
class=
"icon-play"
></i>
Start
</button>
</div>
</div>
<div
class=
"vm-create-advanced"
>
<div
class=
"row"
>
<div
class=
"col-sm-12"
>
<h2>
Resources
</h2>
</div>
<p
class=
"row"
>
<div
class=
"col-sm-3"
>
<label
for=
"vm-cpu-priority-slider"
><i
class=
"icon-trophy"
></i>
CPU priority
</label>
</div>
<div
class=
"col-sm-9"
>
<input
name=
"cpu-priority"
type=
"text"
id=
"vm-cpu-priority-slider"
class=
"vm-slider"
value=
"20"
data-slider-min=
"0"
data-slider-max=
"100"
data-slider-step=
"1"
data-slider-value=
"20"
data-slider-orientation=
"horizontal"
data-slider-handle=
"square"
data-slider-tooltip=
"hide"
/>
</div>
</p>
<p
class=
"row"
>
<div
class=
"col-sm-3"
>
<label
for=
"cpu-count-slider"
><i
class=
"icon-cogs"
></i>
CPU count
</label>
</div>
<div
class=
"col-sm-9"
>
<input
name=
"cpu-count"
type=
"text"
id=
"vm-cpu-count-slider"
class=
"vm-slider"
value=
"2"
data-slider-min=
"0"
data-slider-max=
"8"
data-slider-step=
"1"
data-slider-value=
"2"
data-slider-orientation=
"horizontal"
data-slider-handle=
"square"
data-slider-tooltip=
"hide"
/>
</div>
</p>
<p
class=
"row"
>
<form
method=
"POST"
action=
"/dashboard/vm/create/"
>
<div
class=
"col-sm-3"
>
{% csrf_token %}
<label
for=
"ram-slider"
><i
class=
"icon-ticket"
></i>
RAM amount
</label>
{% crispy vm_create_form %}
</div>
<div
class=
"col-sm-9"
>
<input
name=
"ram-size"
type=
"text"
id=
"vm-ram-size-slider"
class=
"vm-slider"
value=
"512"
data-slider-min=
"128"
data-slider-max=
"4096"
data-slider-step=
"128"
data-slider-value=
"512"
data-slider-orientation=
"horizontal"
data-slider-handle=
"square"
data-slider-tooltip=
"hide"
/>
MiB
</div>
</p>
</div>
<!-- disk -->
<div
class=
"row"
>
<div
class=
"col-sm-4"
>
<h2>
Disks
</h2>
</div>
<div
class=
"col-sm-8"
style=
"padding-top: 3px;"
>
<div
class=
"js-hidden"
style=
"padding-top: 15px; max-width: 450px;"
>
<select
class=
"form-control"
id=
"vm-create-disk-add-form"
multiple
name=
"disks"
>
{% for d in disks %}
<option
value=
"{{ d.pk }}"
>
{{ d.name }}
</option>
{% endfor %}
</select>
</div>
<div
class=
"no-js-hidden"
>
<h3
id=
"vm-create-disk-list"
>
No disks are added!
</h3>
<h3
id=
"vm-create-disk-add"
>
<div
class=
"input-group"
style=
"max-width: 330px;"
>
<select
class=
"form-control"
id=
"vm-create-disk-add-select"
>
<!-- options should be copied via js from above -->
</select>
<div
class=
"input-group-btn"
>
<!--<input type="submit" value="Add to network" class="btn btn-success"/>-->
<a
href=
"#"
id=
"vm-create-disk-add-button"
class=
"btn btn-success"
><i
class=
"icon-plus-sign"
></i></a>
</div>
</div>
</h3>
</div>
</div>
</div>
<!-- network -->
<div
class=
"row"
>
<div
class=
"col-sm-4"
>
<h2>
Network
</h2>
</div>
<style>
/* temporary inline css for dev */
a
.hover-black
{
color
:
white
;
}
.hover-black
:hover
{
color
:
black
/*#d9534f*/
;
text-decoration
:
none
;
}
.no-js-hidden
{
display
:
none
;
}
</style>
<div
class=
"col-sm-8"
style=
"padding-top: 3px;"
>
<div
class=
"js-hidden"
style=
"padding-top: 15px; max-width: 450px;"
>
<h4>
Managed networks
</h4>
<select
class=
"form-control"
id=
"vm-create-network-add-managed"
multiple
name=
"managed-vlans"
>
{% for v in vlans %}
<option
value=
"{{ v.pk }}"
>
{{ v.name }}
</option>
{% endfor %}
</select>
<h4>
Unmanaged networks
</h4>
<select
class=
"form-control"
id=
"vm-create-network-add-unmanaged"
multiple
name=
"unmanaged-vlans"
>
{% for v in vlans %}
<option
value=
"{{ v.pk }}"
>
{{ v.name }}
</option>
{% endfor %}
</select>
</div>
<div
class=
"no-js-hidden"
>
<h3
id=
"vm-create-network-list"
>
Not added to any network!
</h3>
<h3
id=
"vm-create-network-add"
>
<div
class=
"input-group"
style=
"max-width: 330px;"
>
<select
class=
"form-control"
id=
"vm-create-network-add-select"
>
<!-- options should be copied via js from above -->
</select>
<span
class=
"input-group-addon"
>
<input
id=
"vm-create-network-add-checkbox-managed"
type=
"checkbox"
title
data-original-title=
"Managed network?"
style=
"-webkit-transform: scale(1.4, 1.4); margin-top: 4px;"
checked
/>
</span>
<div
class=
"input-group-btn"
>
<!--<input type="submit" value="Add to network" class="btn btn-success"/>-->
<a
href=
"#"
id=
"vm-create-network-add-button"
class=
"btn btn-success"
><i
class=
"icon-plus-sign"
></i></a>
</div>
</div>
</h3>
</div>
</div>
</div>
</div>
</form>
</form>
circle/dashboard/views.py
View file @
e0ab1b77
...
@@ -21,6 +21,7 @@ from django.utils.translation import ugettext as _
...
@@ -21,6 +21,7 @@ from django.utils.translation import ugettext as _
from
django_tables2
import
SingleTableView
from
django_tables2
import
SingleTableView
from
braces.views
import
LoginRequiredMixin
from
braces.views
import
LoginRequiredMixin
from
.forms
import
VmCreateForm
from
.tables
import
(
VmListTable
,
NodeListTable
)
from
.tables
import
(
VmListTable
,
NodeListTable
)
from
vm.models
import
(
Instance
,
InstanceTemplate
,
InterfaceTemplate
,
from
vm.models
import
(
Instance
,
InstanceTemplate
,
InterfaceTemplate
,
InstanceActivity
,
Node
,
instance_activity
)
InstanceActivity
,
Node
,
instance_activity
)
...
@@ -362,7 +363,8 @@ class VmCreate(TemplateView):
...
@@ -362,7 +363,8 @@ class VmCreate(TemplateView):
context
.
update
({
context
.
update
({
'templates'
:
InstanceTemplate
.
objects
.
all
(),
'templates'
:
InstanceTemplate
.
objects
.
all
(),
'vlans'
:
Vlan
.
objects
.
all
(),
'vlans'
:
Vlan
.
objects
.
all
(),
'disks'
:
Disk
.
objects
.
exclude
(
type
=
"qcow2-snap"
)
'disks'
:
Disk
.
objects
.
exclude
(
type
=
"qcow2-snap"
),
'vm_create_form'
:
VmCreateForm
,
})
})
return
context
return
context
...
@@ -376,27 +378,31 @@ class VmCreate(TemplateView):
...
@@ -376,27 +378,31 @@ class VmCreate(TemplateView):
resp
=
{}
resp
=
{}
try
:
try
:
pk
=
request
.
POST
.
get
(
'template
-pk
'
)
pk
=
request
.
POST
.
get
(
'template'
)
template
=
InstanceTemplate
.
objects
.
get
(
template
=
InstanceTemplate
.
objects
.
get
(
pk
=
pk
)
pk
=
pk
)
except
ValueError
:
resp
[
'error'
]
=
True
resp
[
'message'
]
=
_
(
"Select a VM from the list!"
)
except
InstanceTemplate
.
DoesNotExist
as
e
:
except
InstanceTemplate
.
DoesNotExist
as
e
:
logger
.
warning
(
'VmCreate.post:
%
s (pk=
%
d, user=
%
s)'
,
logger
.
warning
(
'VmCreate.post:
%
s (pk=
%
d, user=
%
s)'
,
unicode
(
e
),
unicode
(
request
.
user
),
pk
)
unicode
(
e
),
pk
,
unicode
(
request
.
user
)
)
resp
[
'error'
]
=
True
resp
[
'error'
]
=
True
else
:
else
:
if
request
.
user
.
has_perm
(
'vm.set_resources'
):
if
request
.
user
.
has_perm
(
'vm.set_resources'
):
ikwargs
=
{
ikwargs
=
{
'num_cores'
:
int
(
request
.
POST
.
get
(
'cpu
-
count'
)),
'num_cores'
:
int
(
request
.
POST
.
get
(
'cpu
_
count'
)),
'ram_size'
:
int
(
request
.
POST
.
get
(
'ram
-
size'
)),
'ram_size'
:
int
(
request
.
POST
.
get
(
'ram
_
size'
)),
'priority'
:
int
(
request
.
POST
.
get
(
'cpu
-
priority'
)),
'priority'
:
int
(
request
.
POST
.
get
(
'cpu
_
priority'
)),
}
}
try
:
try
:
networks
=
[
InterfaceTemplate
(
vlan
=
Vlan
.
objects
.
get
(
pk
=
l
),
networks
=
[
InterfaceTemplate
(
vlan
=
Vlan
.
objects
.
get
(
pk
=
l
),
managed
=
True
)
managed
=
True
)
for
l
in
request
.
POST
.
getlist
(
'managed-vlans'
)
for
l
in
request
.
POST
.
getlist
(
'managed_networks'
)
]
]
unmanaged
=
request
.
POST
.
getlist
(
'unmanaged
-vlan
s'
)
unmanaged
=
request
.
POST
.
getlist
(
'unmanaged
_network
s'
)
networks
.
extend
([
networks
.
extend
([
InterfaceTemplate
(
vlan
=
Vlan
.
objects
.
get
(
pk
=
l
),
InterfaceTemplate
(
vlan
=
Vlan
.
objects
.
get
(
pk
=
l
),
managed
=
False
)
managed
=
False
)
...
...
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