Skip to content
Toggle navigation
P
Projects
G
Groups
S
Snippets
Help
CIRCLE
/
cloud
This project
Loading...
Sign in
Toggle navigation
Go to a project
Project
Repository
Issues
94
Merge Requests
10
Pipelines
Wiki
Snippets
Members
Activity
Graph
Charts
Create a new issue
Jobs
Commits
Issue Boards
Files
Commits
Branches
Tags
Contributors
Graph
Compare
Charts
A prog2-höz tartozó friss repo anyagok itt elérhetőek:
https://git.iit.bme.hu/
Commit
d3fc9a1f
authored
Oct 16, 2014
by
Csók Tamás
Browse files
Options
Browse Files
Download
Plain Diff
Merge remote-tracking branch 'origin/master' into issue-218
parents
94ae9469
d4c7fdc3
Hide whitespace changes
Inline
Side-by-side
Showing
5 changed files
with
98 additions
and
83 deletions
+98
-83
circle/common/models.py
+22
-10
circle/dashboard/forms.py
+50
-64
circle/dashboard/templates/dashboard/_disk-list-element.html
+1
-1
circle/dashboard/views/vm.py
+17
-4
circle/vm/operations.py
+8
-4
No files found.
circle/common/models.py
View file @
d3fc9a1f
...
...
@@ -32,6 +32,7 @@ from django.core.serializers.json import DjangoJSONEncoder
from
django.db.models
import
(
CharField
,
DateTimeField
,
ForeignKey
,
NullBooleanField
)
from
django.template
import
defaultfilters
from
django.utils
import
timezone
from
django.utils.encoding
import
force_text
from
django.utils.functional
import
Promise
...
...
@@ -428,6 +429,14 @@ class HumanReadableObject(object):
admin_text_template
=
admin_text_template
.
_proxy____args
[
0
]
self
.
user_text_template
=
user_text_template
self
.
admin_text_template
=
admin_text_template
for
k
,
v
in
params
.
iteritems
():
try
:
v
=
timezone
.
datetime
.
strptime
(
v
,
"
%
Y-
%
m-
%
dT
%
H:
%
M:
%
S.
%
fZ"
)
.
replace
(
tzinfo
=
timezone
.
UTC
())
except
(
ValueError
,
TypeError
):
# Mock raises TypeError
pass
if
isinstance
(
v
,
timezone
.
datetime
):
params
[
k
]
=
defaultfilters
.
date
(
v
,
"DATETIME_FORMAT"
)
self
.
params
=
params
@classmethod
...
...
@@ -444,24 +453,27 @@ class HumanReadableObject(object):
def
from_dict
(
cls
,
d
):
return
None
if
d
is
None
else
cls
(
**
d
)
def
get_admin_text
(
self
):
if
self
.
admin_text_template
==
""
:
def
_get_parsed_text
(
self
,
key
):
value
=
getattr
(
self
,
key
)
if
value
==
""
:
return
""
try
:
return
_
(
self
.
admin_text_template
)
%
self
.
params
return
_
(
value
)
%
self
.
params
except
KeyError
:
logger
.
exception
(
"Can't render
%
s '
%
s'
%% %
s"
,
key
,
value
,
unicode
(
self
.
params
))
raise
def
get_admin_text
(
self
):
try
:
return
self
.
_get_parsed_text
(
"admin_text_template"
)
except
KeyError
:
logger
.
exception
(
"Can't render admin_text_template '
%
s'
%% %
s"
,
self
.
admin_text_template
,
unicode
(
self
.
params
))
return
self
.
get_user_text
()
def
get_user_text
(
self
):
if
self
.
user_text_template
==
""
:
return
""
try
:
return
_
(
self
.
user_text_template
)
%
self
.
params
return
self
.
_get_parsed_text
(
"user_text_template"
)
except
KeyError
:
logger
.
exception
(
"Can't render user_text_template '
%
s'
%% %
s"
,
self
.
user_text_template
,
unicode
(
self
.
params
))
return
self
.
user_text_template
def
get_text
(
self
,
user
):
...
...
circle/dashboard/forms.py
View file @
d3fc9a1f
...
...
@@ -71,9 +71,7 @@ priority_choices = (
)
class
VmSaveForm
(
forms
.
Form
):
name
=
forms
.
CharField
(
max_length
=
100
,
label
=
_
(
'Name'
),
help_text
=
_
(
'Human readable name of template.'
))
class
NoFormTagMixin
(
object
):
@property
def
helper
(
self
):
...
...
@@ -81,6 +79,15 @@ class VmSaveForm(forms.Form):
helper
.
form_tag
=
False
return
helper
class
OperationForm
(
NoFormTagMixin
,
forms
.
Form
):
pass
class
VmSaveForm
(
OperationForm
):
name
=
forms
.
CharField
(
max_length
=
100
,
label
=
_
(
'Name'
),
help_text
=
_
(
'Human readable name of template.'
))
def
__init__
(
self
,
*
args
,
**
kwargs
):
default
=
kwargs
.
pop
(
'default'
,
None
)
super
(
VmSaveForm
,
self
)
.
__init__
(
*
args
,
**
kwargs
)
...
...
@@ -193,7 +200,7 @@ class VmCustomizeForm(forms.Form):
del
self
.
cleaned_data
[
name
]
class
GroupCreateForm
(
forms
.
ModelForm
):
class
GroupCreateForm
(
NoFormTagMixin
,
forms
.
ModelForm
):
description
=
forms
.
CharField
(
label
=
_
(
"Description"
),
required
=
False
,
widget
=
forms
.
Textarea
(
attrs
=
{
'rows'
:
3
}))
...
...
@@ -232,9 +239,8 @@ class GroupCreateForm(forms.ModelForm):
@property
def
helper
(
self
):
helper
=
FormHelper
(
self
)
helper
=
super
(
GroupCreateForm
,
self
)
.
helper
helper
.
add_input
(
Submit
(
"submit"
,
_
(
"Create"
)))
helper
.
form_tag
=
False
return
helper
class
Meta
:
...
...
@@ -242,7 +248,7 @@ class GroupCreateForm(forms.ModelForm):
fields
=
(
'name'
,
)
class
GroupProfileUpdateForm
(
forms
.
ModelForm
):
class
GroupProfileUpdateForm
(
NoFormTagMixin
,
forms
.
ModelForm
):
def
__init__
(
self
,
*
args
,
**
kwargs
):
new_groups
=
kwargs
.
pop
(
'new_groups'
,
None
)
...
...
@@ -261,9 +267,8 @@ class GroupProfileUpdateForm(forms.ModelForm):
@property
def
helper
(
self
):
helper
=
FormHelper
(
self
)
helper
=
super
(
GroupProfileUpdateForm
,
self
)
.
helper
helper
.
add_input
(
Submit
(
"submit"
,
_
(
"Save"
)))
helper
.
form_tag
=
False
return
helper
def
save
(
self
,
commit
=
True
):
...
...
@@ -278,17 +283,16 @@ class GroupProfileUpdateForm(forms.ModelForm):
fields
=
(
'description'
,
'org_id'
)
class
HostForm
(
forms
.
ModelForm
):
class
HostForm
(
NoFormTagMixin
,
forms
.
ModelForm
):
def
setowner
(
self
,
user
):
self
.
instance
.
owner
=
user
def
__init__
(
self
,
*
args
,
**
kwargs
):
super
(
HostForm
,
self
)
.
__init__
(
*
args
,
**
kwargs
)
self
.
helper
=
FormHelper
(
self
)
self
.
helper
.
form_show_labels
=
False
self
.
helper
.
form_tag
=
False
self
.
helper
.
layout
=
Layout
(
@property
def
helper
(
self
):
helper
=
super
(
HostForm
,
self
)
.
helper
helper
.
form_show_labels
=
False
helper
.
layout
=
Layout
(
Div
(
Div
(
# host
Div
(
...
...
@@ -345,6 +349,7 @@ class HostForm(forms.ModelForm):
),
),
)
return
helper
class
Meta
:
model
=
Host
...
...
@@ -725,7 +730,7 @@ class LeaseForm(forms.ModelForm):
model
=
Lease
class
VmRenewForm
(
forms
.
Form
):
class
VmRenewForm
(
Operation
Form
):
force
=
forms
.
BooleanField
(
required
=
False
,
label
=
_
(
"Set expiration times even if they are shorter than "
...
...
@@ -745,16 +750,15 @@ class VmRenewForm(forms.Form):
self
.
fields
[
'lease'
]
.
widget
=
HiddenInput
()
self
.
fields
[
'save'
]
.
widget
=
HiddenInput
()
@property
def
helper
(
self
):
helper
=
FormHelper
(
self
)
helper
.
form_tag
=
False
return
helper
class
VmMigrateForm
(
forms
.
Form
):
live_migration
=
forms
.
BooleanField
(
required
=
False
,
initial
=
True
,
label
=
_
(
"live migration"
))
required
=
False
,
initial
=
True
,
label
=
_
(
"Live migration"
),
help_text
=
_
(
"Live migration is a way of moving virtual machines between "
"hosts with a service interruption of at most some seconds. "
"Please note that it can take very long and cause "
"much network traffic in case of busy machines."
))
def
__init__
(
self
,
*
args
,
**
kwargs
):
choices
=
kwargs
.
pop
(
'choices'
)
...
...
@@ -766,7 +770,7 @@ class VmMigrateForm(forms.Form):
widget
=
forms
.
RadioSelect
(),
label
=
_
(
"Node"
)))
class
VmStateChangeForm
(
forms
.
Form
):
class
VmStateChangeForm
(
Operation
Form
):
interrupt
=
forms
.
BooleanField
(
required
=
False
,
label
=
_
(
"Forcibly interrupt all running activities."
),
...
...
@@ -785,25 +789,13 @@ class VmStateChangeForm(forms.Form):
self
.
fields
[
'interrupt'
]
.
widget
=
HiddenInput
()
self
.
fields
[
'new_state'
]
.
initial
=
status
@property
def
helper
(
self
):
helper
=
FormHelper
(
self
)
helper
.
form_tag
=
False
return
helper
class
RedeployForm
(
forms
.
Form
):
class
RedeployForm
(
Operation
Form
):
with_emergency_change_state
=
forms
.
BooleanField
(
required
=
False
,
initial
=
True
,
label
=
_
(
"use emergency state change"
))
@property
def
helper
(
self
):
helper
=
FormHelper
(
self
)
helper
.
form_tag
=
False
return
helper
class
VmCreateDiskForm
(
forms
.
Form
):
class
VmCreateDiskForm
(
Operation
Form
):
name
=
forms
.
CharField
(
max_length
=
100
,
label
=
_
(
"Name"
))
size
=
forms
.
CharField
(
widget
=
FileSizeWidget
,
initial
=
(
10
<<
30
),
label
=
_
(
'Size'
),
...
...
@@ -823,14 +815,8 @@ class VmCreateDiskForm(forms.Form):
" GB or MB!"
))
return
size_in_bytes
@property
def
helper
(
self
):
helper
=
FormHelper
(
self
)
helper
.
form_tag
=
False
return
helper
class
VmDiskResizeForm
(
forms
.
Form
):
class
VmDiskResizeForm
(
Operation
Form
):
size
=
forms
.
CharField
(
widget
=
FileSizeWidget
,
initial
=
(
10
<<
30
),
label
=
_
(
'Size'
),
help_text
=
_
(
'Size to resize the disk in bytes or with units '
...
...
@@ -863,8 +849,7 @@ class VmDiskResizeForm(forms.Form):
@property
def
helper
(
self
):
helper
=
FormHelper
(
self
)
helper
.
form_tag
=
False
helper
=
super
(
VmDiskResizeForm
,
self
)
.
helper
if
self
.
disk
:
helper
.
layout
=
Layout
(
HTML
(
_
(
"<label>Disk:</label>
%
s"
)
%
escape
(
self
.
disk
)),
...
...
@@ -872,7 +857,7 @@ class VmDiskResizeForm(forms.Form):
return
helper
class
VmDiskRemoveForm
(
forms
.
Form
):
class
VmDiskRemoveForm
(
Operation
Form
):
def
__init__
(
self
,
*
args
,
**
kwargs
):
choices
=
kwargs
.
pop
(
'choices'
)
self
.
disk
=
kwargs
.
pop
(
'default'
)
...
...
@@ -887,8 +872,7 @@ class VmDiskRemoveForm(forms.Form):
@property
def
helper
(
self
):
helper
=
FormHelper
(
self
)
helper
.
form_tag
=
False
helper
=
super
(
VmDiskRemoveForm
,
self
)
.
helper
if
self
.
disk
:
helper
.
layout
=
Layout
(
AnyTag
(
...
...
@@ -901,16 +885,10 @@ class VmDiskRemoveForm(forms.Form):
return
helper
class
VmDownloadDiskForm
(
forms
.
Form
):
class
VmDownloadDiskForm
(
Operation
Form
):
name
=
forms
.
CharField
(
max_length
=
100
,
label
=
_
(
"Name"
),
required
=
False
)
url
=
forms
.
CharField
(
label
=
_
(
'URL'
),
validators
=
[
URLValidator
(),
])
@property
def
helper
(
self
):
helper
=
FormHelper
(
self
)
helper
.
form_tag
=
False
return
helper
def
clean
(
self
):
cleaned_data
=
super
(
VmDownloadDiskForm
,
self
)
.
clean
()
if
not
cleaned_data
[
'name'
]:
...
...
@@ -924,7 +902,7 @@ class VmDownloadDiskForm(forms.Form):
return
cleaned_data
class
VmAddInterfaceForm
(
forms
.
Form
):
class
VmAddInterfaceForm
(
Operation
Form
):
def
__init__
(
self
,
*
args
,
**
kwargs
):
choices
=
kwargs
.
pop
(
'choices'
)
super
(
VmAddInterfaceForm
,
self
)
.
__init__
(
*
args
,
**
kwargs
)
...
...
@@ -936,11 +914,19 @@ class VmAddInterfaceForm(forms.Form):
field
.
empty_label
=
_
(
'No more networks.'
)
self
.
fields
[
'vlan'
]
=
field
@property
def
helper
(
self
):
helper
=
FormHelper
(
self
)
helper
.
form_tag
=
False
return
helper
class
VmDeployForm
(
OperationForm
):
def
__init__
(
self
,
*
args
,
**
kwargs
):
choices
=
kwargs
.
pop
(
'choices'
,
None
)
super
(
VmDeployForm
,
self
)
.
__init__
(
*
args
,
**
kwargs
)
if
choices
is
not
None
:
self
.
fields
.
insert
(
0
,
'node'
,
forms
.
ModelChoiceField
(
queryset
=
choices
,
required
=
False
,
label
=
_
(
'Node'
),
help_text
=
_
(
"Deploy virtual machine to this node "
"(blank allows scheduling automatically)."
)))
class
CircleAuthenticationForm
(
AuthenticationForm
):
...
...
circle/dashboard/templates/dashboard/_disk-list-element.html
View file @
d3fc9a1f
...
...
@@ -8,7 +8,7 @@
<span
class=
"operation-wrapper"
>
<a
href=
"{{ op.remove_disk.get_url }}?disk={{d.pk}}"
class=
"btn btn-xs btn-{{ op.remove_disk.effect}} pull-right operation disk-remove-btn
{% if op.re
siz
e_disk.disabled %}disabled{% endif %}"
>
{% if op.re
mov
e_disk.disabled %}disabled{% endif %}"
>
<i
class=
"fa fa-{{ op.remove_disk.icon }}"
></i>
{% trans "Remove" %}
</a>
</span>
...
...
circle/dashboard/views/vm.py
View file @
d3fc9a1f
...
...
@@ -60,7 +60,7 @@ from ..forms import (
VmAddInterfaceForm
,
VmCreateDiskForm
,
VmDownloadDiskForm
,
VmSaveForm
,
VmRenewForm
,
VmStateChangeForm
,
VmListSearchForm
,
VmCustomizeForm
,
TransferOwnershipForm
,
VmDiskResizeForm
,
RedeployForm
,
VmDiskRemoveForm
,
VmMigrateForm
,
VmMigrateForm
,
VmDeployForm
,
)
from
..models
import
Favourite
,
Profile
...
...
@@ -605,7 +605,6 @@ class VmStateChangeView(FormOperationMixin, VmOperationView):
op
=
'emergency_change_state'
icon
=
'legal'
effect
=
'danger'
show_in_toolbar
=
True
form_class
=
VmStateChangeForm
wait_for_result
=
0.5
...
...
@@ -628,9 +627,23 @@ class RedeployView(FormOperationMixin, VmOperationView):
wait_for_result
=
0.5
class
VmDeployView
(
FormOperationMixin
,
VmOperationView
):
op
=
'deploy'
icon
=
'play'
effect
=
'success'
form_class
=
VmDeployForm
def
get_form_kwargs
(
self
):
kwargs
=
super
(
VmDeployView
,
self
)
.
get_form_kwargs
()
if
self
.
request
.
user
.
is_superuser
:
online
=
(
n
.
pk
for
n
in
Node
.
objects
.
filter
(
enabled
=
True
)
if
n
.
online
)
kwargs
[
'choices'
]
=
Node
.
objects
.
filter
(
pk__in
=
online
)
return
kwargs
vm_ops
=
OrderedDict
([
(
'deploy'
,
VmOperationView
.
factory
(
op
=
'deploy'
,
icon
=
'play'
,
effect
=
'success'
)),
(
'deploy'
,
VmDeployView
),
(
'wake_up'
,
VmOperationView
.
factory
(
op
=
'wake_up'
,
icon
=
'sun-o'
,
effect
=
'success'
)),
(
'sleep'
,
VmOperationView
.
factory
(
...
...
circle/vm/operations.py
View file @
d3fc9a1f
...
...
@@ -324,10 +324,14 @@ class DeployOperation(InstanceOperation):
"deployed to node:
%(node)
s"
),
node
=
self
.
instance
.
node
)
def
_operation
(
self
,
activity
):
def
_operation
(
self
,
activity
,
node
=
None
):
# Allocate VNC port and host node
self
.
instance
.
allocate_vnc_port
()
self
.
instance
.
allocate_node
()
if
node
is
not
None
:
self
.
instance
.
node
=
node
self
.
instance
.
save
()
else
:
self
.
instance
.
allocate_node
()
# Deploy virtual images
self
.
instance
.
_deploy_disks
(
parent_activity
=
activity
)
...
...
@@ -462,8 +466,8 @@ class DestroyOperation(InstanceOperation):
class
MigrateOperation
(
RemoteInstanceOperation
):
id
=
'migrate'
name
=
_
(
"migrate"
)
description
=
_
(
"Move
virtual machine to an other worker node with a few
"
"
seconds of interruption (live migration)
."
)
description
=
_
(
"Move
a running virtual machine to an other worker node
"
"
keeping its full state
."
)
required_perms
=
()
superuser_required
=
True
accept_states
=
(
'RUNNING'
,
)
...
...
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