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
a71972e7
authored
Jun 04, 2014
by
Bach Dániel
Browse files
Options
Browse Files
Download
Plain Diff
Merge branch 'feature-screenshot'
Conflicts: circle/dashboard/urls.py
parents
c6347434
5abed6d9
Show whitespace changes
Inline
Side-by-side
Showing
7 changed files
with
86 additions
and
18 deletions
+86
-18
circle/dashboard/static/dashboard/dashboard.css
+9
-0
circle/dashboard/static/dashboard/vm-details.js
+25
-0
circle/dashboard/templates/dashboard/vm-detail/console.html
+10
-2
circle/dashboard/urls.py
+3
-0
circle/dashboard/views.py
+14
-16
circle/vm/models/instance.py
+6
-0
circle/vm/operations.py
+19
-0
No files found.
circle/dashboard/static/dashboard/dashboard.css
View file @
a71972e7
...
...
@@ -654,3 +654,12 @@ textarea[name="list-new-namelist"] {
80
%
{
-webkit-transform
:
scale
(
1
);
}
100
%
{
-webkit-transform
:
scale
(
1
);
}
}
.btn-toolbar
{
margin-bottom
:
5px
;
}
#vm-console-screenshot
{
display
:
none
;
}
circle/dashboard/static/dashboard/vm-details.js
View file @
a71972e7
...
...
@@ -264,6 +264,31 @@ $(function() {
return
false
;
});
// screenshot
$
(
"#getScreenshotButton"
).
click
(
function
()
{
var
vm
=
$
(
this
).
data
(
"vm-pk"
);
var
ct
=
$
(
"#vm-console-screenshot"
);
$
(
"i"
,
this
).
addClass
(
"icon-spinner icon-spin"
);
$
(
this
).
prop
(
"disabled"
,
true
);
ct
.
slideDown
();
var
img
=
$
(
"img"
,
ct
).
prop
(
"src"
,
'/dashboard/vm/'
+
vm
+
'/screenshot/'
);
});
// if the image is loaded remove the spinning stuff
// note: this should not work if the image is cached, but it's not
// see: http://stackoverflow.com/a/3877079/1112653
$
(
"#vm-console-screenshot img"
).
load
(
function
(
e
)
{
$
(
"#getScreenshotButton"
).
prop
(
"disabled"
,
false
)
.
find
(
"i"
).
removeClass
(
"icon-spinner icon-spin"
);
});
// screenshot close
$
(
"#vm-console-screenshot button"
).
click
(
function
()
{
$
(
this
).
parent
(
"div"
).
slideUp
();
});
});
...
...
circle/dashboard/templates/dashboard/vm-detail/console.html
View file @
a71972e7
{% load i18n %}
<div
class=
"btn-toolbar"
>
<button
id=
"sendCtrlAltDelButton"
class=
"btn btn-danger small"
>
{% trans "Send Ctrl+Alt+Del" %}
</button>
<button
id=
"sendPasswordButton"
class=
"btn btn-default small"
>
{% trans "Type password" %}
</button>
<button
id=
"sendCtrlAltDelButton"
class=
"btn btn-danger btn-sm"
>
{% trans "Send Ctrl+Alt+Del" %}
</button>
<button
id=
"sendPasswordButton"
class=
"btn btn-default btn-sm"
>
{% trans "Type password" %}
</button>
<button
id=
"getScreenshotButton"
class=
"btn btn-info btn-sm pull-right"
data-vm-pk=
"{{ instance.pk }}"
><i
class=
"icon-picture"
></i>
{% trans "Screenshot" %}
</button>
</div>
<div
class=
"alert alert-info"
id=
"noVNC_status"
>
</div>
<div
id=
"vm-console-screenshot"
>
<button
class=
"btn btn-danger btn-sm pull-right"
>
{% trans "Close" %}
</button>
<h3>
{% trans "Screenshot" %}
</h3>
<img
/>
<hr
/>
</div>
<canvas
id=
"noVNC_canvas"
width=
"640px"
height=
"20px"
>
Canvas not supported.
</canvas>
...
...
circle/dashboard/urls.py
View file @
a71972e7
...
...
@@ -34,6 +34,7 @@ from .views import (
GroupCreate
,
TemplateChoose
,
UserCreationView
,
get_vm_screenshot
)
urlpatterns
=
patterns
(
...
...
@@ -84,6 +85,8 @@ urlpatterns = patterns(
name
=
'dashboard.views.vm-renew'
),
url
(
r'^vm/activity/(?P<pk>\d+)/$'
,
InstanceActivityDetail
.
as_view
(),
name
=
'dashboard.views.vm-activity'
),
url
(
r'^vm/(?P<pk>\d+)/screenshot/$'
,
get_vm_screenshot
,
name
=
'dashboard.views.vm-get-screenshot'
),
url
(
r'^node/list/$'
,
NodeList
.
as_view
(),
name
=
'dashboard.views.node-list'
),
url
(
r'^node/(?P<pk>\d+)/$'
,
NodeDetailView
.
as_view
(),
...
...
circle/dashboard/views.py
View file @
a71972e7
...
...
@@ -1496,14 +1496,6 @@ class NodeCreate(LoginRequiredMixin, SuperuserRequiredMixin, TemplateView):
})
return
self
.
render_to_response
(
context
)
def
get_context_data
(
self
,
**
kwargs
):
context
=
super
(
NodeCreate
,
self
)
.
get_context_data
(
**
kwargs
)
# TODO acl
context
.
update
({
})
return
context
# TODO handle not ajax posts
def
post
(
self
,
request
,
*
args
,
**
kwargs
):
if
not
self
.
request
.
user
.
is_authenticated
():
...
...
@@ -1594,8 +1586,7 @@ class VmDelete(LoginRequiredMixin, DeleteView):
object
=
self
.
get_object
()
if
not
object
.
has_level
(
self
.
request
.
user
,
'owner'
):
raise
PermissionDenied
()
# this is redundant now, but if we wanna add more to print
# we'll need this
context
=
super
(
VmDelete
,
self
)
.
get_context_data
(
**
kwargs
)
return
context
...
...
@@ -1634,12 +1625,6 @@ class NodeDelete(LoginRequiredMixin, SuperuserRequiredMixin, DeleteView):
else
:
return
[
'dashboard/confirm/base-delete.html'
]
def
get_context_data
(
self
,
**
kwargs
):
# this is redundant now, but if we wanna add more to print
# we'll need this
context
=
super
(
NodeDelete
,
self
)
.
get_context_data
(
**
kwargs
)
return
context
# github.com/django/django/blob/master/django/views/generic/edit.py#L245
def
delete
(
self
,
request
,
*
args
,
**
kwargs
):
object
=
self
.
get_object
()
...
...
@@ -2650,3 +2635,16 @@ class InterfaceDeleteView(DeleteView):
if
redirect
:
return
redirect
self
.
object
.
instance
.
get_absolute_url
()
@require_GET
def
get_vm_screenshot
(
request
,
pk
):
instance
=
get_object_or_404
(
Instance
,
pk
=
pk
)
try
:
image
=
instance
.
screenshot
(
instance
=
instance
,
user
=
request
.
user
)
.
getvalue
()
except
:
# TODO handle this better
raise
Http404
()
return
HttpResponse
(
image
,
mimetype
=
"image/png"
)
circle/vm/models/instance.py
View file @
a71972e7
...
...
@@ -915,3 +915,9 @@ class Instance(AclBase, VirtualMachineDescModel, StatusModel, OperatedMixin,
i
.
is_abortable_for_user
=
partial
(
i
.
is_abortable_for
,
user
=
user
)
return
acts
def
get_screenshot
(
self
,
timeout
=
5
):
queue_name
=
self
.
get_remote_queue_name
(
'vm'
)
return
vm_tasks
.
screenshot
.
apply_async
(
args
=
[
self
.
vm_name
],
queue
=
queue_name
)
.
get
(
timeout
=
timeout
)
circle/vm/operations.py
View file @
a71972e7
...
...
@@ -543,3 +543,22 @@ class FlushOperation(NodeOperation):
register_operation
(
FlushOperation
)
class
ScreenshotOperation
(
InstanceOperation
):
activity_code_suffix
=
'screenshot'
id
=
'screenshot'
name
=
_
(
"screenshot"
)
description
=
_
(
"Get screenshot"
)
acl_level
=
"owner"
def
check_precond
(
self
):
super
(
ScreenshotOperation
,
self
)
.
check_precond
()
if
self
.
instance
.
status
not
in
[
'RUNNING'
]:
raise
self
.
instance
.
WrongStateError
(
self
.
instance
)
def
_operation
(
self
,
instance
,
user
):
return
self
.
instance
.
get_screenshot
(
timeout
=
20
)
register_operation
(
ScreenshotOperation
)
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