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
cfae5fec
authored
8 years ago
by
Kálmán Viktor
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
dashboard: add disk usage breakdown pie chart
parent
ab26a51e
Show whitespace changes
Inline
Side-by-side
Showing
8 changed files
with
159 additions
and
2 deletions
+159
-2
circle/bower.json
+2
-1
circle/circle/settings/base.py
+6
-0
circle/dashboard/static/dashboard/dashboard.less
+25
-0
circle/dashboard/static/dashboard/datastore-details.js
+36
-0
circle/dashboard/templates/dashboard/storage/detail.html
+56
-1
circle/dashboard/views/storage.py
+22
-0
circle/storage/models.py
+7
-0
circle/storage/tasks/storage_tasks.py
+5
-0
No files found.
circle/bower.json
View file @
cfae5fec
...
...
@@ -20,6 +20,7 @@
"bootbox"
:
"~4.3.0"
,
"intro.js"
:
"0.9.0"
,
"favico.js"
:
"~0.3.5"
,
"datatables"
:
"~1.10.4"
"datatables"
:
"~1.10.4"
,
"chart.js"
:
"2.3.0"
}
}
This diff is collapsed.
Click to expand it.
circle/circle/settings/base.py
View file @
cfae5fec
...
...
@@ -245,6 +245,12 @@ PIPELINE_JS = {
),
"output_filename"
:
"vm-detail.js"
,
},
"datastore"
:
{
"source_filenames"
:
(
"chart.js/dist/Chart.min.js"
,
"dashboard/datastore-details.js"
),
"output_filename"
:
"datastore.js"
,
},
}
...
...
This diff is collapsed.
Click to expand it.
circle/dashboard/static/dashboard/dashboard.less
View file @
cfae5fec
...
...
@@ -1563,3 +1563,28 @@ textarea[name="new_members"] {
margin: 15px 0 2px 0;
}
}
#datastore-chart-legend {
width: 350px;
margin-top: 100px;
margin-left: -120px;
/* Landscape phones and down */
@media (max-width: 992px) {
margin-left: -25px;
}
ul {
list-style: none;
}
li {
font-size: 18px;
margin-bottom: 2px;
span {
display: inline-block;
width: 30px;
height: 18px;
margin-right: 8px;
}
}
}
This diff is collapsed.
Click to expand it.
circle/dashboard/static/dashboard/datastore-details.js
0 → 100644
View file @
cfae5fec
$
(
function
()
{
var
data
=
JSON
.
parse
(
$
(
"#chart-data"
).
data
(
"data"
));
var
labels
=
[];
for
(
var
i
=
0
;
i
<
data
.
labels
.
length
;
i
++
)
{
labels
.
push
(
data
.
labels
[
i
]
+
" ("
+
data
.
readable_data
[
i
]
+
")"
);
}
var
pieChart
=
new
Chart
(
document
.
getElementById
(
"datastore-chart"
),
{
type
:
'pie'
,
data
:
{
labels
:
labels
,
datasets
:
[{
data
:
data
[
'data'
],
backgroundColor
:
[
"#57b257"
,
"#538ccc"
,
"#f0df24"
,
"#ff9a38"
,
"#7f7f7f"
,
]
}]
},
options
:
{
legend
:
{
display
:
false
,
},
tooltips
:
{
callbacks
:
{
label
:
function
(
item
,
chartData
)
{
return
data
[
'labels'
][
item
.
index
]
+
": "
+
data
[
'readable_data'
][
item
.
index
];
}
}
},
}
});
$
(
"#datastore-chart-legend"
).
html
(
pieChart
.
generateLegend
());
});
This diff is collapsed.
Click to expand it.
circle/dashboard/templates/dashboard/storage/detail.html
View file @
cfae5fec
{% extends "dashboard/base.html" %}
{% load staticfiles %}
{% load pipeline %}
{% load sizefieldtags %}
{% load i18n %}
{% load render_table from django_tables2 %}
{% load crispy_forms_tags %}
...
...
@@ -105,4 +106,58 @@
</div>
</div>
<div
class=
"row"
>
<div
class=
"col-md-12"
>
<div
class=
"panel panel-default"
>
<div
class=
"panel-heading"
>
<h3
class=
"no-margin"
>
<i
class=
"fa fa-pie-chart"
></i>
{% trans "Disk usage breakdown" %}
</h3>
</div>
<div
class=
"panel-body"
>
<div
class=
"row"
>
<div
class=
"col-md-9"
>
<canvas
id=
"datastore-chart"
></canvas>
</div>
<div
class=
"col-md-3"
>
<div
id=
"datastore-chart-legend"
></div>
</div>
</div>
<div
id=
"chart-data"
data-data=
'{
"data": [{{stats.template_actual_size}},
{{stats.vm_actual_size}},
{{stats.dumps}},
{{stats.iso_raw}},
{{stats.trash}}],
"readable_data": ["{{stats.template_actual_size|filesize}}",
"{{stats.vm_actual_size|filesize}}",
"{{stats.dumps|filesize}}",
"{{stats.dumps|filesize}}",
"{{stats.iso_raw|filesize}}",
"{{stats.trash|filesize}}"],
"labels": ["{% trans "Templates" %}",
"{% trans "Virtual machines" %}",
"{% trans "Memory dumps" %}",
"{% trans "ISO + Raw images" %}",
"{% trans "Trash" %}"]
}
'
>
</div>
<div>
{% trans "Total virtual machine disk usage" %}:
<strong>
{{ stats.vm_actual_size|filesize }}
</strong>
<br
/>
{% trans "Actual virtual machine disk usage" %}:
<strong>
{{ stats.vm_size|filesize}}
</strong>
</div>
</div>
<!-- .panel-body -->
</div>
</div>
</div>
{% endblock %}
{% block extra_js %}
{% javascript "datastore" %}
{% endblock %}
This diff is collapsed.
Click to expand it.
circle/dashboard/views/storage.py
View file @
cfae5fec
...
...
@@ -91,6 +91,7 @@ class StorageDetail(SuperuserRequiredMixin, UpdateView):
return
qs
def
_get_stats
(
self
):
# datastore stats
stats
=
self
.
object
.
get_statistics
()
free_space
=
int
(
stats
[
'free_space'
])
free_percent
=
float
(
stats
[
'free_percent'
])
...
...
@@ -98,11 +99,32 @@ class StorageDetail(SuperuserRequiredMixin, UpdateView):
total_space
=
free_space
/
(
free_percent
/
100.0
)
used_space
=
total_space
-
free_space
# file stats
data
=
self
.
get_object
()
.
get_file_statistics
()
dumps_size
=
sum
(
d
[
'size'
]
for
d
in
data
[
'dumps'
])
trash
=
sum
(
d
[
'size'
]
for
d
in
data
[
'trash'
])
iso_raw
=
sum
(
d
[
'size'
]
for
d
in
data
[
'disks'
]
if
d
[
'format'
]
in
(
"iso"
,
"raw"
))
vm_size
=
vm_actual_size
=
template_actual_size
=
0
for
d
in
data
[
'disks'
]:
if
d
[
'format'
]
==
"qcow2"
and
d
[
'type'
]
==
"normal"
:
template_actual_size
+=
d
[
'actual_size'
]
else
:
vm_size
+=
d
[
'size'
]
vm_actual_size
+=
d
[
'actual_size'
]
return
{
'used_percent'
:
int
(
100
-
free_percent
),
'free_space'
:
filesizeformat
(
free_space
),
'used_space'
:
filesizeformat
(
used_space
),
'total_space'
:
filesizeformat
(
total_space
),
'dumps'
:
dumps_size
,
'trash'
:
trash
,
'iso_raw'
:
iso_raw
,
'vm_size'
:
vm_size
,
'vm_actual_size'
:
vm_actual_size
,
'template_actual_size'
:
template_actual_size
,
}
def
get_success_url
(
self
):
...
...
This diff is collapsed.
Click to expand it.
circle/storage/models.py
View file @
cfae5fec
...
...
@@ -110,6 +110,13 @@ class DataStore(Model):
disks
=
Disk
.
objects
.
filter
(
destroyed__isnull
=
True
,
is_ready
=
True
)
return
disks
.
exclude
(
filename__in
=
files
)
@method_cache
(
30
)
def
get_file_statistics
(
self
,
timeout
=
15
):
queue_name
=
self
.
get_remote_queue_name
(
'storage'
,
"slow"
)
data
=
storage_tasks
.
get_file_statistics
.
apply_async
(
args
=
[
self
.
path
],
queue
=
queue_name
)
.
get
(
timeout
=
timeout
)
return
data
class
Disk
(
TimeStampedModel
):
...
...
This diff is collapsed.
Click to expand it.
circle/storage/tasks/storage_tasks.py
View file @
cfae5fec
...
...
@@ -81,3 +81,8 @@ def recover_from_trash(datastore, disk_path):
@celery.task
(
name
=
'storagedriver.get_storage_stat'
)
def
get_storage_stat
(
path
):
pass
@celery.task
(
name
=
'storagedriver.get_file_statistics'
)
def
get_file_statistics
(
datastore
):
pass
This diff is collapsed.
Click to expand it.
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