Skip to content
Projects
Groups
Snippets
Help
Loading...
Help
Support
Keyboard shortcuts
?
Submit feedback
Contribute to GitLab
Sign in / Register
Toggle navigation
S
slapos.toolbox
Project overview
Project overview
Details
Activity
Releases
Repository
Repository
Files
Commits
Branches
Tags
Contributors
Graph
Compare
Issues
0
Issues
0
List
Boards
Labels
Milestones
Merge Requests
0
Merge Requests
0
CI / CD
CI / CD
Pipelines
Jobs
Schedules
Analytics
Analytics
CI / CD
Repository
Value Stream
Wiki
Wiki
Snippets
Snippets
Members
Members
Collapse sidebar
Close sidebar
Activity
Graph
Create a new issue
Jobs
Commits
Issue Boards
Open sidebar
Kirill Smelkov
slapos.toolbox
Commits
3ce5dac2
Commit
3ce5dac2
authored
Jun 14, 2012
by
Alain Takoudjou
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
Add support for instance parameters
parent
4f7342b7
Changes
10
Hide whitespace changes
Inline
Side-by-side
Showing
10 changed files
with
383 additions
and
97 deletions
+383
-97
slapos/runner/__init__.py
slapos/runner/__init__.py
+5
-0
slapos/runner/static/css/jqueryTabs.css
slapos/runner/static/css/jqueryTabs.css
+8
-3
slapos/runner/static/css/styles.css
slapos/runner/static/css/styles.css
+34
-18
slapos/runner/static/js/jquery/jqueryTabs.js
slapos/runner/static/js/jquery/jqueryTabs.js
+21
-5
slapos/runner/static/js/jquery/popup.js
slapos/runner/static/js/jquery/popup.js
+3
-3
slapos/runner/static/js/scripts/common.js
slapos/runner/static/js/scripts/common.js
+47
-20
slapos/runner/static/js/scripts/inspectInstance.js
slapos/runner/static/js/scripts/inspectInstance.js
+134
-18
slapos/runner/templates/instanceInspect.html
slapos/runner/templates/instanceInspect.html
+45
-15
slapos/runner/utils.py
slapos/runner/utils.py
+43
-6
slapos/runner/views.py
slapos/runner/views.py
+43
-9
No files found.
slapos/runner/__init__.py
View file @
3ce5dac2
...
...
@@ -109,6 +109,7 @@ def run():
def
serve
(
config
):
from
views
import
app
#import FlaskRealmDigestDB
workdir
=
os
.
path
.
join
(
config
.
runner_workdir
,
'project'
)
app
.
config
.
update
(
**
config
.
__dict__
)
app
.
config
.
update
(
...
...
@@ -121,5 +122,9 @@ def serve(config):
)
if
not
os
.
path
.
exists
(
workdir
):
os
.
mkdir
(
workdir
)
#authDB = FlaskRealmDigestDB('SlaposWebRunner')
#user_dict = authDB.toDict()
#if not user_dict['db']:
# authDB.add_user('admin', 'root')
app
.
run
(
host
=
config
.
runner_host
,
port
=
int
(
config
.
runner_port
),
debug
=
config
.
debug
,
threaded
=
True
)
slapos/runner/static/css/jqueryTabs.css
View file @
3ce5dac2
...
...
@@ -9,7 +9,12 @@
#tabContaier
textarea
{
width
:
702px
;
margin-top
:
4px
;
margin-left
:
4px
;
resize
:
none
;
}
#tabContaier
textarea
.slap
{
width
:
455px
;
max-height
:
120px
;
height
:
20px
;
padding
:
3px
;
color
:
#6F6F6F
}
#tabContaier
input
[
type
=
'text'
]
{
width
:
125px
;}
#tabContaier
>
ul
{
overflow
:
hidden
;
height
:
34px
;
...
...
@@ -39,9 +44,9 @@
}
#tabContaier
>
ul
>
li
a
.active
{
background
:
#fbfbfb
;
border
:
1px
solid
#fff
;
border
:
1px
solid
#fff
;
border-top
:
0
;
border-right
:
0
;
border-right
:
0
;
color
:
#333
;
}
#tabContaier
>
ul
>
li
:first-child
a
{
border-left
:
0
}
...
...
@@ -55,4 +60,4 @@
}
.tabContents
p
{
padding
:
0
0
10px
;
}
}
slapos/runner/static/css/styles.css
View file @
3ce5dac2
...
...
@@ -15,7 +15,8 @@ a:hover {
}
table
{
margin
:
0
;
margin
:
0
;
padding
:
0
;
border-right
:
none
;
border-bottom
:
none
;
font-size
:
14px
;
...
...
@@ -36,16 +37,18 @@ th{
font-weight
:
normal
;
font-size
:
18px
;
}
table
.small
th
{
padding
:
4px
;
font-size
:
16px
;}
textarea
{
width
:
762px
;
}
body
{
background
:
url("../images/1307251316-background-stripes.gif")
repeat
#9C9C9C
;
font-family
:
'Helvetica Neue'
,
Helvetica
,
Arial
,
sans-serif
;
font-family
:
'Helvetica Neue'
,
Tahoma
,
Helvetica
,
Arial
,
sans-serif
;
color
:
#000000
;
font-size
:
13px
;
overflow
:
-moz-scrollbars-vertical
;
overflow-y
:
scroll
;
}
#page
...
...
@@ -314,7 +317,7 @@ input[type="radio"], input[type="checkbox"]{
#home_box
{
background
:
none
;
border
:
1px
solid
#678dad
;
border
:
2px
solid
#87B0D4
;
padding
:
0
;
color
:
#4c6172
;
margin
:
15px
59px
15px
59px
;
...
...
@@ -333,7 +336,7 @@ input[type="radio"], input[type="checkbox"]{
#home_box
h2
{
font-weight
:
normal
;
font-size
:
23px
;
color
:
#4
c6172
;
color
:
#4
75F73
;
}
#home_box
p
{
...
...
@@ -351,7 +354,6 @@ input[type="radio"], input[type="checkbox"]{
.inner_box
{
background
:
none
;
margin
:
0
;
border
:
1px
solid
#CAD4DC
;
display
:
block
;
padding
:
30px
0
30px
0
;
}
...
...
@@ -371,23 +373,24 @@ input[type="radio"], input[type="checkbox"]{
margin
:
10px
45px
10px
45px
;
padding
:
10px
;
padding-bottom
:
15px
;
border
:
#678dad
;
width
:
530px
;
border
:
1px
solid
#678dad
;
}
.lmenu
:hover
,
.smenu
:hover
,
.sright_menu
:hover
{
.smaller
{
margin-left
:
10px
;
width
:
350px
;
float
:
right
}
.smaller
p
{
width
:
280px
;}
.umenu
{
display
:
block
;
margin
:
10px
0
10px
45px
;
width
:
147px
;
float
:
left
;
border
:
1px
solid
#678dad
;
padding
:
10px
;
height
:
80px
;
padding-bottom
:
15px
;}
.umenu
p
{
font-size
:
13px
;
float
:
left
;
width
:
77px
;
cursor
:
default
;}
.lmenu
:hover
,
.smenu
:hover
,
.sright_menu
:hover
,
.smaller
:hover
,
.umenu
:hover
{
background
:
#96b9d7
;
}
.smenu
{
display
:
block
;
height
:
80px
;
margin
:
0
10px
0
45px
;
padding
:
10px
;
padding-bottom
:
15px
;
border
:
#678dad
;
width
:
250px
;
border
:
1px
solid
#678dad
;
float
:
left
;
...
...
@@ -580,9 +583,10 @@ a.lshare{
height
:
18px
;
font-size
:
15px
;
border
:
solid
1px
#678dad
;
color
:
#4DA0C6
;
color
:
#4DA0C6
;
text-align
:
center
;
font-weight
:
bold
;
cursor
:
pointer
;
}
a
.lshare
:hover
{
background
:
#D9D9D9
;
...
...
@@ -593,7 +597,9 @@ a.lshare:hover{
a
.lshare
:focus
{
border
:
solid
1px
#73A6FF
;
}
a
.no-right-border
{
border-right
:
none
}
a
.no-right-border
:hover
{
border-right
:
none
}
a
.no-right-border
:focus
{
border-right
:
none
}
a
.lshare
img
{
margin
:
5px
;
}
...
...
@@ -635,19 +641,19 @@ a.lshare img{
width
:
36px
;
height
:
26px
;
}
#error
td
.close
{
#error
td
.
b_
close
{
width
:
30px
;
height
:
22px
;
}
.list
{
background
:
url(../images/menu_dropdown.png)
left
center
no-repeat
;
padding-left
:
10px
;}
.slidebox
{
padding
:
10px
;
}
.alert_message
{
background
:
url(../images/alert.png)
center
no-repeat
;
height
:
26px
;}
.error_message
{
background
:
url(../images/exit.png)
center
no-repeat
;
height
:
26px
;}
.confirm_message
{
background
:
url(../images/confirm.png)
center
no-repeat
;
height
:
26px
;}
.info_message
{
background
:
url(../images/info.png)
center
no-repeat
;
height
:
26px
;}
#error
p
{
font-size
:
13px
;
color
:
#4A131F
;}
#pClose
{
background
:
url(../images/close.png)
no-repeat
0px
0px
;
display
:
block
;
width
:
22px
;
height
:
22px
;
cursor
:
pointer
}
#pClose
:hover
{
background
:
url(../images/close_hover.png)
no-repeat
0px
0px
;}
#pClose
,
.close
{
background
:
url(../images/close.png)
no-repeat
0px
0px
;
display
:
block
;
width
:
22px
;
height
:
22px
;
cursor
:
pointer
}
#pClose
:hover
,
.close
:hover
{
background
:
url(../images/close_hover.png)
no-repeat
0px
0px
;}
.md5sum
{
margin
:
10px
;
font-size
:
15px
;}
.title
{
background
:
#e4e4e4
;
width
:
100%
;
height
:
25px
;
padding-top
:
2px
;
text-indent
:
5px
;
color
:
#737373
;
text-shadow
:
0px
1px
#FFF
;}
.menu-box-left
{
float
:
left
;
width
:
120px
;
font-size
:
14px
;
background
:
#e4e4e4
;
padding
:
5px
0
5px
5px
;
margin-top
:
10px
;
...
...
@@ -679,7 +685,8 @@ a.lshare img{
.popup
li
{
border-bottom
:
1px
dashed
#666666
;
padding
:
5px
;
padding-top
:
5px
;}
.popup-value
{
display
:
none
;}
textarea
.parameter
{
border
:
solid
1px
#678dad
;
color
:
#666666
;
height
:
110px
;}
.link
{
color
:
#fff
;
font-weight
:
bold
;
text-decoration
:
none
}
.link
:hover
{
color
:
#19485C
;}
input
[
type
=
radio
]
{
}
...
...
@@ -689,3 +696,12 @@ input[type=radio]:checked {
input
[
type
=
radio
]
:hover
{
box-shadow
:
0px
1px
3px
#F0F1F2
;
}
/* Login Css region *******/
#login-page
{
width
:
429px
;
height
:
236px
;
margin
:
130px
auto
0px
;
background
:
url(../images/loginBox.png)
no-repeat
;
padding
:
10px
;
font-size
:
14px
;
color
:
#03406A
}
#login-page
h2
{
color
:
#fff
;
font-size
:
26px
;
font-weight
:
normal
;
text-indent
:
50px
;}
.login-content
{
margin
:
10px
;
margin-top
:
40px
;
margin-bottom
:
0
;
height
:
90px
;}
.login-button
{
width
:
140px
;
margin
:
0
auto
;}
.login-element
{
float
:
left
;
min-width
:
120px
;}
.login-label
{
padding
:
5px
;
font-size
:
16px
;}
.login-input
{
width
:
220px
;}
\ No newline at end of file
slapos/runner/static/js/jquery/jqueryTabs.js
View file @
3ce5dac2
$
(
document
).
ready
(
function
(){
$
(
"
.tabContents
"
).
hide
();
// Hide all tab content divs by default
var
hashes
=
window
.
location
.
href
.
split
(
'
#
'
);
if
(
hashes
.
length
==
2
){
$
(
"
.tabContents
"
).
hide
();
// Hide all tab content divs by default
var
hashes
=
window
.
location
.
href
.
split
(
'
#
'
);
var
fromheight
=
0
;
var
previoustab
=
null
;
if
(
hashes
.
length
==
2
&&
hashes
[
1
]
!=
""
){
$
(
"
#tabContaier>ul li
"
).
each
(
function
()
{
var
$tab
=
$
(
this
).
find
(
"
a
"
);
if
(
$tab
.
hasClass
(
"
active
"
))
$tab
.
removeClass
(
"
active
"
);
if
(
$tab
.
hasClass
(
"
active
"
)){
$tab
.
removeClass
(
"
active
"
);
}
if
(
$tab
.
attr
(
"
href
"
)
==
"
#
"
+
hashes
[
1
]){
$tab
.
addClass
(
"
active
"
);
$
(
"
#
"
+
hashes
[
1
]).
show
();
previoustab
=
"
#
"
+
hashes
[
1
];
}
//alert($(this).attr("href"));
});
}
else
{
$
(
"
.tabContents:first
"
).
show
();}
// Show the first div of tab content by default
else
{
$
(
"
.tabContents:first
"
).
show
();
previoustab
=
"
.tabContents:first
"
;
}
// Show the first div of tab content by default
$
(
"
#tabContaier ul li a
"
).
click
(
function
(){
//Fire the click event
if
(
$
(
this
).
hasClass
(
'
active
'
)){
return
;
}
fromheight
=
$
(
previoustab
).
height
();
var
activeTab
=
$
(
this
).
attr
(
"
href
"
);
// Catch the click link
$
(
"
#tabContaier .tabDetails
"
).
css
(
"
height
"
,
$
(
"
#tabContaier .tabDetails
"
).
height
());
$
(
"
#tabContaier ul li a
"
).
removeClass
(
"
active
"
);
// Remove pre-highlighted link
$
(
this
).
addClass
(
"
active
"
);
// set clicked link to highlight state
$
(
"
.tabContents
"
).
hide
();
// hide currently visible tab content div
$
(
activeTab
).
fadeIn
();
// show the target tab content div by matching clicked link.
var
diff
=
fromheight
-
$
(
activeTab
).
height
();
if
(
diff
>
0
){
$
(
"
#tabContaier .tabDetails
"
).
animate
({
height
:
'
-=
'
+
diff
+
'
px
'
},
850
,
'
swing
'
,
function
()
{
$
(
"
#tabContaier .tabDetails
"
).
css
(
"
height
"
,
""
);
});}
else
{
diff
=
-
1
*
diff
;
$
(
"
#tabContaier .tabDetails
"
).
animate
({
height
:
'
+=
'
+
diff
+
'
px
'
},
850
,
'
swing
'
,
function
()
{
$
(
"
#tabContaier .tabDetails
"
).
css
(
"
height
"
,
""
);
});}
previoustab
=
activeTab
;
$
(
"
#tabContaier .tabDetails
"
).
css
(
"
height
"
,
$
(
"
#tabContaier .tabDetails
"
).
height
());
});
});
\ No newline at end of file
slapos/runner/static/js/jquery/popup.js
View file @
3ce5dac2
...
...
@@ -9,14 +9,14 @@
if
(
option
.
closebtn
==
undefined
)
option
.
closebtn
=
false
;
if
(
option
.
duration
==
undefined
)
option
.
duration
=
0
;
if
(
option
.
load
==
undefined
)
option
.
load
=
false
;
$box
=
$
(
this
);
$box
=
$
(
this
);
$box
.
empty
();
$box
.
css
(
'
top
'
,
'
-1000px
'
);
$box
.
show
();
$box
.
append
(
'
<div><table id="bcontent"><tr>
'
+
'
<td valign="middle" class="logo
'
+
option
.
type
+
'
_message"></td>
'
+
'
<td valign="middle"><p>
'
+
msg
+
'
</p></td>
'
+
'
<td valign="middle" class="
close"><span id="pClose"></span></td></tr></table></div>
'
);
'
<td valign="middle" class="
b_close"><span id="pClose"></span></td></tr></table></div>
'
);
$
(
window
).
scroll
(
function
(){
$box
.
animate
({
top
:
$
(
window
).
scrollTop
()
+
"
px
"
},{
queue
:
false
,
duration
:
350
});
});
...
...
@@ -45,5 +45,5 @@
});
}
}
});
});
}(
jQuery
,
document
,
this
));
\ No newline at end of file
slapos/runner/static/js/scripts/common.js
View file @
3ce5dac2
/*Common javascript function*/
String
.
prototype
.
toHtmlChar
=
function
(){
c
=
{
'
<
'
:
'
<
'
,
'
>
'
:
'
>
'
,
'
&
'
:
'
&
'
,
'
"
'
:
'
"
'
,
"
'
"
:
'
'
'
,
var
c
=
{
'
<
'
:
'
<
'
,
'
>
'
:
'
>
'
,
'
&
'
:
'
&
'
,
'
"
'
:
'
"
'
,
"
'
"
:
'
'
'
,
'
#
'
:
'
#
'
};
return
this
.
replace
(
/
[
<&>'"#
]
/g
,
function
(
s
)
{
return
c
[
s
];
}
);
}
...
...
@@ -8,23 +8,50 @@ String.prototype.trim = function () {
return
this
.
replace
(
/^
\s
*/
,
""
).
replace
(
/
\s
*$/
,
""
);
}
/**************************/
$
(
document
).
ready
(
function
()
{
$
(
'
input[type="text"]
'
).
addClass
(
"
idleField
"
);
$
(
'
input[type="text"]
'
).
focus
(
function
()
{
$
(
this
).
removeClass
(
"
idleField
"
).
addClass
(
"
focusField
"
);
if
(
this
.
value
==
this
.
defaultValue
){
this
.
value
=
''
;
}
if
(
this
.
value
!=
this
.
defaultValue
){
this
.
select
();
}
});
$
(
'
input[type="text"]
'
).
blur
(
function
()
{
$
(
this
).
removeClass
(
"
focusField
"
).
addClass
(
"
idleField
"
);
if
(
$
.
trim
(
this
.
value
)
==
''
){
this
.
value
=
(
this
.
defaultValue
?
this
.
defaultValue
:
''
);
}
});
});
\ No newline at end of file
/****************************************/
function
setInput
(
$elt
)
{
if
(
!
$elt
){
var
$elt
=
$
(
'
input[type="text"], input[type="password"]
'
);}
$elt
.
addClass
(
"
idleField
"
);
$elt
.
focus
(
function
()
{
$
(
this
).
removeClass
(
"
idleField
"
).
addClass
(
"
focusField
"
);
if
(
this
.
value
==
this
.
defaultValue
){
this
.
value
=
''
;
}
if
(
this
.
value
!=
this
.
defaultValue
){
this
.
select
();
}
});
$elt
.
blur
(
function
()
{
$
(
this
).
removeClass
(
"
focusField
"
).
addClass
(
"
idleField
"
);
if
(
$
.
trim
(
this
.
value
)
==
''
){
this
.
value
=
(
this
.
defaultValue
?
this
.
defaultValue
:
''
);
}
});
}
/**************************/
(
function
(
$
,
document
,
window
)
{
$
.
extend
(
$
.
fn
,
{
slideBox
:
function
(
state
)
{
if
(
!
state
)
state
=
"
hide
"
;
var
header
=
$
(
"
#
"
+
$
(
this
).
attr
(
'
id
'
)
+
"
>h2
"
);
var
box
=
$
(
"
#
"
+
$
(
this
).
attr
(
'
id
'
)
+
"
>div
"
);
header
.
addClass
(
state
);
if
(
state
==
"
hide
"
){
box
.
css
(
'
display
'
,
'
none
'
);}
header
.
click
(
function
(){
var
state
=
box
.
css
(
"
display
"
);
if
(
state
==
"
none
"
){
box
.
slideDown
(
"
normal
"
);
header
.
removeClass
(
"
hide
"
);
header
.
addClass
(
"
show
"
);
}
else
{
box
.
slideUp
(
"
normal
"
);
header
.
removeClass
(
"
show
"
);
header
.
addClass
(
"
hide
"
);
}
});
}
});
}(
jQuery
,
document
,
this
));
\ No newline at end of file
slapos/runner/static/js/scripts/inspectInstance.js
View file @
3ce5dac2
...
...
@@ -4,28 +4,77 @@ $(document).ready( function() {
$
(
$
(
"
#slappart li
"
)[
0
]).
find
(
"
input:radio
"
).
attr
(
'
checked
'
,
true
);
$
(
"
.menu-box-right>div
"
).
css
(
'
min-height
'
,
$
(
"
#slappart li
"
).
length
*
26
+
20
+
"
px
"
);
configRadio
();
var
send
=
false
;
var
lastli
=
null
;
var
partitionAmount
=
$
(
"
i
m
put#partitionAmount
"
).
val
();
var
partitionAmount
=
$
(
"
i
n
put#partitionAmount
"
).
val
();
$
(
"
#slappart li
"
).
each
(
function
(){
lastli
=
$
(
this
);
$
(
this
).
find
(
"
input:radio
"
).
change
(
function
(){
configRadio
();
configRadio
();
});
});
lastli
.
css
(
"
border-bottom
"
,
"
none
"
);
});
lastli
.
css
(
"
border-bottom
"
,
"
none
"
);
$
(
"
#parameterkw
"
).
slideBox
(
"
show
"
);
setupSlappart
();
$
(
"
#softwareType
"
).
slideBox
();
$
(
"
#reloadfiles
"
).
click
(
function
(){
setupFileTree
();
});
$
(
"
#refresh
"
).
click
(
function
(){
if
(
send
)
return
;
$
(
"
#imgwaitting
"
).
fadeIn
();
$
.
ajax
({
type
:
"
GET
"
,
url
:
$SCRIPT_ROOT
+
'
/supervisordStatus
'
,
data
:
""
,
success
:
function
(
data
){
if
(
data
.
code
==
1
){
$
(
"
#supervisordcontent
"
).
empty
();
$
(
"
#supervisordcontent
"
).
append
(
data
.
result
);
}
$
(
"
#imgwaitting
"
).
fadeOut
();
}
});
return
false
;
});
$
(
"
#add_attribute
"
).
click
(
function
(){
var
size
=
Number
(
$
(
"
#partitionParameter > tbody > tr
"
).
last
().
attr
(
'
id
'
).
split
(
'
_
'
)[
1
])
+
1
;
var
row
=
"
<tr id='row_
"
+
size
+
"
'><td class='propertie first'><input type='text' name='txt_
"
+
size
+
"
' id='txt_
"
+
size
+
"
'></td>
"
+
"
<td style='padding:6px'><textarea class='slap' id='value_
"
+
size
+
"
'></textarea>
"
+
"
</td><td valign='middle'><span style='margin-left: 10px;' id='btn_
"
+
size
+
"
' class='close'></span></td></tr>
"
;
$
(
"
#partitionParameter
"
).
append
(
row
);
setInput
(
$
(
"
input#txt_
"
+
size
));
$
(
"
#btn_
"
+
size
).
click
(
function
(){
var
index
=
$
(
this
).
attr
(
'
id
'
).
split
(
'
_
'
)[
1
];
$
(
"
tr#row_
"
+
index
).
remove
();
});
return
false
;
});
$
(
"
#updateParameters
"
).
click
(
function
(){
updateParameter
();
return
false
;
});
//Load previous instance parameters
loadParameter
();
function
setupFileTree
(){
function
setupFileTree
(
path
){
var
root
=
$
(
"
input#root
"
).
val
();
if
(
root
==
""
)
return
;
if
(
path
){
root
+=
"
/
"
+
path
;
$
(
"
#tab4>h2
"
).
html
(
"
File content for <strong>
"
+
path
+
"
</strong>
"
);
}
else
{
$
(
"
#tab4>h2
"
).
html
(
"
File content for all your partitions
"
);}
$
(
'
#fileTree
'
).
empty
();
$
(
'
#fileTree
'
).
fileTree
({
root
:
root
,
script
:
$SCRIPT_ROOT
+
"
/readFolder
"
,
folderEvent
:
'
click
'
,
expandSpeed
:
750
,
collapseSpeed
:
750
,
multiFolder
:
false
,
selectFolder
:
false
},
function
(
file
)
{
collapseSpeed
:
750
,
multiFolder
:
false
,
selectFolder
:
false
},
function
(
file
)
{
},
function
(
file
){
//User have double click on file in to the fileTree
viewFile
(
file
);
});
}
function
viewFile
(
file
){
//User have double click on file in to the fileTree
loadFileContent
(
file
);
...
...
@@ -49,7 +98,7 @@ $(document).ready( function() {
}
});
});
function
loadFileContent
(
file
){
$
.
ajax
({
type
:
"
POST
"
,
...
...
@@ -62,14 +111,14 @@ $(document).ready( function() {
type
:
"
POST
"
,
url
:
$SCRIPT_ROOT
+
'
/getFileContent
'
,
data
:
{
file
:
file
,
truncate
:
1500
},
success
:
function
(
data
){
success
:
function
(
data
){
if
(
data
.
code
==
1
){
$
(
"
#inline_content
"
).
empty
();
$
(
"
#inline_content
"
).
append
(
'
<h2 style="color: #4c6172; font: 18px
\'
Helvetica Neue
\'
, Helvetica, Arial, sans-serif;">Inspect Instance Content:
'
+
file
+
'
</h2>
'
);
$
(
"
#inline_content
"
).
append
(
'
<br/><div class="main_content"><pre id="editor"></pre></div>
'
);
setupEditor
();
$
(
"
.inline
"
).
colorbox
({
inline
:
true
,
width
:
"
847px
"
,
onComplete
:
function
(){
$
(
"
.inline
"
).
colorbox
({
inline
:
true
,
width
:
"
847px
"
,
onComplete
:
function
(){
editor
.
getSession
().
setValue
(
data
.
result
);
}});
$
(
"
.inline
"
).
click
();
...
...
@@ -91,10 +140,59 @@ $(document).ready( function() {
}
});
}
function
updateParameter
(){
var
xml
=
'
<?xml version="1.0" encoding="utf-8"?>
\n
'
,
software_type
=
""
;
if
(
$
(
"
input#software_type
"
).
val
()
!=
""
&&
$
(
"
input#software_type
"
).
val
()
!=
"
Software Type here...
"
){
software_type
=
+
$
(
"
input#software_type
"
).
val
();
}
xml
+=
'
<instance>
\n
'
;
var
size
=
$
(
"
#partitionParameter > tbody > tr
"
).
length
;
if
(
size
>
1
){
for
(
var
i
=
2
;
i
<=
size
;
i
++
){
if
(
$
(
"
input#txt_
"
+
i
).
val
()
!=
""
){
xml
+=
'
<parameter id="
'
+
$
(
"
input#txt_
"
+
i
).
val
()
+
'
">
'
+
$
(
"
textarea#value_
"
+
i
).
val
()
+
'
</parameter>
\n
'
;
}
}
}
xml
+=
'
</instance>
\n
'
;
$
.
ajax
({
type
:
"
POST
"
,
url
:
$SCRIPT_ROOT
+
'
/saveParameterXml
'
,
data
:
{
software_type
:
software_type
,
parameter
:
xml
},
success
:
function
(
data
){
if
(
data
.
code
==
1
){
$
(
"
#error
"
).
Popup
(
"
Instance parameters has been updated, please run your instance now!
"
,
{
type
:
'
confirm
'
,
duration
:
5000
});
}
else
{
$
(
"
#error
"
).
Popup
(
data
.
result
,
{
type
:
'
error
'
,
duration
:
5000
});
}
}
});
}
function
loadParameter
(){
$
.
ajax
({
type
:
"
GET
"
,
url
:
$SCRIPT_ROOT
+
'
/getParameterXml
'
,
success
:
function
(
data
){
if
(
data
.
code
==
1
){
var
dict
=
data
.
result
[
'
instance
'
];
for
(
propertie
in
dict
){
$
(
"
#add_attribute
"
).
click
();
var
size
=
Number
(
$
(
"
#partitionParameter > tbody > tr
"
).
last
().
attr
(
'
id
'
).
split
(
'
_
'
)[
1
]);
$
(
"
input#txt_
"
+
size
).
val
(
propertie
);
$
(
"
textarea#value_
"
+
size
).
val
(
dict
[
propertie
]);
}
}
else
{
$
(
"
#error
"
).
Popup
(
data
.
result
,
{
type
:
'
error
'
,
duration
:
5000
});
}
}
});
}
function
configRadio
(){
$
(
"
#slappart li
"
).
each
(
function
()
{
$
(
"
#slappart li
"
).
each
(
function
()
{
var
$radio
=
$
(
this
).
find
(
"
input:radio
"
);
var
boxselector
=
"
#box
"
+
$radio
.
attr
(
'
id
'
);
var
boxselector
=
"
#box
"
+
$radio
.
attr
(
'
id
'
);
if
(
$
(
this
).
hasClass
(
'
checked
'
)){
$
(
this
).
removeClass
(
'
checked
'
);
$
(
boxselector
).
slideUp
(
"
normal
"
);
...
...
@@ -103,11 +201,24 @@ $(document).ready( function() {
$
(
this
).
addClass
(
'
checked
'
);
//change content here
$
(
boxselector
).
slideDown
(
"
normal
"
);
}
});
}
function
setupEditor
(){
function
setupBox
(){
var
state
=
$
(
"
#softwareType
"
).
css
(
"
display
"
);
if
(
state
==
"
none
"
){
$
(
"
#softwareType
"
).
slideDown
(
"
normal
"
);
$
(
"
#softwareTypeHead
"
).
removeClass
(
"
hide
"
);
$
(
"
#softwareTypeHead
"
).
addClass
(
"
show
"
);
}
else
{
$
(
"
#softwareType
"
).
slideUp
(
"
normal
"
);
$
(
"
#softwareTypeHead
"
).
removeClass
(
"
show
"
);
$
(
"
#softwareTypeHead
"
).
addClass
(
"
hide
"
);
}
}
function
setupEditor
(){
editor
=
ace
.
edit
(
"
editor
"
);
editor
.
setTheme
(
"
ace/theme/crimson_editor
"
);
...
...
@@ -121,9 +232,14 @@ $(document).ready( function() {
function
setupSlappart
(){
for
(
var
i
=
0
;
i
<
partitionAmount
;
i
++
){
var
elt
=
$
(
"
#slappart
"
+
i
+
"
Parameter
"
);
if
(
elt
!=
undefined
)
elt
.
click
(
function
(){
alert
(
elt
.
attr
(
'
id
'
));
});
var
fileId
=
$
(
"
#slappart
"
+
i
+
"
Files
"
);
if
(
elt
&&
elt
!=
undefined
)
elt
.
click
(
function
(){
alert
(
$
(
this
).
html
());
});
if
(
fileId
&&
fileId
!=
undefined
)
fileId
.
click
(
function
(){
$
(
"
#instancetabfiles
"
).
click
();
setupFileTree
(
$
(
this
).
attr
(
"
rel
"
));
});
}
}
});
\ No newline at end of file
slapos/runner/templates/instanceInspect.html
View file @
3ce5dac2
...
...
@@ -19,14 +19,15 @@
<div
id=
"tabContaier"
>
<ul>
<li><a
href=
"#tab1"
class=
"active"
>
Slapgrid Supervisor
</a></li>
<li><a
href=
"#tab2"
>
SLAP Response
&
Parameters
</a></li>
<li><a
href=
"#tab3"
>
Partitions Content
</a></li>
<li><a
href=
"#tab2"
>
SLAP Response
</a></li>
<li><a
href=
"#tab3"
>
Parameters
</a></li>
<li><a
href=
"#tab4"
id=
"instancetabfiles"
>
Partitions Content
</a></li>
</ul>
<!-- //Tab buttons -->
<div
class=
"tabDetails"
>
<div
id=
"tab1"
class=
"tabContents"
>
<p>
This tab show all process generated by slapgrid for your application. You can click on the process name to display log.
</p>
{% if supervisor %}
<table
cellpadding=
"0"
cellspacing=
"0"
width=
"100%"
>
<table
cellpadding=
"0"
cellspacing=
"0"
width=
"100%"
id=
"supervisordcontent"
>
<tr>
<th>
Partition and Process name
</th><th>
Status
</th><th>
Process PID
</th><th>
UpTime
</th><th></th>
</tr>
...
...
@@ -39,7 +40,10 @@
</tr>
{% endfor %}
</table><br/>
<a
href=
"{{ url_for('stopAllPartition') }}"
class=
"lshare simple"
>
Stop all process
</a>
<a
href=
"#"
id=
"refresh"
class=
"lshare simple no-right-border"
style=
"float:left"
>
Refresh Status
</a>
<a
href=
"{{ url_for('stopAllPartition') }}"
class=
"lshare simple"
style=
"float:left"
>
Stop all process
</a>
<img
class=
"waitting"
id=
"imgwaitting"
src=
"{{ url_for('static', filename='images/waiting.gif') }}"
alt=
""
/>
<div
class=
"clear"
></div><br/>
{% else %}
<h2>
No process to display, please run your instance
</h2>
{%endif%}
...
...
@@ -52,13 +56,13 @@
{% for item in slap_status %}
<div
id=
"box{{item[0]}}"
style=
"display:none;"
>
{% if item[1] %}
<
!--<
h2><span style="float:left; margin-left:10px;" id="{{item[0]}}title">Slap Response for {{item[0]}}</span>
<a href="#" id="{{item[0]}}Parameter" rel="{{item[0]}}" class="lshare simple" style="float:right">
SLAP
Parameters</a>
</h2>--
>
<
h2>
Slap Response for {{item[0]}}
<
/h2>
<h2><span
style=
"float:left; margin-left:10px;"
id=
"{{item[0]}}title"
>
Slap Response for {{item[0]}}
</span>
<a
href=
"#"
id=
"{{item[0]}}Parameter"
rel=
"{{item[0]}}"
class=
"lshare simple"
style=
"float:right"
>
Parameters
</a>
<a
href=
"#"
id=
"{{item[0]}}Files"
rel=
"{{item[0]}}"
class=
"lshare simple no-right-border"
style=
"float:right"
>
Files
</a
>
</h2>
<div
class=
"clear"
></div><br/>
<div
id=
"bcontent{{item[0]}}"
>
<table
cellpadding=
"0"
cellspacing=
"0"
width=
"100%"
>
<div
id=
"bcontent{{item[0]}}"
>
<table
cellpadding=
"0"
cellspacing=
"0"
width=
"100%"
>
<tr>
<th>
Parameter Name
</th><th>
Parameter Value
</th>
</tr>
...
...
@@ -67,9 +71,9 @@
<td
class=
"propertie first"
>
{{k}}
</td><td
align=
'left'
>
{{item[1][k]}}
</td>
</tr>
{% endfor %}
</table>
</table>
</div>
{% else %}
{% else %}
<h2>
Empty Partition
</h2></br>
<center><img
alt=
""
src=
"{{ url_for('static', filename='images/empty.png') }}"
/></center>
<br/><h2>
Partition {{item[0]}} is still empty
</h2>
...
...
@@ -82,8 +86,8 @@
<ul
id=
"slappart"
>
{% for item in slap_status %}
<li><input
type=
"radio"
name=
"slapresponse"
id=
"{{item[0]}}"
value=
"{{item[0]}}"
/>
<label
for=
"{{item[0]}}"
{%
if
item
[
1
]
%}
style=
"font-weight:bold"
{%
endif
%}
>
{{item[0]}}
</label></li>
{% endfor %}
<label
for=
"{{item[0]}}"
{%
if
item
[
1
]
%}
style=
"font-weight:bold"
{%
endif
%}
>
{{item[0]}}
</label></li>
{% endfor %}
</ul>
</div>
<div
class=
"clear"
></div><br/>
...
...
@@ -92,8 +96,34 @@
{%endif%}
</div>
<!-- end tab2 -->
<div
id=
"tab3"
class=
"tabContents"
>
<div
id=
"fileTree"
class=
"file_tree_tabs"
></div>
<div
id=
"softwareType"
>
<h2
class=
'hight'
>
Software Type parameter
</h2>
<div
class=
"slidebox"
>
<label
for=
"software_type"
>
Software Type
</label>
<input
type=
"text"
name=
"software_type"
id=
"software_type"
size=
"35"
value=
"Software Type here..."
/>
</div>
</div>
<br/>
<div
id=
"parameterkw"
>
<h2
class=
'hight'
>
Partitions Parameter
</h2>
<div
class=
"slidebox"
>
<table
class=
"small"
cellpadding=
"0"
cellspacing=
"0"
width=
"100%"
id=
"partitionParameter"
>
<tr
id=
"row_1"
>
<th
width=
"150"
>
Parameter Name
</th><th>
Parameter Value
</th><th
width=
"49"
>
<a
href=
"#"
class=
"link"
id=
"add_attribute"
>
[new]
</a>
</th>
</tr>
</table>
</div>
</div>
<div
style=
"margin-left:10px;"
><a
id=
"updateParameters"
class=
"lshare simple"
>
Update Values
</a></div>
</div>
<!-- end tab3 -->
<div
id=
"tab4"
class=
"tabContents"
>
<h2>
File content for all your partitions
</h2>
<div
id=
"fileTree"
class=
"file_tree_tabs"
alt=
"Double click to open file"
></div>
<br/>
<a
href=
"#"
id=
"reloadfiles"
class=
"lshare simple"
>
Reload Files
</a>
</div>
<!-- end tab4 -->
</div>
</div>
<!-- This contains the hidden content for inline calls -->
...
...
slapos/runner/utils.py
View file @
3ce5dac2
...
...
@@ -33,11 +33,20 @@ html_escape_table = {
">"
:
">"
,
"<"
:
"<"
,
}
def
html_escape
(
text
):
"""Produce entities within text."""
return
""
.
join
(
html_escape_table
.
get
(
c
,
c
)
for
c
in
text
)
def
checkLogin
(
config
,
login
,
pwd
):
if
not
os
.
path
.
exists
(
os
.
path
.
join
(
config
[
'runner_workdir'
],
'.users'
)):
return
False
user
=
open
(
os
.
path
.
join
(
config
[
'runner_workdir'
],
'.users'
),
'r'
).
read
().
split
(
';'
)
salt
=
"runner81"
#to be changed
current_pwd
=
hashlib
.
md5
(
salt
+
pwd
).
hexdigest
()
if
current_pwd
==
user
[
1
]:
return
user
return
False
def
updateProxy
(
config
):
if
not
os
.
path
.
exists
(
config
[
'instance_root'
]):
...
...
@@ -82,12 +91,11 @@ def updateProxy(config):
#get instance parameter
param_path
=
os
.
path
.
join
(
config
[
'runner_workdir'
],
".parameter.xml"
)
xml_result
=
readParameters
(
param_path
)
partition_parameter_kw
=
None
if
type
(
xml_result
)
!=
type
(
''
)
and
xml_result
.
has_key
(
'instance'
):
partition_parameter_kw
=
xml_result
[
'instance'
]
else
:
partition_parameter_kw
=
None
computer
.
updateConfiguration
(
xml_marshaller
.
dumps
(
slap_config
))
sr_request
=
slap
.
registerOpenOrder
().
request
(
profile
,
partition_reference
=
partition_reference
,
sr_request
=
slap
.
registerOpenOrder
().
request
(
profile
,
partition_reference
=
getSoftwareReleaseName
(
config
)
,
partition_parameter_kw
=
partition_parameter_kw
,
software_type
=
None
,
filter_kw
=
None
,
state
=
None
,
shared
=
False
)
#open(param_path, 'w').write(xml_marshaller.dumps(sr_request.
...
...
@@ -107,6 +115,27 @@ def readPid(file):
def
writePid
(
file
,
pid
):
open
(
file
,
'w'
).
write
(
str
(
pid
))
def
updateInstanceParameter
(
config
,
software_type
=
None
):
slap
=
slapos
.
slap
.
slap
()
slap
.
initializeConnection
(
config
[
'master_url'
])
partition_list
=
[]
#Get current software release profile
try
:
software_folder
=
open
(
os
.
path
.
join
(
config
[
'runner_workdir'
],
".project"
)).
read
()
profile
=
realpath
(
config
,
os
.
path
.
join
(
software_folder
,
config
[
'software_profile'
]))
except
:
return
False
#get instance parameter
param_path
=
os
.
path
.
join
(
config
[
'runner_workdir'
],
".parameter.xml"
)
xml_result
=
readParameters
(
param_path
)
partition_parameter_kw
=
None
if
type
(
xml_result
)
!=
type
(
''
)
and
xml_result
.
has_key
(
'instance'
):
partition_parameter_kw
=
xml_result
[
'instance'
]
slap
.
registerOpenOrder
().
request
(
profile
,
partition_reference
=
getSoftwareReleaseName
(
config
),
partition_parameter_kw
=
partition_parameter_kw
,
software_type
=
software_type
,
filter_kw
=
None
,
state
=
None
,
shared
=
False
)
def
startProxy
(
config
):
proxy_pid
=
os
.
path
.
join
(
config
[
'runner_workdir'
],
'proxy.pid'
)
...
...
@@ -244,6 +273,7 @@ def runInstanceWithLock(config):
logfile
=
open
(
config
[
'instance_log'
],
'w'
)
if
not
updateProxy
(
config
):
return
False
svcStopAll
(
config
)
#prevent lost control of process
slapgrid
=
Popen
([
config
[
'slapgrid_cp'
],
'-vc'
,
config
[
'configuration_file_path'
]],
stdout
=
logfile
)
writePid
(
slapgrid_pid
,
slapgrid
.
pid
)
slapgrid
.
wait
()
...
...
@@ -264,8 +294,7 @@ def getSlapStatus(config):
try
:
for
partition
in
computer
.
getComputerPartitionList
():
# Note: Internal use of API, as there is no reflexion interface in SLAP
partition_list
.
append
((
partition
.
getId
(),
partition
.
_connection_dict
.
copy
(),
partition
.
_parameter_dict
.
copy
()))
partition_list
.
append
((
partition
.
getId
(),
partition
.
_connection_dict
.
copy
()))
except
Exception
:
pass
if
partition_list
:
...
...
@@ -445,6 +474,14 @@ def getProjectTitle(config):
return software + " (" + string.join(project[:(len(project) - 2)], '
/
') + ")"
return "No Profile"
def getSoftwareReleaseName(config):
sr_profile = os.path.join(config['
runner_workdir
'], ".project")
if os.path.exists(sr_profile):
project = open(sr_profile, "r").read().split("/")
software = project[len(project) - 2]
return software.replace('
', '
_
')
return "No_name"
def loadSoftwareData(runner_dir):
import pickle
file_path = os.path.join(runner_dir, '
.
softdata
')
...
...
slapos/runner/views.py
View file @
3ce5dac2
...
...
@@ -11,6 +11,9 @@ app = Flask(__name__)
@
app
.
before_request
def
before_request
():
if
not
session
.
has_key
(
'account'
)
and
request
.
path
!=
'/login'
\
and
request
.
path
!=
'/doLogin'
and
not
request
.
path
.
startswith
(
'/static'
):
return
redirect
(
url_for
(
'login'
))
session
[
'title'
]
=
getProjectTitle
(
app
.
config
)
# general views
...
...
@@ -20,11 +23,24 @@ def home():
return
redirect
(
url_for
(
'configRepo'
))
return
render_template
(
'index.html'
)
@
app
.
route
(
"/login"
)
def
login
():
return
render_template
(
'login.html'
)
@
app
.
route
(
'/configRepo'
)
def
configRepo
():
public_key
=
open
(
app
.
config
[
'public_key'
],
'r'
).
read
()
return
render_template
(
'cloneRepository.html'
,
workDir
=
'workspace'
,
public_key
=
public_key
)
@
app
.
route
(
"/doLogin"
,
methods
=
[
'POST'
])
def
doLogin
():
check_user
=
checkLogin
(
app
.
config
,
request
.
form
[
'clogin'
],
request
.
form
[
'cpwd'
])
if
not
check_user
:
return
jsonify
(
code
=
0
,
result
=
"Login or password is incorrect, please check it!"
)
else
:
session
[
'account'
]
=
check_user
return
jsonify
(
code
=
1
,
result
=
check_user
)
# software views
@
app
.
route
(
'/editSoftwareProfile'
)
def
editSoftwareProfile
():
...
...
@@ -88,11 +104,26 @@ def inspectInstance():
file_content
=
'instance_root'
result
=
getSvcStatus
(
app
.
config
)
if
len
(
result
)
==
0
:
result
=
[]
result
=
[]
return
render_template
(
'instanceInspect.html'
,
file_path
=
file_content
,
supervisor
=
result
,
slap_status
=
getSlapStatus
(
app
.
config
),
supervisore
=
result
,
partition_amount
=
app
.
config
[
'partition_amount'
])
@
app
.
route
(
'/supervisordStatus'
,
methods
=
[
'GET'
])
def
supervisordStatus
():
result
=
getSvcStatus
(
app
.
config
)
if
not
(
result
):
return
jsonify
(
code
=
0
,
result
=
""
)
html
=
"<tr><th>Partition and Process name</th><th>Status</th><th>Process PID </th><th> UpTime</th><th></th></tr>"
for
item
in
result
:
html
+=
"<tr>"
html
+=
"<td class='first'><b><a href='"
+
url_for
(
'tailProcess'
,
process
=
item
[
0
])
+
"'>"
+
item
[
0
]
+
"</a></b></td>"
html
+=
"<td align='center'><a href='"
+
url_for
(
'startStopProccess'
,
process
=
item
[
0
],
action
=
item
[
1
])
+
"'>"
+
item
[
1
]
+
"</a></td>"
html
+=
"<td align='center'>"
+
item
[
3
]
+
"</td><td>"
+
item
[
5
]
+
"</td>"
html
+=
"<td align='center'><a href='"
+
url_for
(
'startStopProccess'
,
process
=
item
[
0
],
action
=
'RESTART'
)
+
"'>Restart</a></td>"
html
+=
"</tr>"
return
jsonify
(
code
=
1
,
result
=
html
)
@
app
.
route
(
'/removeInstance'
)
def
removeInstance
():
if
isInstanceRunning
(
app
.
config
):
...
...
@@ -360,7 +391,7 @@ def getPath():
return
jsonify
(
code
=
1
,
result
=
realfile
)
@
app
.
route
(
"/saveParameterXml"
,
methods
=
[
'POST'
])
def
red
ParameterXml
():
def
save
ParameterXml
():
project
=
os
.
path
.
join
(
app
.
config
[
'runner_workdir'
],
".project"
)
if
not
os
.
path
.
exists
(
project
):
return
jsonify
(
code
=
0
,
result
=
"Please first open a Software Release"
)
...
...
@@ -370,20 +401,23 @@ def redParameterXml():
f
.
write
(
content
)
f
.
close
()
result
=
readParameters
(
param_path
)
software_type
=
None
if
(
request
.
form
[
'software_type'
]):
software_type
=
request
.
form
[
'software_type'
]
if
type
(
result
)
==
type
(
''
):
return
jsonify
(
code
=
0
,
result
=
"XML Error: "
+
result
)
else
:
try
:
update
Proxy
(
app
.
config
)
except
Ex
eption
:
return
jsonify
(
code
=
0
,
result
=
"An error occurred while applying your settings!
"
)
update
InstanceParameter
(
app
.
config
,
software_type
)
except
Ex
ception
,
e
:
return
jsonify
(
code
=
0
,
result
=
"An error occurred while applying your settings!
<br/>"
+
str
(
e
)
)
return
jsonify
(
code
=
1
,
result
=
""
)
@
app
.
route
(
"/getParameterXml"
,
methods
=
[
'GET'
])
def
getParameterXml
():
param_path
=
os
.
path
.
join
(
app
.
config
[
'runner_workdir'
],
".parameter.xml"
)
if
os
.
path
.
exists
(
param_path
):
content
=
open
(
param_path
,
'r'
).
read
()
return
html_escape
(
content
)
parameters
=
readParameters
(
param_path
)
if
type
(
parameters
)
!=
type
(
''
):
return
jsonify
(
code
=
1
,
result
=
parameters
)
else
:
return
"<?xml version='1.0' encoding='utf-8'?>"
\ No newline at end of file
return
jsonify
(
code
=
0
,
result
=
parameters
)
\ No newline at end of file
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