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
a3ceda07
authored
Sep 29, 2014
by
Bach Dániel
Browse files
Options
Browse Files
Download
Plain Diff
Merge branch 'feature-redeploy' into 'master'
Feature Redeploy
🚧
test See merge request !218
parents
f0929ad9
a431c8f2
Hide whitespace changes
Inline
Side-by-side
Showing
5 changed files
with
88 additions
and
2 deletions
+88
-2
circle/dashboard/forms.py
+12
-0
circle/dashboard/views/node.py
+2
-0
circle/dashboard/views/vm.py
+11
-1
circle/vm/models/instance.py
+1
-0
circle/vm/operations.py
+62
-1
No files found.
circle/dashboard/forms.py
View file @
a3ceda07
...
@@ -752,6 +752,7 @@ class VmStateChangeForm(forms.Form):
...
@@ -752,6 +752,7 @@ class VmStateChangeForm(forms.Form):
"but don't interrupt any tasks."
))
"but don't interrupt any tasks."
))
new_state
=
forms
.
ChoiceField
(
Instance
.
STATUS
,
label
=
_
(
new_state
=
forms
.
ChoiceField
(
Instance
.
STATUS
,
label
=
_
(
"New status"
))
"New status"
))
reset_node
=
forms
.
BooleanField
(
required
=
False
,
label
=
_
(
"Reset node"
))
def
__init__
(
self
,
*
args
,
**
kwargs
):
def
__init__
(
self
,
*
args
,
**
kwargs
):
show_interrupt
=
kwargs
.
pop
(
'show_interrupt'
)
show_interrupt
=
kwargs
.
pop
(
'show_interrupt'
)
...
@@ -769,6 +770,17 @@ class VmStateChangeForm(forms.Form):
...
@@ -769,6 +770,17 @@ class VmStateChangeForm(forms.Form):
return
helper
return
helper
class
RedeployForm
(
forms
.
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
(
forms
.
Form
):
name
=
forms
.
CharField
(
max_length
=
100
,
label
=
_
(
"Name"
))
name
=
forms
.
CharField
(
max_length
=
100
,
label
=
_
(
"Name"
))
size
=
forms
.
CharField
(
size
=
forms
.
CharField
(
...
...
circle/dashboard/views/node.py
View file @
a3ceda07
...
@@ -68,6 +68,8 @@ node_ops = OrderedDict([
...
@@ -68,6 +68,8 @@ node_ops = OrderedDict([
op
=
'passivate'
,
icon
=
'play-circle-o'
,
effect
=
'info'
)),
op
=
'passivate'
,
icon
=
'play-circle-o'
,
effect
=
'info'
)),
(
'disable'
,
NodeOperationView
.
factory
(
(
'disable'
,
NodeOperationView
.
factory
(
op
=
'disable'
,
icon
=
'times-circle-o'
,
effect
=
'danger'
)),
op
=
'disable'
,
icon
=
'times-circle-o'
,
effect
=
'danger'
)),
(
'reset'
,
NodeOperationView
.
factory
(
op
=
'reset'
,
icon
=
'stethoscope'
,
effect
=
'danger'
)),
(
'flush'
,
NodeOperationView
.
factory
(
(
'flush'
,
NodeOperationView
.
factory
(
op
=
'flush'
,
icon
=
'paint-brush'
,
effect
=
'danger'
)),
op
=
'flush'
,
icon
=
'paint-brush'
,
effect
=
'danger'
)),
])
])
...
...
circle/dashboard/views/vm.py
View file @
a3ceda07
...
@@ -58,7 +58,7 @@ from ..forms import (
...
@@ -58,7 +58,7 @@ from ..forms import (
AclUserOrGroupAddForm
,
VmResourcesForm
,
TraitsForm
,
RawDataForm
,
AclUserOrGroupAddForm
,
VmResourcesForm
,
TraitsForm
,
RawDataForm
,
VmAddInterfaceForm
,
VmCreateDiskForm
,
VmDownloadDiskForm
,
VmSaveForm
,
VmAddInterfaceForm
,
VmCreateDiskForm
,
VmDownloadDiskForm
,
VmSaveForm
,
VmRenewForm
,
VmStateChangeForm
,
VmListSearchForm
,
VmCustomizeForm
,
VmRenewForm
,
VmStateChangeForm
,
VmListSearchForm
,
VmCustomizeForm
,
TransferOwnershipForm
,
VmDiskResizeForm
,
TransferOwnershipForm
,
VmDiskResizeForm
,
RedeployForm
,
)
)
from
..models
import
Favourite
,
Profile
from
..models
import
Favourite
,
Profile
...
@@ -599,6 +599,15 @@ class VmStateChangeView(FormOperationMixin, VmOperationView):
...
@@ -599,6 +599,15 @@ class VmStateChangeView(FormOperationMixin, VmOperationView):
return
val
return
val
class
RedeployView
(
FormOperationMixin
,
VmOperationView
):
op
=
'redeploy'
icon
=
'stethoscope'
effect
=
'danger'
show_in_toolbar
=
True
form_class
=
RedeployForm
wait_for_result
=
0.5
vm_ops
=
OrderedDict
([
vm_ops
=
OrderedDict
([
(
'deploy'
,
VmOperationView
.
factory
(
(
'deploy'
,
VmOperationView
.
factory
(
op
=
'deploy'
,
icon
=
'play'
,
effect
=
'success'
)),
op
=
'deploy'
,
icon
=
'play'
,
effect
=
'success'
)),
...
@@ -620,6 +629,7 @@ vm_ops = OrderedDict([
...
@@ -620,6 +629,7 @@ vm_ops = OrderedDict([
(
'recover'
,
VmOperationView
.
factory
(
(
'recover'
,
VmOperationView
.
factory
(
op
=
'recover'
,
icon
=
'medkit'
,
effect
=
'warning'
)),
op
=
'recover'
,
icon
=
'medkit'
,
effect
=
'warning'
)),
(
'nostate'
,
VmStateChangeView
),
(
'nostate'
,
VmStateChangeView
),
(
'redeploy'
,
RedeployView
),
(
'destroy'
,
VmOperationView
.
factory
(
(
'destroy'
,
VmOperationView
.
factory
(
extra_bases
=
[
TokenOperationView
],
extra_bases
=
[
TokenOperationView
],
op
=
'destroy'
,
icon
=
'times'
,
effect
=
'danger'
)),
op
=
'destroy'
,
icon
=
'times'
,
effect
=
'danger'
)),
...
...
circle/vm/models/instance.py
View file @
a3ceda07
...
@@ -275,6 +275,7 @@ class Instance(AclBase, VirtualMachineDescModel, StatusModel, OperatedMixin,
...
@@ -275,6 +275,7 @@ class Instance(AclBase, VirtualMachineDescModel, StatusModel, OperatedMixin,
(
'change_resources'
,
_
(
'Can change resources of a running VM.'
)),
(
'change_resources'
,
_
(
'Can change resources of a running VM.'
)),
(
'set_resources'
,
_
(
'Can change resources of a new VM.'
)),
(
'set_resources'
,
_
(
'Can change resources of a new VM.'
)),
(
'create_vm'
,
_
(
'Can create a new VM.'
)),
(
'create_vm'
,
_
(
'Can create a new VM.'
)),
(
'redeploy'
,
_
(
'Can redeploy a VM.'
)),
(
'config_ports'
,
_
(
'Can configure port forwards.'
)),
(
'config_ports'
,
_
(
'Can configure port forwards.'
)),
(
'recover'
,
_
(
'Can recover a destroyed VM.'
)),
(
'recover'
,
_
(
'Can recover a destroyed VM.'
)),
(
'emergency_change_state'
,
_
(
'Can change VM state to NOSTATE.'
)),
(
'emergency_change_state'
,
_
(
'Can change VM state to NOSTATE.'
)),
...
...
circle/vm/operations.py
View file @
a3ceda07
...
@@ -806,7 +806,8 @@ class ChangeStateOperation(InstanceOperation):
...
@@ -806,7 +806,8 @@ class ChangeStateOperation(InstanceOperation):
required_perms
=
(
'vm.emergency_change_state'
,
)
required_perms
=
(
'vm.emergency_change_state'
,
)
concurrency_check
=
False
concurrency_check
=
False
def
_operation
(
self
,
user
,
activity
,
new_state
=
"NOSTATE"
,
interrupt
=
False
):
def
_operation
(
self
,
user
,
activity
,
new_state
=
"NOSTATE"
,
interrupt
=
False
,
reset_node
=
False
):
activity
.
resultant_state
=
new_state
activity
.
resultant_state
=
new_state
if
interrupt
:
if
interrupt
:
msg_txt
=
ugettext_noop
(
"Activity is forcibly interrupted."
)
msg_txt
=
ugettext_noop
(
"Activity is forcibly interrupted."
)
...
@@ -816,6 +817,37 @@ class ChangeStateOperation(InstanceOperation):
...
@@ -816,6 +817,37 @@ class ChangeStateOperation(InstanceOperation):
i
.
finish
(
False
,
result
=
message
)
i
.
finish
(
False
,
result
=
message
)
logger
.
error
(
'Forced finishing activity
%
s'
,
i
)
logger
.
error
(
'Forced finishing activity
%
s'
,
i
)
if
reset_node
:
self
.
instance
.
node
=
None
self
.
instance
.
save
()
@register_operation
class
RedeployOperation
(
InstanceOperation
):
activity_code_suffix
=
'redeploy'
id
=
'redeploy'
name
=
_
(
"redeploy"
)
description
=
_
(
"Change the virtual machine state to NOSTATE "
"and redeploy the VM. This operation allows starting "
"machines formerly running on a failed node."
)
acl_level
=
"owner"
required_perms
=
(
'vm.redeploy'
,
)
concurrency_check
=
False
def
_operation
(
self
,
user
,
activity
,
with_emergency_change_state
=
True
):
if
with_emergency_change_state
:
ChangeStateOperation
(
self
.
instance
)
.
call
(
parent_activity
=
activity
,
user
=
user
,
new_state
=
'NOSTATE'
,
interrupt
=
False
,
reset_node
=
True
)
else
:
ShutOffOperation
(
self
.
instance
)
.
call
(
parent_activity
=
activity
,
user
=
user
)
self
.
instance
.
_update_status
()
DeployOperation
(
self
.
instance
)
.
call
(
parent_activity
=
activity
,
user
=
user
)
class
NodeOperation
(
Operation
):
class
NodeOperation
(
Operation
):
async_operation
=
abortable_async_node_operation
async_operation
=
abortable_async_node_operation
...
@@ -855,6 +887,35 @@ class NodeOperation(Operation):
...
@@ -855,6 +887,35 @@ class NodeOperation(Operation):
@register_operation
@register_operation
class
ResetNodeOperation
(
NodeOperation
):
activity_code_suffix
=
'reset'
id
=
'reset'
name
=
_
(
"reset"
)
description
=
_
(
"Disable missing node and redeploy all instances "
"on other ones."
)
required_perms
=
()
online_required
=
False
async_queue
=
"localhost.man.slow"
def
check_precond
(
self
):
super
(
ResetNodeOperation
,
self
)
.
check_precond
()
if
not
self
.
node
.
enabled
or
self
.
node
.
online
:
raise
humanize_exception
(
ugettext_noop
(
"You cannot reset a disabled or online node."
),
Exception
())
def
_operation
(
self
,
activity
,
user
):
if
self
.
node
.
enabled
:
DisableOperation
(
self
.
node
)
.
call
(
parent_activity
=
activity
,
user
=
user
)
for
i
in
self
.
node
.
instance_set
.
all
():
name
=
create_readable
(
ugettext_noop
(
"migrate
%(instance)
s (
%(pk)
s)"
),
instance
=
i
.
name
,
pk
=
i
.
pk
)
with
activity
.
sub_activity
(
'migrate_instance_
%
d'
%
i
.
pk
,
readable_name
=
name
):
i
.
redeploy
(
user
=
user
)
@register_operation
class
FlushOperation
(
NodeOperation
):
class
FlushOperation
(
NodeOperation
):
activity_code_suffix
=
'flush'
activity_code_suffix
=
'flush'
id
=
'flush'
id
=
'flush'
...
...
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