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
db560b90
authored
Aug 27, 2014
by
Őry Máté
Browse files
Options
Browse Files
Download
Plain Diff
Merge branch 'master' into feature-mass-ops
parents
9f4783eb
106f963d
Hide whitespace changes
Inline
Side-by-side
Showing
14 changed files
with
112 additions
and
225 deletions
+112
-225
circle/circle/settings/base.py
+3
-3
circle/dashboard/forms.py
+35
-15
circle/dashboard/static/dashboard/dashboard.js
+1
-1
circle/dashboard/static/dashboard/group-list.js
+0
-126
circle/dashboard/templates/dashboard/_vm-create-2.html
+3
-1
circle/dashboard/templates/dashboard/group-list.html
+6
-45
circle/dashboard/templates/dashboard/group-list/column-actions.html
+5
-1
circle/dashboard/templates/dashboard/index-nodes.html
+4
-2
circle/dashboard/templates/dashboard/index-vm.html
+6
-4
circle/dashboard/templates/dashboard/vm-detail/_operations.html
+1
-1
circle/dashboard/views.py
+29
-9
circle/firewall/models.py
+1
-10
circle/vm/operations.py
+12
-2
circle/vm/tasks/local_agent_tasks.py
+6
-5
No files found.
circle/circle/settings/base.py
View file @
db560b90
...
@@ -368,9 +368,9 @@ if get_env_variable('DJANGO_SAML', 'FALSE') == 'TRUE':
...
@@ -368,9 +368,9 @@ if get_env_variable('DJANGO_SAML', 'FALSE') == 'TRUE':
from
shutilwhich
import
which
from
shutilwhich
import
which
from
saml2
import
BINDING_HTTP_POST
,
BINDING_HTTP_REDIRECT
from
saml2
import
BINDING_HTTP_POST
,
BINDING_HTTP_REDIRECT
# INSTALLED_APPS += ( # needed only for testing djangosaml2
INSTALLED_APPS
+=
(
# 'djangosaml
',
'djangosaml2
'
,
#
)
)
AUTHENTICATION_BACKENDS
=
(
AUTHENTICATION_BACKENDS
=
(
'django.contrib.auth.backends.ModelBackend'
,
'django.contrib.auth.backends.ModelBackend'
,
'djangosaml2.backends.Saml2Backend'
,
'djangosaml2.backends.Saml2Backend'
,
...
...
circle/dashboard/forms.py
View file @
db560b90
...
@@ -634,12 +634,8 @@ class LeaseForm(forms.ModelForm):
...
@@ -634,12 +634,8 @@ class LeaseForm(forms.ModelForm):
Field
(
'name'
),
Field
(
'name'
),
Field
(
"suspend_interval_seconds"
,
type
=
"hidden"
,
value
=
"0"
),
Field
(
"suspend_interval_seconds"
,
type
=
"hidden"
,
value
=
"0"
),
Field
(
"delete_interval_seconds"
,
type
=
"hidden"
,
value
=
"0"
),
Field
(
"delete_interval_seconds"
,
type
=
"hidden"
,
value
=
"0"
),
HTML
(
string_concat
(
"<label>"
,
_
(
"Suspend in"
),
"</label>"
)),
Div
(
Div
(
Div
(
HTML
(
_
(
"Suspend in"
)),
css_class
=
"input-group-addon"
,
style
=
"width: 100px;"
,
),
NumberField
(
"suspend_hours"
,
css_class
=
"form-control"
),
NumberField
(
"suspend_hours"
,
css_class
=
"form-control"
),
Div
(
Div
(
HTML
(
_
(
"hours"
)),
HTML
(
_
(
"hours"
)),
...
@@ -662,12 +658,8 @@ class LeaseForm(forms.ModelForm):
...
@@ -662,12 +658,8 @@ class LeaseForm(forms.ModelForm):
),
),
css_class
=
"input-group interval-input"
,
css_class
=
"input-group interval-input"
,
),
),
HTML
(
string_concat
(
"<label>"
,
_
(
"Delete in"
),
"</label>"
)),
Div
(
Div
(
Div
(
HTML
(
_
(
"Delete in"
)),
css_class
=
"input-group-addon"
,
style
=
"width: 100px;"
,
),
NumberField
(
"delete_hours"
,
css_class
=
"form-control"
),
NumberField
(
"delete_hours"
,
css_class
=
"form-control"
),
Div
(
Div
(
HTML
(
_
(
"hours"
)),
HTML
(
_
(
"hours"
)),
...
@@ -691,7 +683,7 @@ class LeaseForm(forms.ModelForm):
...
@@ -691,7 +683,7 @@ class LeaseForm(forms.ModelForm):
css_class
=
"input-group interval-input"
,
css_class
=
"input-group interval-input"
,
)
)
)
)
helper
.
add_input
(
Submit
(
"submit"
,
"Save changes"
))
helper
.
add_input
(
Submit
(
"submit"
,
_
(
"Save changes"
)
))
return
helper
return
helper
class
Meta
:
class
Meta
:
...
@@ -703,6 +695,8 @@ class VmRenewForm(forms.Form):
...
@@ -703,6 +695,8 @@ class VmRenewForm(forms.Form):
force
=
forms
.
BooleanField
(
required
=
False
,
label
=
_
(
force
=
forms
.
BooleanField
(
required
=
False
,
label
=
_
(
"Set expiration times even if they are shorter than "
"Set expiration times even if they are shorter than "
"the current value."
))
"the current value."
))
save
=
forms
.
BooleanField
(
required
=
False
,
label
=
_
(
"Save selected lease."
))
def
__init__
(
self
,
*
args
,
**
kwargs
):
def
__init__
(
self
,
*
args
,
**
kwargs
):
choices
=
kwargs
.
pop
(
'choices'
)
choices
=
kwargs
.
pop
(
'choices'
)
...
@@ -714,6 +708,32 @@ class VmRenewForm(forms.Form):
...
@@ -714,6 +708,32 @@ class VmRenewForm(forms.Form):
empty_label
=
None
,
label
=
_
(
'Length'
)))
empty_label
=
None
,
label
=
_
(
'Length'
)))
if
len
(
choices
)
<
2
:
if
len
(
choices
)
<
2
:
self
.
fields
[
'lease'
]
.
widget
=
HiddenInput
()
self
.
fields
[
'lease'
]
.
widget
=
HiddenInput
()
self
.
fields
[
'save'
]
.
widget
=
HiddenInput
()
@property
def
helper
(
self
):
helper
=
FormHelper
(
self
)
helper
.
form_tag
=
False
return
helper
class
VmStateChangeForm
(
forms
.
Form
):
interrupt
=
forms
.
BooleanField
(
required
=
False
,
label
=
_
(
"Forcibly interrupt all running activities."
),
help_text
=
_
(
"Set all activities to finished state, "
"but don't interrupt any tasks."
))
new_state
=
forms
.
ChoiceField
(
Instance
.
STATUS
,
label
=
_
(
"New status"
))
def
__init__
(
self
,
*
args
,
**
kwargs
):
show_interrupt
=
kwargs
.
pop
(
'show_interrupt'
)
status
=
kwargs
.
pop
(
'status'
)
super
(
VmStateChangeForm
,
self
)
.
__init__
(
*
args
,
**
kwargs
)
if
not
show_interrupt
:
self
.
fields
[
'interrupt'
]
.
widget
=
HiddenInput
()
self
.
fields
[
'new_state'
]
.
initial
=
status
@property
@property
def
helper
(
self
):
def
helper
(
self
):
...
@@ -1141,9 +1161,9 @@ class VmResourcesForm(forms.ModelForm):
...
@@ -1141,9 +1161,9 @@ class VmResourcesForm(forms.ModelForm):
vm_search_choices
=
(
vm_search_choices
=
(
(
0
,
_
(
"owned"
)),
(
"owned"
,
_
(
"owned"
)),
(
1
,
_
(
"shared"
)),
(
"shared"
,
_
(
"shared"
)),
(
2
,
_
(
"all"
)),
(
"all"
,
_
(
"all"
)),
)
)
...
@@ -1162,5 +1182,5 @@ class VmListSearchForm(forms.Form):
...
@@ -1162,5 +1182,5 @@ class VmListSearchForm(forms.Form):
# set initial value, otherwise it would be overwritten by request.GET
# set initial value, otherwise it would be overwritten by request.GET
if
not
self
.
data
.
get
(
"stype"
):
if
not
self
.
data
.
get
(
"stype"
):
data
=
self
.
data
.
copy
()
data
=
self
.
data
.
copy
()
data
[
'stype'
]
=
2
data
[
'stype'
]
=
"all"
self
.
data
=
data
self
.
data
=
data
circle/dashboard/static/dashboard/dashboard.js
View file @
db560b90
...
@@ -262,7 +262,7 @@ $(function () {
...
@@ -262,7 +262,7 @@ $(function () {
$
(
"#dashboard-vm-search-form"
).
submit
(
function
()
{
$
(
"#dashboard-vm-search-form"
).
submit
(
function
()
{
var
vm_list_items
=
$
(
"#dashboard-vm-list .list-group-item"
);
var
vm_list_items
=
$
(
"#dashboard-vm-list .list-group-item"
);
if
(
vm_list_items
.
length
==
1
)
{
if
(
vm_list_items
.
length
==
1
&&
vm_list_items
.
first
().
prop
(
"href"
)
)
{
window
.
location
.
href
=
vm_list_items
.
first
().
prop
(
"href"
);
window
.
location
.
href
=
vm_list_items
.
first
().
prop
(
"href"
);
return
false
;
return
false
;
}
}
...
...
circle/dashboard/static/dashboard/group-list.js
View file @
db560b90
var
ctrlDown
,
shiftDown
=
false
;
var
ctrlKey
=
17
;
var
shiftKey
=
16
;
var
selected
=
[];
$
(
function
()
{
$
(
function
()
{
$
(
document
).
keydown
(
function
(
e
)
{
if
(
e
.
keyCode
==
ctrlKey
)
ctrlDown
=
true
;
if
(
e
.
keyCode
==
shiftKey
)
shiftDown
=
true
;
}).
keyup
(
function
(
e
)
{
if
(
e
.
keyCode
==
ctrlKey
)
ctrlDown
=
false
;
if
(
e
.
keyCode
==
shiftKey
)
shiftDown
=
false
;
});
$
(
'.group-list-table tbody'
).
find
(
'tr'
).
mousedown
(
function
()
{
var
retval
=
true
;
if
(
ctrlDown
)
{
setRowColor
(
$
(
this
));
if
(
!
$
(
this
).
hasClass
(
'group-list-selected'
))
{
selected
.
splice
(
selected
.
indexOf
(
$
(
this
).
index
()),
1
);
}
else
{
selected
.
push
(
$
(
this
).
index
());
}
retval
=
false
;
}
else
if
(
shiftDown
)
{
if
(
selected
.
length
>
0
)
{
start
=
selected
[
selected
.
length
-
1
]
+
1
;
end
=
$
(
this
).
index
();
if
(
start
>
end
)
{
var
tmp
=
start
-
1
;
start
=
end
;
end
=
tmp
-
1
;
}
for
(
var
i
=
start
;
i
<=
end
;
i
++
)
{
if
(
selected
.
indexOf
(
i
)
<
0
)
{
selected
.
push
(
i
);
setRowColor
(
$
(
'.group-list-table tbody tr'
).
eq
(
i
));
}
}
}
retval
=
false
;
}
else
{
$
(
'.group-list-selected'
).
removeClass
(
'group-list-selected'
);
$
(
this
).
addClass
(
'group-list-selected'
);
selected
=
[
$
(
this
).
index
()];
}
// reset btn disables
$
(
'.group-list-table tbody tr .btn'
).
attr
(
'disabled'
,
false
);
// show/hide group controls
if
(
selected
.
length
>
1
)
{
$
(
'.group-list-group-control a'
).
attr
(
'disabled'
,
false
);
for
(
var
i
=
0
;
i
<
selected
.
length
;
i
++
)
{
$
(
'.group-list-table tbody tr'
).
eq
(
selected
[
i
]).
find
(
'.btn'
).
attr
(
'disabled'
,
true
);
}
}
else
{
$
(
'.group-list-group-control a'
).
attr
(
'disabled'
,
true
);
}
return
retval
;
});
$
(
'#group-list-group-migrate'
).
click
(
function
()
{
console
.
log
(
collectIds
(
selected
));
});
$
(
'tbody a'
).
mousedown
(
function
(
e
)
{
// parent tr doesn't get selected when clicked
e
.
stopPropagation
();
});
$
(
'tbody a'
).
click
(
function
(
e
)
{
// browser doesn't jump to top when clicked the buttons
if
(
!
$
(
this
).
hasClass
(
'real-link'
))
{
return
false
;
}
});
/* rename */
/* rename */
$
(
"#group-list-rename-button, .group-details-rename-button"
).
click
(
function
()
{
$
(
"#group-list-rename-button, .group-details-rename-button"
).
click
(
function
()
{
$
(
"#group-list-column-name"
,
$
(
this
).
closest
(
"tr"
)).
hide
();
$
(
"#group-list-column-name"
,
$
(
this
).
closest
(
"tr"
)).
hide
();
...
@@ -113,51 +34,4 @@ $(function() {
...
@@ -113,51 +34,4 @@ $(function() {
return
false
;
return
false
;
});
});
/* group actions */
/* select all */
$
(
'#group-list-group-select-all'
).
click
(
function
()
{
$
(
'.group-list-table tbody tr'
).
each
(
function
()
{
var
index
=
$
(
this
).
index
();
if
(
selected
.
indexOf
(
index
)
<
0
)
{
selected
.
push
(
index
);
$
(
this
).
addClass
(
'group-list-selected'
);
}
});
if
(
selected
.
length
>
0
)
$
(
'.group-list-group-control a'
).
attr
(
'disabled'
,
false
);
return
false
;
});
/* mass vm delete */
$
(
'#group-list-group-delete'
).
click
(
function
()
{
addModalConfirmation
(
massDeleteVm
,
{
'url'
:
'/dashboard/group/mass-delete/'
,
'data'
:
{
'selected'
:
selected
,
'v'
:
collectIds
(
selected
)
}
}
);
return
false
;
});
});
});
function
collectIds
(
rows
)
{
var
ids
=
[];
for
(
var
i
=
0
;
i
<
rows
.
length
;
i
++
)
{
var
div
=
$
(
'td:first-child div'
,
$
(
'.group-list-table tbody tr'
).
eq
(
rows
[
i
]));
ids
.
push
(
div
.
prop
(
'id'
).
replace
(
'node-'
,
''
));
}
return
ids
;
}
function
setRowColor
(
row
)
{
if
(
!
row
.
hasClass
(
'group-list-selected'
))
{
row
.
addClass
(
'group-list-selected'
);
}
else
{
row
.
removeClass
(
'group-list-selected'
);
}
}
circle/dashboard/templates/dashboard/_vm-create-2.html
View file @
db560b90
...
@@ -7,7 +7,6 @@
...
@@ -7,7 +7,6 @@
{% csrf_token %}
{% csrf_token %}
{{ vm_create_form.template }}
{{ vm_create_form.template }}
{{ vm_create_form.customized }}
<div
class=
"row"
>
<div
class=
"row"
>
<div
class=
"col-sm-12"
>
<div
class=
"col-sm-12"
>
...
@@ -23,6 +22,8 @@
...
@@ -23,6 +22,8 @@
</div>
</div>
</div>
</div>
{% if perms.vm.set_resources %}
{{ vm_create_form.customized }}
<div
class=
"row"
>
<div
class=
"row"
>
<div
class=
"col-sm-10"
>
<div
class=
"col-sm-10"
>
<div
class=
"form-group"
>
<div
class=
"form-group"
>
...
@@ -85,6 +86,7 @@
...
@@ -85,6 +86,7 @@
</div>
<!-- .no-js-hidden -->
</div>
<!-- .no-js-hidden -->
</div>
<!-- .col-sm-8 -->
</div>
<!-- .col-sm-8 -->
</div>
<!-- .row -->
</div>
<!-- .row -->
{% endif %}
</form>
</form>
<script>
<script>
...
...
circle/dashboard/templates/dashboard/group-list.html
View file @
db560b90
...
@@ -6,63 +6,24 @@
...
@@ -6,63 +6,24 @@
{% block content %}
{% block content %}
<div
class=
"alert alert-info"
>
Tip #1: you can select multiple vm instances while holding down the
<strong>
CTRL
</strong>
key!
</div>
<div
class=
"alert alert-info"
>
Tip #2: if you want to select multiple instances by one click select an instance then hold down
<strong>
SHIFT
</strong>
key and select another one!
</div>
<div
class=
"row"
>
<div
class=
"row"
>
<div
class=
"col-md-12"
>
<div
class=
"col-md-12"
>
<div
class=
"panel panel-default"
>
<div
class=
"panel panel-default"
>
<div
class=
"panel-heading"
>
<div
class=
"panel-heading"
>
<h3
class=
"no-margin"
><i
class=
"fa fa-group"
></i>
Your groups
</h3>
<h3
class=
"no-margin"
><i
class=
"fa fa-group"
></i>
Your groups
</h3>
</div>
</div>
<div
class=
"panel-body group-list-group-control"
>
<div
class=
"panel-body"
>
<p>
<strong>
Group actions
</strong>
<button
id=
"group-list-group-select-all"
class=
"btn btn-info btn-xs"
>
Select all
</button>
<a
id=
"group-list-group-delete"
disabled
href=
"#"
class=
"btn btn-danger btn-xs"
><i
class=
"fa fa-times"
></i>
Discard
</a>
</p>
</div>
<div
id=
"table_container"
>
<div
id=
"table_container"
>
<div
id=
"rendered_table"
class=
"panel-body"
>
<div
id=
"rendered_table"
class=
"panel-body"
>
{% render_table table %}
{% render_table table %}
</div>
</div>
</div>
</div>
</div>
<!-- .panel-body -->
</div>
</div>
</div>
</div>
</div>
</div>
<style>
.popover
{
max-width
:
600px
;
}
.group-list-selected
,
.group-list-selected
td
{
background-color
:
#e8e8e8
!important
;
}
.group-list-selected
:hover
,
.group-list-selected
:hover
td
{
background-color
:
#d0d0d0
!important
;
}
.group-list-selected
td
:first-child
{
font-weight
:
bold
;
}
.group-list-table-thin
{
width
:
10px
;
}
.group-list-table-admin
{
width
:
130px
;
}
</style>
{% endblock %}
{% endblock %}
{% block extra_js %}
{% block extra_js %}
<script
src=
"{{ STATIC_URL}}dashboard/group-list.js"
></script>
<script
src=
"{{ STATIC_URL}}dashboard/group-list.js"
></script>
{% endblock %}
{% endblock %}
circle/dashboard/templates/dashboard/group-list/column-actions.html
View file @
db560b90
<a
data-group-pk=
"{{ record.pk }}"
class=
"btn btn-danger btn-xs real-link group-delete"
href=
"{% url "
dashboard
.
views
.
delete-group
"
pk=
record.pk
%}?
next=
{{
request
.
path
}}"
><i
class=
"fa fa-trash"
></i></a>
<a
data-group-pk=
"{{ record.pk }}"
class=
"btn btn-danger btn-xs real-link group-delete"
href=
"{% url "
dashboard
.
views
.
delete-group
"
pk=
record.pk
%}?
next=
{{
request
.
path
}}"
>
<i
class=
"fa fa-trash-o"
></i>
</a>
circle/dashboard/templates/dashboard/index-nodes.html
View file @
db560b90
...
@@ -3,8 +3,10 @@
...
@@ -3,8 +3,10 @@
<div
class=
"panel-heading"
>
<div
class=
"panel-heading"
>
<div
class=
"pull-right toolbar"
>
<div
class=
"pull-right toolbar"
>
<div
class=
"btn-group"
>
<div
class=
"btn-group"
>
<a
href=
"#index-graph-view"
data-index-box=
"node"
class=
"btn btn-default btn-xs"
><i
class=
"fa fa-dashboard"
></i></a>
<a
href=
"#index-graph-view"
data-index-box=
"node"
class=
"btn btn-default btn-xs"
<a
href=
"#index-list-view"
data-index-box=
"node"
class=
"btn btn-default btn-xs disabled"
><i
class=
"fa fa-list"
></i></a>
data-container=
"body"
><i
class=
"fa fa-dashboard"
></i></a>
<a
href=
"#index-list-view"
data-index-box=
"node"
class=
"btn btn-default btn-xs disabled"
data-container=
"body"
><i
class=
"fa fa-list"
></i></a>
</div>
</div>
<span
class=
"btn btn-default btn-xs infobtn"
title=
"{% trans "
List
of
compute
nodes
,
also
called
worker
nodes
or
hypervisors
,
which
run
the
virtual
machines
."
%}"
><i
class=
"fa fa-info-circle"
></i></span>
<span
class=
"btn btn-default btn-xs infobtn"
title=
"{% trans "
List
of
compute
nodes
,
also
called
worker
nodes
or
hypervisors
,
which
run
the
virtual
machines
."
%}"
><i
class=
"fa fa-info-circle"
></i></span>
...
...
circle/dashboard/templates/dashboard/index-vm.html
View file @
db560b90
...
@@ -3,10 +3,12 @@
...
@@ -3,10 +3,12 @@
<div
class=
"panel-heading"
>
<div
class=
"panel-heading"
>
<div
class=
"pull-right toolbar"
>
<div
class=
"pull-right toolbar"
>
<div
class=
"btn-group"
>
<div
class=
"btn-group"
>
<a
href=
"#index-graph-view"
data-index-box=
"vm"
class=
"btn
<a
href=
"#index-graph-view"
data-index-box=
"vm"
class=
"btn btn-default btn-xs"
btn-default btn-xs"
title=
"{% trans "
summary
view
"
%}"
><i
class=
"fa fa-dashboard"
></i></a>
data-container=
"body"
<a
href=
"#index-list-view"
data-index-box=
"vm"
class=
"btn
title=
"{% trans "
summary
view
"
%}"
><i
class=
"fa fa-dashboard"
></i></a>
btn-default btn-xs disabled"
title=
"{% trans "
list
view
"
%}"
><i
class=
"fa fa-list"
></i></a>
<a
href=
"#index-list-view"
data-index-box=
"vm"
class=
"btn btn-default btn-xs disabled"
data-container=
"body"
title=
"{% trans "
list
view
"
%}"
><i
class=
"fa fa-list"
></i></a>
</div>
</div>
<span
class=
"btn btn-default btn-xs infobtn"
title=
"{% trans "
List
of
your
current
virtual
machines
.
Favourited
ones
are
ahead
of
others
."
%}"
><i
class=
"fa fa-info-circle"
></i></span>
<span
class=
"btn btn-default btn-xs infobtn"
title=
"{% trans "
List
of
your
current
virtual
machines
.
Favourited
ones
are
ahead
of
others
."
%}"
><i
class=
"fa fa-info-circle"
></i></span>
</div>
</div>
...
...
circle/dashboard/templates/dashboard/vm-detail/_operations.html
View file @
db560b90
...
@@ -7,7 +7,7 @@
...
@@ -7,7 +7,7 @@
<span
class=
"operation operation-{{op.op}} btn btn-default disabled btn-xs"
>
<span
class=
"operation operation-{{op.op}} btn btn-default disabled btn-xs"
>
{% else %}
{% else %}
<a
href=
"{{op.get_url}}"
class=
"operation operation-{{op.op}} btn
<a
href=
"{{op.get_url}}"
class=
"operation operation-{{op.op}} btn
btn-{{op.effect}} btn-xs"
title=
"{{op.name|capfirst}}: {{op.description|truncatewords:
20
}}"
>
btn-{{op.effect}} btn-xs"
title=
"{{op.name|capfirst}}: {{op.description|truncatewords:
15
}}"
>
{% endif %}
{% endif %}
<i
class=
"fa fa-{{op.icon}}"
></i>
<i
class=
"fa fa-{{op.icon}}"
></i>
<span
{%
if
not
op
.
is_preferred
%}
class=
"sr-only"
{%
endif
%}
>
{{op.name}}
</span>
<span
{%
if
not
op
.
is_preferred
%}
class=
"sr-only"
{%
endif
%}
>
{{op.name}}
</span>
...
...
circle/dashboard/views.py
View file @
db560b90
...
@@ -67,7 +67,7 @@ from .forms import (
...
@@ -67,7 +67,7 @@ from .forms import (
CircleAuthenticationForm
,
HostForm
,
LeaseForm
,
MyProfileForm
,
CircleAuthenticationForm
,
HostForm
,
LeaseForm
,
MyProfileForm
,
NodeForm
,
TemplateForm
,
TraitForm
,
VmCustomizeForm
,
GroupCreateForm
,
NodeForm
,
TemplateForm
,
TraitForm
,
VmCustomizeForm
,
GroupCreateForm
,
UserCreationForm
,
GroupProfileUpdateForm
,
UnsubscribeForm
,
UserCreationForm
,
GroupProfileUpdateForm
,
UnsubscribeForm
,
VmSaveForm
,
UserKeyForm
,
VmRenewForm
,
VmSaveForm
,
UserKeyForm
,
VmRenewForm
,
VmStateChangeForm
,
CirclePasswordChangeForm
,
VmCreateDiskForm
,
VmDownloadDiskForm
,
CirclePasswordChangeForm
,
VmCreateDiskForm
,
VmDownloadDiskForm
,
TraitsForm
,
RawDataForm
,
GroupPermissionForm
,
AclUserAddForm
,
TraitsForm
,
RawDataForm
,
GroupPermissionForm
,
AclUserAddForm
,
VmResourcesForm
,
VmAddInterfaceForm
,
VmListSearchForm
VmResourcesForm
,
VmAddInterfaceForm
,
VmListSearchForm
...
@@ -936,6 +936,24 @@ class VmRenewView(FormOperationMixin, TokenOperationView, VmOperationView):
...
@@ -936,6 +936,24 @@ class VmRenewView(FormOperationMixin, TokenOperationView, VmOperationView):
return
extra
return
extra
class
VmStateChangeView
(
FormOperationMixin
,
VmOperationView
):
op
=
'emergency_change_state'
icon
=
'legal'
effect
=
'danger'
show_in_toolbar
=
True
form_class
=
VmStateChangeForm
wait_for_result
=
0.5
def
get_form_kwargs
(
self
):
inst
=
self
.
get_op
()
.
instance
active_activities
=
InstanceActivity
.
objects
.
filter
(
finished__isnull
=
True
,
instance
=
inst
)
show_interrupt
=
active_activities
.
exists
()
val
=
super
(
VmStateChangeView
,
self
)
.
get_form_kwargs
()
val
.
update
({
'show_interrupt'
:
show_interrupt
,
'status'
:
inst
.
status
})
return
val
vm_ops
=
OrderedDict
([
vm_ops
=
OrderedDict
([
(
'deploy'
,
VmOperationView
.
factory
(
(
'deploy'
,
VmOperationView
.
factory
(
op
=
'deploy'
,
icon
=
'play'
,
effect
=
'success'
)),
op
=
'deploy'
,
icon
=
'play'
,
effect
=
'success'
)),
...
@@ -956,8 +974,7 @@ vm_ops = OrderedDict([
...
@@ -956,8 +974,7 @@ vm_ops = OrderedDict([
op
=
'shut_off'
,
icon
=
'ban'
,
effect
=
'warning'
)),
op
=
'shut_off'
,
icon
=
'ban'
,
effect
=
'warning'
)),
(
'recover'
,
VmOperationView
.
factory
(
(
'recover'
,
VmOperationView
.
factory
(
op
=
'recover'
,
icon
=
'medkit'
,
effect
=
'warning'
)),
op
=
'recover'
,
icon
=
'medkit'
,
effect
=
'warning'
)),
(
'nostate'
,
VmOperationView
.
factory
(
(
'nostate'
,
VmStateChangeView
),
op
=
'emergency_change_state'
,
icon
=
'legal'
,
effect
=
'danger'
)),
(
'destroy'
,
VmOperationView
.
factory
(
(
'destroy'
,
VmOperationView
.
factory
(
extra_bases
=
[
TokenOperationView
],
extra_bases
=
[
TokenOperationView
],
op
=
'destroy'
,
icon
=
'times'
,
effect
=
'danger'
)),
op
=
'destroy'
,
icon
=
'times'
,
effect
=
'danger'
)),
...
@@ -1764,10 +1781,10 @@ class VmList(LoginRequiredMixin, FilterMixin, ListView):
...
@@ -1764,10 +1781,10 @@ class VmList(LoginRequiredMixin, FilterMixin, ListView):
def
create_default_queryset
(
self
):
def
create_default_queryset
(
self
):
cleaned_data
=
self
.
search_form
.
cleaned_data
cleaned_data
=
self
.
search_form
.
cleaned_data
stype
=
cleaned_data
.
get
(
'stype'
,
2
)
stype
=
cleaned_data
.
get
(
'stype'
,
"all"
)
superuser
=
stype
==
2
superuser
=
stype
==
"all"
shared
=
stype
==
1
shared
=
stype
==
"shared"
level
=
"owner"
if
stype
==
0
else
"user"
level
=
"owner"
if
stype
==
"owned"
else
"user"
queryset
=
Instance
.
get_objects_with_level
(
queryset
=
Instance
.
get_objects_with_level
(
level
,
self
.
request
.
user
,
level
,
self
.
request
.
user
,
group_also
=
shared
,
disregard_superuser
=
not
superuser
,
group_also
=
shared
,
disregard_superuser
=
not
superuser
,
...
@@ -2048,8 +2065,10 @@ class VmCreate(LoginRequiredMixin, TemplateView):
...
@@ -2048,8 +2065,10 @@ class VmCreate(LoginRequiredMixin, TemplateView):
if
not
template
.
has_level
(
request
.
user
,
'user'
):
if
not
template
.
has_level
(
request
.
user
,
'user'
):
raise
PermissionDenied
()
raise
PermissionDenied
()
instances
=
[
Instance
.
create_from_template
(
args
=
{
"template"
:
template
,
"owner"
:
user
}
template
=
template
,
owner
=
user
)]
if
"name"
in
request
.
POST
:
args
[
"name"
]
=
request
.
POST
.
get
(
"name"
)
instances
=
[
Instance
.
create_from_template
(
**
args
)]
return
self
.
__deploy
(
request
,
instances
)
return
self
.
__deploy
(
request
,
instances
)
def
__create_customized
(
self
,
request
,
*
args
,
**
kwargs
):
def
__create_customized
(
self
,
request
,
*
args
,
**
kwargs
):
...
@@ -2075,6 +2094,7 @@ class VmCreate(LoginRequiredMixin, TemplateView):
...
@@ -2075,6 +2094,7 @@ class VmCreate(LoginRequiredMixin, TemplateView):
'num_cores'
:
post
[
'cpu_count'
],
'num_cores'
:
post
[
'cpu_count'
],
'ram_size'
:
post
[
'ram_size'
],
'ram_size'
:
post
[
'ram_size'
],
'priority'
:
post
[
'cpu_priority'
],
'priority'
:
post
[
'cpu_priority'
],
'max_ram_size'
:
post
[
'ram_size'
],
}
}
networks
=
[
InterfaceTemplate
(
vlan
=
l
,
managed
=
l
.
managed
)
networks
=
[
InterfaceTemplate
(
vlan
=
l
,
managed
=
l
.
managed
)
for
l
in
post
[
'networks'
]]
for
l
in
post
[
'networks'
]]
...
...
circle/firewall/models.py
View file @
db560b90
...
@@ -203,12 +203,6 @@ class Rule(models.Model):
...
@@ -203,12 +203,6 @@ class Rule(models.Model):
elif
self
.
firewall_id
:
elif
self
.
firewall_id
:
return
'INPUT'
if
self
.
direction
==
'in'
else
'OUTPUT'
return
'INPUT'
if
self
.
direction
==
'in'
else
'OUTPUT'
def
get_dport_sport
(
self
):
if
self
.
direction
==
'in'
:
return
self
.
dport
,
self
.
sport
else
:
return
self
.
sport
,
self
.
dport
def
get_ipt_rules
(
self
,
host
=
None
):
def
get_ipt_rules
(
self
,
host
=
None
):
# action
# action
action
=
'LOG_ACC'
if
self
.
action
==
'accept'
else
'LOG_DROP'
action
=
'LOG_ACC'
if
self
.
action
==
'accept'
else
'LOG_DROP'
...
@@ -235,9 +229,6 @@ class Rule(models.Model):
...
@@ -235,9 +229,6 @@ class Rule(models.Model):
if
vlan
and
not
vlan
.
managed
:
if
vlan
and
not
vlan
.
managed
:
return
retval
return
retval
# src and dst ports
dport
,
sport
=
self
.
get_dport_sport
()
# process foreign vlans
# process foreign vlans
for
foreign_vlan
in
self
.
foreign_network
.
vlans
.
all
():
for
foreign_vlan
in
self
.
foreign_network
.
vlans
.
all
():
if
not
foreign_vlan
.
managed
:
if
not
foreign_vlan
.
managed
:
...
@@ -246,7 +237,7 @@ class Rule(models.Model):
...
@@ -246,7 +237,7 @@ class Rule(models.Model):
r
=
IptRule
(
priority
=
self
.
weight
,
action
=
action
,
r
=
IptRule
(
priority
=
self
.
weight
,
action
=
action
,
proto
=
self
.
proto
,
extra
=
self
.
extra
,
proto
=
self
.
proto
,
extra
=
self
.
extra
,
comment
=
'Rule #
%
s'
%
self
.
pk
,
comment
=
'Rule #
%
s'
%
self
.
pk
,
src
=
src
,
dst
=
dst
,
dport
=
dport
,
sport
=
sport
)
src
=
src
,
dst
=
dst
,
dport
=
self
.
dport
,
sport
=
self
.
sport
)
chain_name
=
self
.
get_chain_name
(
local
=
vlan
,
remote
=
foreign_vlan
)
chain_name
=
self
.
get_chain_name
(
local
=
vlan
,
remote
=
foreign_vlan
)
retval
[
chain_name
]
=
r
retval
[
chain_name
]
=
r
...
...
circle/vm/operations.py
View file @
db560b90
...
@@ -745,7 +745,7 @@ class RenewOperation(InstanceOperation):
...
@@ -745,7 +745,7 @@ class RenewOperation(InstanceOperation):
required_perms
=
()
required_perms
=
()
concurrency_check
=
False
concurrency_check
=
False
def
_operation
(
self
,
activity
,
lease
=
None
,
force
=
False
):
def
_operation
(
self
,
activity
,
lease
=
None
,
force
=
False
,
save
=
False
):
suspend
,
delete
=
self
.
instance
.
get_renew_times
(
lease
)
suspend
,
delete
=
self
.
instance
.
get_renew_times
(
lease
)
if
(
not
force
and
suspend
and
self
.
instance
.
time_of_suspend
and
if
(
not
force
and
suspend
and
self
.
instance
.
time_of_suspend
and
suspend
<
self
.
instance
.
time_of_suspend
):
suspend
<
self
.
instance
.
time_of_suspend
):
...
@@ -759,6 +759,8 @@ class RenewOperation(InstanceOperation):
...
@@ -759,6 +759,8 @@ class RenewOperation(InstanceOperation):
"in its delete time get earlier than before."
))
"in its delete time get earlier than before."
))
self
.
instance
.
time_of_suspend
=
suspend
self
.
instance
.
time_of_suspend
=
suspend
self
.
instance
.
time_of_delete
=
delete
self
.
instance
.
time_of_delete
=
delete
if
save
:
self
.
instance
.
lease
=
lease
self
.
instance
.
save
()
self
.
instance
.
save
()
activity
.
result
=
create_readable
(
ugettext_noop
(
activity
.
result
=
create_readable
(
ugettext_noop
(
"Renewed to suspend at
%(suspend)
s and destroy at
%(delete)
s."
),
"Renewed to suspend at
%(suspend)
s and destroy at
%(delete)
s."
),
...
@@ -779,9 +781,17 @@ class ChangeStateOperation(InstanceOperation):
...
@@ -779,9 +781,17 @@ class ChangeStateOperation(InstanceOperation):
"resources."
)
"resources."
)
acl_level
=
"owner"
acl_level
=
"owner"
required_perms
=
(
'vm.emergency_change_state'
,
)
required_perms
=
(
'vm.emergency_change_state'
,
)
concurrency_check
=
False
def
_operation
(
self
,
user
,
activity
,
new_state
=
"NOSTATE"
):
def
_operation
(
self
,
user
,
activity
,
new_state
=
"NOSTATE"
,
interrupt
=
False
):
activity
.
resultant_state
=
new_state
activity
.
resultant_state
=
new_state
if
interrupt
:
msg_txt
=
ugettext_noop
(
"Activity is forcibly interrupted."
)
message
=
create_readable
(
msg_txt
,
msg_txt
)
for
i
in
InstanceActivity
.
objects
.
filter
(
finished__isnull
=
True
,
instance
=
self
.
instance
):
i
.
finish
(
False
,
result
=
message
)
logger
.
error
(
'Forced finishing activity
%
s'
,
i
)
register_operation
(
ChangeStateOperation
)
register_operation
(
ChangeStateOperation
)
...
...
circle/vm/tasks/local_agent_tasks.py
View file @
db560b90
...
@@ -86,7 +86,7 @@ def agent_started(vm, version=None):
...
@@ -86,7 +86,7 @@ def agent_started(vm, version=None):
if
version
and
version
!=
settings
.
AGENT_VERSION
:
if
version
and
version
!=
settings
.
AGENT_VERSION
:
try
:
try
:
update_agent
(
vm
,
instance
,
act
)
update_agent
(
instance
,
act
)
except
TimeoutError
:
except
TimeoutError
:
pass
pass
else
:
else
:
...
@@ -134,9 +134,9 @@ def agent_stopped(vm):
...
@@ -134,9 +134,9 @@ def agent_stopped(vm):
pass
pass
def
update_agent
(
instance
,
vm
,
act
=
None
):
def
update_agent
(
instance
,
act
=
None
):
if
act
:
if
act
:
act
.
sub_activity
(
act
=
act
.
sub_activity
(
'update'
,
'update'
,
readable_name
=
create_readable
(
readable_name
=
create_readable
(
ugettext_noop
(
'update to
%(version)
s'
),
ugettext_noop
(
'update to
%(version)
s'
),
...
@@ -150,5 +150,6 @@ def update_agent(instance, vm, act=None):
...
@@ -150,5 +150,6 @@ def update_agent(instance, vm, act=None):
version
=
settings
.
AGENT_VERSION
))
version
=
settings
.
AGENT_VERSION
))
with
act
:
with
act
:
queue
=
instance
.
get_remote_queue_name
(
"agent"
)
queue
=
instance
.
get_remote_queue_name
(
"agent"
)
update
.
apply_async
(
queue
=
queue
,
update
.
apply_async
(
args
=
(
vm
,
create_agent_tar
()))
.
get
(
timeout
=
10
)
queue
=
queue
,
args
=
(
instance
.
vm_name
,
create_agent_tar
()))
.
get
(
timeout
=
10
)
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