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
Commit
8540bead
authored
Jul 05, 2016
by
Kálmán Viktor
Browse files
Options
Browse Files
Download
Plain Diff
Merge branch 'feature-node-pimp' into 'master'
Feature node pimp See merge request
!377
parents
5ea451a2
871de94e
Pipeline
#121
passed with stage
in 0 seconds
Changes
6
Pipelines
1
Hide whitespace changes
Inline
Side-by-side
Showing
6 changed files
with
138 additions
and
15 deletions
+138
-15
circle/common/models.py
+8
-0
circle/dashboard/templates/dashboard/node-detail/_activity-timeline.html
+5
-3
circle/dashboard/templates/dashboard/nodeactivity_detail.html
+83
-0
circle/dashboard/urls.py
+3
-1
circle/dashboard/views/node.py
+32
-3
circle/vm/models/activity.py
+7
-8
No files found.
circle/common/models.py
View file @
8540bead
...
@@ -232,6 +232,14 @@ class ActivityModel(TimeStampedModel):
...
@@ -232,6 +232,14 @@ class ActivityModel(TimeStampedModel):
else
:
else
:
return
code
return
code
def
get_status_id
(
self
):
if
self
.
succeeded
is
None
:
return
'wait'
elif
self
.
succeeded
:
return
'success'
else
:
return
'failed'
@celery.task
()
@celery.task
()
def
compute_cached
(
method
,
instance
,
memcached_seconds
,
def
compute_cached
(
method
,
instance
,
memcached_seconds
,
...
...
circle/dashboard/templates/dashboard/node-detail/_activity-timeline.html
View file @
8540bead
...
@@ -5,10 +5,11 @@
...
@@ -5,10 +5,11 @@
{% for a in activities %}
{% for a in activities %}
<div
class=
"activity"
data-activity-id=
"{{ a.pk }}"
>
<div
class=
"activity"
data-activity-id=
"{{ a.pk }}"
>
<span
class=
"timeline-icon{% if a.has_failed %} timeline-icon-failed{% endif %}"
>
<span
class=
"timeline-icon{% if a.has_failed %} timeline-icon-failed{% endif %}"
>
<i
class=
"fa {% if not a.finished %}fa-refresh fa-spin {% else %}fa-
plus
{% endif %}"
></i>
<i
class=
"fa {% if not a.finished %}fa-refresh fa-spin {% else %}fa-
{{a.icon}}
{% endif %}"
></i>
</span>
</span>
<strong
title=
"{{ a.result.get_admin_text }}"
>
<strong
title=
"{{ a.result.get_admin_text }}"
>
{{ a.readable_name.get_admin_text|capfirst }}
<a
href=
"{{ a.get_absolute_url }}"
>
{{ a.readable_name.get_admin_text|capfirst }}
</a>
</strong>
</strong>
<span
title=
"{{ a.started }}"
>
{{ a.started|arrowfilter:LANGUAGE_CODE }}
</span>
{% if a.user %}, {{ a.user }}{% endif %}
<span
title=
"{{ a.started }}"
>
{{ a.started|arrowfilter:LANGUAGE_CODE }}
</span>
{% if a.user %}, {{ a.user }}{% endif %}
...
@@ -19,7 +20,8 @@
...
@@ -19,7 +20,8 @@
<div
data-activity-id=
"{{ s.pk }}"
<div
data-activity-id=
"{{ s.pk }}"
class=
"sub-activity{% if s.has_failed %} sub-activity-failed{% endif %}"
>
class=
"sub-activity{% if s.has_failed %} sub-activity-failed{% endif %}"
>
<span
title=
"{{ s.result.get_admin_text }}"
>
<span
title=
"{{ s.result.get_admin_text }}"
>
{{ s.readable_name|get_text:user }}
<a
href=
"{{ s.get_absolute_url }}"
>
{{ s.readable_name|get_text:user }}
</a>
</span>
</span>
–
–
{% if s.finished %}
{% if s.finished %}
...
...
circle/dashboard/templates/dashboard/nodeactivity_detail.html
0 → 100644
View file @
8540bead
{% extends "dashboard/base.html" %}
{% load i18n %}
{% load hro %}
{% block content %}
<div
class=
"body-content"
>
<div
class=
"page-header"
>
<h1>
<div
class=
"pull-right"
id=
"vm-activity-state"
>
<span
class=
"label label-{% if object.get_status_id == 'wait' %}info{% else %}{% if object.succeeded %}success{% else %}danger{% endif %}{% endif %}"
>
<span>
{{ object.get_status_id|upper }}
</span>
</span>
</div>
<i
class=
"fa fa-{{icon}}"
></i>
{{ object.node.name }}: {{object.readable_name|get_text:user}}
</h1>
</div>
<div
class=
"row"
>
<div
class=
"col-md-6"
id=
"vm-info-pane"
>
{% include "dashboard/vm-detail/_activity-timeline.html" with active=object %}
</div>
<div
class=
"col-md-6"
>
<div
class=
"panel panel-default"
>
<div
class=
"panel-body"
>
<dl>
<dt>
{% trans "activity code" %}
</dt>
<dd>
{{object.activity_code}}
</dd>
<dt>
{% trans "node" %}
</dt>
<dd><a
href=
"{{object.node.get_absolute_url}}"
>
{{object.node}}
</a></dd>
<dt>
{% trans "time" %}
</dt>
<dd>
{{object.started|default:'n/a'}} → {{object.finished|default:'n/a'}}
</dd>
<dt>
{% trans "user" %}
</dt>
<dd>
<a
href=
"{{ object.user.profile.get_absolute_url }}"
>
{{object.user|default:'(system)'}}
</a></dd>
<dt>
{% trans "type" %}
</dt>
<dd>
{% if object.parent %}
{% blocktrans with url=object.parent.get_absolute_url name=object.parent %}
subactivity of
<a
href=
"{{url}}"
>
{{name}}
</a>
{% endblocktrans %}
{% else %}{% trans "top level activity" %}{% endif %}
</dd>
<dt>
{% trans "task uuid" %}
</dt>
<dd>
{{ object.task_uuid|default:'n/a' }}
</dd>
<dt>
{% trans "status" %}
</dt>
<dd
id=
"activity_status"
>
{{ object.get_status_id }}
</dd>
<dt>
{% trans "result" %}
</dt>
<dd><textarea
class=
"form-control"
id=
"activity_result_text"
>
{{object.result|get_text:user}}
</textarea></dd>
<dt>
{% trans "subactivities" %}
</dt>
{% for s in object.children.all %}
<dd>
<span
{%
if
s
.
result
%}
title=
"{{ s.result|get_text:user }}"
{%
endif
%}
>
<a
href=
"{{ s.get_absolute_url }}"
>
{{ s.readable_name|get_text:user|capfirst }}
</a></span>
–
{% if s.finished %}
{{ s.finished|time:"H:i:s" }}
{% else %}
<i
class=
"fa fa-refresh fa-spin"
class=
"sub-activity-loading-icon"
></i>
{% endif %}
{% if s.has_failed %}
<div
class=
"label label-danger"
>
{% trans "failed" %}
</div>
{% endif %}
</dd>
{% empty %}
<dd>
{% trans "none" %}
</dd>
{% endfor %}
</div>
</div>
</div>
</div>
</div>
</div>
{% endblock %}
circle/dashboard/urls.py
View file @
8540bead
...
@@ -25,7 +25,7 @@ from .views import (
...
@@ -25,7 +25,7 @@ from .views import (
GroupDetailView
,
GroupList
,
IndexView
,
GroupDetailView
,
GroupList
,
IndexView
,
InstanceActivityDetail
,
LeaseCreate
,
LeaseDelete
,
LeaseDetail
,
InstanceActivityDetail
,
LeaseCreate
,
LeaseDelete
,
LeaseDetail
,
MyPreferencesView
,
NodeAddTraitView
,
NodeCreate
,
NodeDelete
,
MyPreferencesView
,
NodeAddTraitView
,
NodeCreate
,
NodeDelete
,
NodeDetailView
,
NodeList
,
NodeDetailView
,
NodeList
,
NodeActivityDetail
,
NotificationView
,
TemplateAclUpdateView
,
TemplateCreate
,
NotificationView
,
TemplateAclUpdateView
,
TemplateCreate
,
TemplateDelete
,
TemplateDetail
,
TemplateList
,
TemplateDelete
,
TemplateDetail
,
TemplateList
,
vm_activity
,
VmCreate
,
VmDetailView
,
vm_activity
,
VmCreate
,
VmDetailView
,
...
@@ -133,6 +133,8 @@ urlpatterns = patterns(
...
@@ -133,6 +133,8 @@ urlpatterns = patterns(
name
=
'dashboard.views.node-activity-list'
),
name
=
'dashboard.views.node-activity-list'
),
url
(
r'^node/create/$'
,
NodeCreate
.
as_view
(),
url
(
r'^node/create/$'
,
NodeCreate
.
as_view
(),
name
=
'dashboard.views.node-create'
),
name
=
'dashboard.views.node-create'
),
url
(
r'^node/activity/(?P<pk>\d+)/$'
,
NodeActivityDetail
.
as_view
(),
name
=
'dashboard.views.node-activity'
),
url
(
r'^favourite/$'
,
FavouriteView
.
as_view
(),
url
(
r'^favourite/$'
,
FavouriteView
.
as_view
(),
name
=
'dashboard.views.favourite'
),
name
=
'dashboard.views.favourite'
),
...
...
circle/dashboard/views/node.py
View file @
8540bead
...
@@ -82,6 +82,20 @@ node_ops = OrderedDict([
...
@@ -82,6 +82,20 @@ node_ops = OrderedDict([
])
])
def
_get_activity_icon
(
act
):
op
=
act
.
get_operation
()
if
op
and
op
.
id
in
node_ops
:
return
node_ops
[
op
.
id
]
.
icon
else
:
return
"cog"
def
_format_activities
(
acts
):
for
i
in
acts
:
i
.
icon
=
_get_activity_icon
(
i
)
return
acts
class
NodeDetailView
(
LoginRequiredMixin
,
class
NodeDetailView
(
LoginRequiredMixin
,
GraphMixin
,
DetailView
):
GraphMixin
,
DetailView
):
template_name
=
"dashboard/node-detail.html"
template_name
=
"dashboard/node-detail.html"
...
@@ -104,7 +118,7 @@ class NodeDetailView(LoginRequiredMixin,
...
@@ -104,7 +118,7 @@ class NodeDetailView(LoginRequiredMixin,
context
[
'ops'
]
=
get_operations
(
self
.
object
,
self
.
request
.
user
)
context
[
'ops'
]
=
get_operations
(
self
.
object
,
self
.
request
.
user
)
context
[
'op'
]
=
{
i
.
op
:
i
for
i
in
context
[
'ops'
]}
context
[
'op'
]
=
{
i
.
op
:
i
for
i
in
context
[
'ops'
]}
context
[
'show_show_all'
]
=
len
(
na
)
>
10
context
[
'show_show_all'
]
=
len
(
na
)
>
10
context
[
'activities'
]
=
na
[:
10
]
context
[
'activities'
]
=
_format_activities
(
na
[:
10
])
context
[
'trait_form'
]
=
form
context
[
'trait_form'
]
=
form
context
[
'graphite_enabled'
]
=
(
context
[
'graphite_enabled'
]
=
(
settings
.
GRAPHITE_URL
is
not
None
)
settings
.
GRAPHITE_URL
is
not
None
)
...
@@ -306,8 +320,8 @@ class NodeActivityView(LoginRequiredMixin, SuperuserRequiredMixin, View):
...
@@ -306,8 +320,8 @@ class NodeActivityView(LoginRequiredMixin, SuperuserRequiredMixin, View):
show_all
=
request
.
GET
.
get
(
"show_all"
,
"false"
)
==
"true"
show_all
=
request
.
GET
.
get
(
"show_all"
,
"false"
)
==
"true"
node
=
Node
.
objects
.
get
(
pk
=
pk
)
node
=
Node
.
objects
.
get
(
pk
=
pk
)
activities
=
NodeActivity
.
objects
.
filter
(
activities
=
_format_activities
(
NodeActivity
.
objects
.
filter
(
node
=
node
,
parent
=
None
)
.
order_by
(
'-started'
)
.
select_related
()
node
=
node
,
parent
=
None
)
.
order_by
(
'-started'
)
.
select_related
()
)
show_show_all
=
len
(
activities
)
>
10
show_show_all
=
len
(
activities
)
>
10
if
not
show_all
:
if
not
show_all
:
...
@@ -324,3 +338,18 @@ class NodeActivityView(LoginRequiredMixin, SuperuserRequiredMixin, View):
...
@@ -324,3 +338,18 @@ class NodeActivityView(LoginRequiredMixin, SuperuserRequiredMixin, View):
json
.
dumps
(
response
),
json
.
dumps
(
response
),
content_type
=
"application/json"
content_type
=
"application/json"
)
)
class
NodeActivityDetail
(
LoginRequiredMixin
,
SuperuserRequiredMixin
,
DetailView
):
model
=
NodeActivity
context_object_name
=
'nodeactivity'
# much simpler to mock object
template_name
=
'dashboard/nodeactivity_detail.html'
def
get_context_data
(
self
,
**
kwargs
):
ctx
=
super
(
NodeActivityDetail
,
self
)
.
get_context_data
(
**
kwargs
)
ctx
[
'activities'
]
=
_format_activities
(
NodeActivity
.
objects
.
filter
(
node
=
self
.
object
.
node
,
parent
=
None
)
.
order_by
(
'-started'
)
.
select_related
())
ctx
[
'icon'
]
=
_get_activity_icon
(
self
.
object
)
return
ctx
circle/vm/models/activity.py
View file @
8540bead
...
@@ -135,14 +135,6 @@ class InstanceActivity(ActivityModel):
...
@@ -135,14 +135,6 @@ class InstanceActivity(ActivityModel):
def
get_absolute_url
(
self
):
def
get_absolute_url
(
self
):
return
reverse
(
'dashboard.views.vm-activity'
,
args
=
[
self
.
pk
])
return
reverse
(
'dashboard.views.vm-activity'
,
args
=
[
self
.
pk
])
def
get_status_id
(
self
):
if
self
.
succeeded
is
None
:
return
'wait'
elif
self
.
succeeded
:
return
'success'
else
:
return
'failed'
def
has_percentage
(
self
):
def
has_percentage
(
self
):
op
=
self
.
instance
.
get_operation_from_activity_code
(
self
.
activity_code
)
op
=
self
.
instance
.
get_operation_from_activity_code
(
self
.
activity_code
)
return
(
self
.
task_uuid
and
op
and
op
.
has_percentage
and
return
(
self
.
task_uuid
and
op
and
op
.
has_percentage
and
...
@@ -215,6 +207,13 @@ class NodeActivity(ActivityModel):
...
@@ -215,6 +207,13 @@ class NodeActivity(ActivityModel):
app_label
=
'vm'
app_label
=
'vm'
db_table
=
'vm_nodeactivity'
db_table
=
'vm_nodeactivity'
def
get_operation
(
self
):
return
self
.
node
.
get_operation_from_activity_code
(
self
.
activity_code
)
def
get_absolute_url
(
self
):
return
reverse
(
'dashboard.views.node-activity'
,
args
=
[
self
.
pk
])
def
__unicode__
(
self
):
def
__unicode__
(
self
):
if
self
.
parent
:
if
self
.
parent
:
return
'{}({})->{}'
.
format
(
self
.
parent
.
activity_code
,
return
'{}({})->{}'
.
format
(
self
.
parent
.
activity_code
,
...
...
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