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
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"] {
...
@@ -654,3 +654,12 @@ textarea[name="list-new-namelist"] {
80
%
{
-webkit-transform
:
scale
(
1
);
}
80
%
{
-webkit-transform
:
scale
(
1
);
}
100
%
{
-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() {
...
@@ -264,6 +264,31 @@ $(function() {
return
false
;
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 %}
{% load i18n %}
<div
class=
"btn-toolbar"
>
<div
class=
"btn-toolbar"
>
<button
id=
"sendCtrlAltDelButton"
class=
"btn btn-danger small"
>
{% trans "Send Ctrl+Alt+Del" %}
</button>
<button
id=
"sendCtrlAltDelButton"
class=
"btn btn-danger btn-sm"
>
{% trans "Send Ctrl+Alt+Del" %}
</button>
<button
id=
"sendPasswordButton"
class=
"btn btn-default small"
>
{% trans "Type password" %}
</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>
<div
class=
"alert alert-info"
id=
"noVNC_status"
>
<div
class=
"alert alert-info"
id=
"noVNC_status"
>
</div>
</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
id=
"noVNC_canvas"
width=
"640px"
height=
"20px"
>
Canvas not supported.
</canvas>
</canvas>
...
...
circle/dashboard/urls.py
View file @
a71972e7
...
@@ -34,6 +34,7 @@ from .views import (
...
@@ -34,6 +34,7 @@ from .views import (
GroupCreate
,
GroupCreate
,
TemplateChoose
,
TemplateChoose
,
UserCreationView
,
UserCreationView
,
get_vm_screenshot
)
)
urlpatterns
=
patterns
(
urlpatterns
=
patterns
(
...
@@ -84,6 +85,8 @@ urlpatterns = patterns(
...
@@ -84,6 +85,8 @@ urlpatterns = patterns(
name
=
'dashboard.views.vm-renew'
),
name
=
'dashboard.views.vm-renew'
),
url
(
r'^vm/activity/(?P<pk>\d+)/$'
,
InstanceActivityDetail
.
as_view
(),
url
(
r'^vm/activity/(?P<pk>\d+)/$'
,
InstanceActivityDetail
.
as_view
(),
name
=
'dashboard.views.vm-activity'
),
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/list/$'
,
NodeList
.
as_view
(),
name
=
'dashboard.views.node-list'
),
url
(
r'^node/(?P<pk>\d+)/$'
,
NodeDetailView
.
as_view
(),
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):
...
@@ -1496,14 +1496,6 @@ class NodeCreate(LoginRequiredMixin, SuperuserRequiredMixin, TemplateView):
})
})
return
self
.
render_to_response
(
context
)
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
# TODO handle not ajax posts
def
post
(
self
,
request
,
*
args
,
**
kwargs
):
def
post
(
self
,
request
,
*
args
,
**
kwargs
):
if
not
self
.
request
.
user
.
is_authenticated
():
if
not
self
.
request
.
user
.
is_authenticated
():
...
@@ -1594,8 +1586,7 @@ class VmDelete(LoginRequiredMixin, DeleteView):
...
@@ -1594,8 +1586,7 @@ class VmDelete(LoginRequiredMixin, DeleteView):
object
=
self
.
get_object
()
object
=
self
.
get_object
()
if
not
object
.
has_level
(
self
.
request
.
user
,
'owner'
):
if
not
object
.
has_level
(
self
.
request
.
user
,
'owner'
):
raise
PermissionDenied
()
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
)
context
=
super
(
VmDelete
,
self
)
.
get_context_data
(
**
kwargs
)
return
context
return
context
...
@@ -1634,12 +1625,6 @@ class NodeDelete(LoginRequiredMixin, SuperuserRequiredMixin, DeleteView):
...
@@ -1634,12 +1625,6 @@ class NodeDelete(LoginRequiredMixin, SuperuserRequiredMixin, DeleteView):
else
:
else
:
return
[
'dashboard/confirm/base-delete.html'
]
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
# github.com/django/django/blob/master/django/views/generic/edit.py#L245
def
delete
(
self
,
request
,
*
args
,
**
kwargs
):
def
delete
(
self
,
request
,
*
args
,
**
kwargs
):
object
=
self
.
get_object
()
object
=
self
.
get_object
()
...
@@ -2650,3 +2635,16 @@ class InterfaceDeleteView(DeleteView):
...
@@ -2650,3 +2635,16 @@ class InterfaceDeleteView(DeleteView):
if
redirect
:
if
redirect
:
return
redirect
return
redirect
self
.
object
.
instance
.
get_absolute_url
()
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,
...
@@ -915,3 +915,9 @@ class Instance(AclBase, VirtualMachineDescModel, StatusModel, OperatedMixin,
i
.
is_abortable_for_user
=
partial
(
i
.
is_abortable_for
,
i
.
is_abortable_for_user
=
partial
(
i
.
is_abortable_for
,
user
=
user
)
user
=
user
)
return
acts
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):
...
@@ -543,3 +543,22 @@ class FlushOperation(NodeOperation):
register_operation
(
FlushOperation
)
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