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
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
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):
else
:
return
code
def
get_status_id
(
self
):
if
self
.
succeeded
is
None
:
return
'wait'
elif
self
.
succeeded
:
return
'success'
else
:
return
'failed'
@celery.task
()
def
compute_cached
(
method
,
instance
,
memcached_seconds
,
...
...
circle/dashboard/templates/dashboard/node-detail/_activity-timeline.html
View file @
8540bead
...
...
@@ -5,10 +5,11 @@
{% for a in activities %}
<div
class=
"activity"
data-activity-id=
"{{ a.pk }}"
>
<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>
<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>
<span
title=
"{{ a.started }}"
>
{{ a.started|arrowfilter:LANGUAGE_CODE }}
</span>
{% if a.user %}, {{ a.user }}{% endif %}
...
...
@@ -19,7 +20,8 @@
<div
data-activity-id=
"{{ s.pk }}"
class=
"sub-activity{% if s.has_failed %} sub-activity-failed{% endif %}"
>
<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>
–
{% 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 (
GroupDetailView
,
GroupList
,
IndexView
,
InstanceActivityDetail
,
LeaseCreate
,
LeaseDelete
,
LeaseDetail
,
MyPreferencesView
,
NodeAddTraitView
,
NodeCreate
,
NodeDelete
,
NodeDetailView
,
NodeList
,
NodeDetailView
,
NodeList
,
NodeActivityDetail
,
NotificationView
,
TemplateAclUpdateView
,
TemplateCreate
,
TemplateDelete
,
TemplateDetail
,
TemplateList
,
vm_activity
,
VmCreate
,
VmDetailView
,
...
...
@@ -133,6 +133,8 @@ urlpatterns = patterns(
name
=
'dashboard.views.node-activity-list'
),
url
(
r'^node/create/$'
,
NodeCreate
.
as_view
(),
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
(),
name
=
'dashboard.views.favourite'
),
...
...
circle/dashboard/views/node.py
View file @
8540bead
...
...
@@ -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
,
GraphMixin
,
DetailView
):
template_name
=
"dashboard/node-detail.html"
...
...
@@ -104,7 +118,7 @@ class NodeDetailView(LoginRequiredMixin,
context
[
'ops'
]
=
get_operations
(
self
.
object
,
self
.
request
.
user
)
context
[
'op'
]
=
{
i
.
op
:
i
for
i
in
context
[
'ops'
]}
context
[
'show_show_all'
]
=
len
(
na
)
>
10
context
[
'activities'
]
=
na
[:
10
]
context
[
'activities'
]
=
_format_activities
(
na
[:
10
])
context
[
'trait_form'
]
=
form
context
[
'graphite_enabled'
]
=
(
settings
.
GRAPHITE_URL
is
not
None
)
...
...
@@ -306,8 +320,8 @@ class NodeActivityView(LoginRequiredMixin, SuperuserRequiredMixin, View):
show_all
=
request
.
GET
.
get
(
"show_all"
,
"false"
)
==
"true"
node
=
Node
.
objects
.
get
(
pk
=
pk
)
activities
=
NodeActivity
.
objects
.
filter
(
node
=
node
,
parent
=
None
)
.
order_by
(
'-started'
)
.
select_related
()
activities
=
_format_activities
(
NodeActivity
.
objects
.
filter
(
node
=
node
,
parent
=
None
)
.
order_by
(
'-started'
)
.
select_related
()
)
show_show_all
=
len
(
activities
)
>
10
if
not
show_all
:
...
...
@@ -324,3 +338,18 @@ class NodeActivityView(LoginRequiredMixin, SuperuserRequiredMixin, View):
json
.
dumps
(
response
),
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):
def
get_absolute_url
(
self
):
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
):
op
=
self
.
instance
.
get_operation_from_activity_code
(
self
.
activity_code
)
return
(
self
.
task_uuid
and
op
and
op
.
has_percentage
and
...
...
@@ -215,6 +207,13 @@ class NodeActivity(ActivityModel):
app_label
=
'vm'
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
):
if
self
.
parent
:
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