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
Members
Members
Collapse sidebar
Close sidebar
Activity
Graph
Create a new issue
Jobs
Commits
Issue Boards
Open sidebar
Jérome Perrin
slapos.toolbox
Commits
8cebacc6
Commit
8cebacc6
authored
Aug 11, 2014
by
Nicolas Wavrant
Browse files
Options
Browse Files
Download
Plain Diff
Merge branch 'slaprunner-paas'
parents
c4716eaa
c9a34429
Changes
18
Show whitespace changes
Inline
Side-by-side
Showing
18 changed files
with
443 additions
and
128 deletions
+443
-128
slapos/resiliencytest/suites/slaprunner.py
slapos/resiliencytest/suites/slaprunner.py
+2
-1
slapos/runner/__init__.py
slapos/runner/__init__.py
+20
-0
slapos/runner/runnertest.py
slapos/runner/runnertest.py
+33
-5
slapos/runner/static/css/editor.css
slapos/runner/static/css/editor.css
+40
-1
slapos/runner/static/css/images/terminal.png
slapos/runner/static/css/images/terminal.png
+0
-0
slapos/runner/static/css/styles.css
slapos/runner/static/css/styles.css
+10
-3
slapos/runner/static/images/doc.png
slapos/runner/static/images/doc.png
+0
-0
slapos/runner/static/images/forum.png
slapos/runner/static/images/forum.png
+0
-0
slapos/runner/static/js/scripts/account.js
slapos/runner/static/js/scripts/account.js
+1
-1
slapos/runner/static/js/scripts/inspectInstance.js
slapos/runner/static/js/scripts/inspectInstance.js
+6
-3
slapos/runner/static/js/scripts/process.js
slapos/runner/static/js/scripts/process.js
+112
-104
slapos/runner/static/js/scripts/shell.js
slapos/runner/static/js/scripts/shell.js
+91
-0
slapos/runner/static/js/scripts/viewlog.js
slapos/runner/static/js/scripts/viewlog.js
+4
-4
slapos/runner/templates/layout.html
slapos/runner/templates/layout.html
+5
-4
slapos/runner/templates/softwareFolder.html
slapos/runner/templates/softwareFolder.html
+8
-0
slapos/runner/templates/viewLog.html
slapos/runner/templates/viewLog.html
+4
-0
slapos/runner/utils.py
slapos/runner/utils.py
+44
-0
slapos/runner/views.py
slapos/runner/views.py
+63
-2
No files found.
slapos/resiliencytest/suites/slaprunner.py
View file @
8cebacc6
...
...
@@ -200,9 +200,10 @@ class SlaprunnerTestSuite(ResiliencyTestSuite):
def
_getRcode
(
self
):
#XXX-Nicolas: hardcoded url. Best way right now to automate the tests...
monitoring_password
=
"passwordtochange"
monitor_url
=
self
.
monitor_url
+
"?script=zero-knowledge%2Fsettings.cgi"
result
=
self
.
_opener_director
.
open
(
monitor_url
,
"password=
passwordtochange"
)
"password=
"
+
monitoring_password
+
";password_2="
+
monitoring_password
)
if
result
.
getcode
()
is
not
200
:
raise
NotHttpOkException
(
result
.
getcode
())
...
...
slapos/runner/__init__.py
View file @
8cebacc6
...
...
@@ -4,6 +4,7 @@
import
ConfigParser
import
datetime
import
flask
import
logging
import
logging.handlers
import
os
...
...
@@ -133,4 +134,23 @@ def serve(config):
config
.
logger
.
info
(
'Done.'
)
app
.
wsgi_app
=
ProxyFix
(
app
.
wsgi_app
)
def
getUpdatedParameter
(
self
,
var
):
configuration_parser
=
ConfigParser
.
SafeConfigParser
()
configuration_file_path
=
os
.
path
.
abspath
(
os
.
getenv
(
'RUNNER_CONFIG'
))
configuration_parser
.
read
(
configuration_file_path
)
for
section
in
configuration_parser
.
sections
():
if
configuration_parser
.
has_option
(
section
,
var
):
return
configuration_parser
.
get
(
section
,
var
)
# if the requested var is dependant of flask
if
var
in
self
.
keys
():
temp_dict
=
dict
()
temp_dict
.
update
(
self
)
return
temp_dict
[
var
]
else
:
raise
KeyError
flask
.
config
.
Config
.
__getitem__
=
getUpdatedParameter
run
()
slapos/runner/runnertest.py
View file @
8cebacc6
...
...
@@ -96,8 +96,6 @@ class SlaprunnerTestCase(unittest.TestCase):
software_profile
=
'software.cfg'
,
SECRET_KEY
=
"123456"
,
PERMANENT_SESSION_LIFETIME
=
datetime
.
timedelta
(
days
=
31
),
auto_deploy
=
True
,
autorun
=
False
,
instance_monitoring_url
=
'https://['
+
config
.
ipv6_address
+
']:9684'
,
)
self
.
app
=
views
.
app
.
test_client
()
...
...
@@ -122,6 +120,10 @@ class SlaprunnerTestCase(unittest.TestCase):
project
=
os
.
path
.
join
(
self
.
app
.
config
[
'etc_dir'
],
'.project'
)
users
=
os
.
path
.
join
(
self
.
app
.
config
[
'etc_dir'
],
'.users'
)
#reset tested parameters
self
.
updateConfigParameter
(
'autorun'
,
False
)
self
.
updateConfigParameter
(
'auto_deploy'
,
True
)
if
os
.
path
.
exists
(
users
):
os
.
unlink
(
users
)
if
os
.
path
.
exists
(
project
):
...
...
@@ -139,6 +141,15 @@ class SlaprunnerTestCase(unittest.TestCase):
killRunningProcess
(
'slapgrid-cp'
,
recursive
=
True
)
killRunningProcess
(
'slapgrid-sr'
,
recursive
=
True
)
def
updateConfigParameter
(
self
,
parameter
,
value
):
config_parser
=
ConfigParser
.
SafeConfigParser
()
config_parser
.
read
(
os
.
getenv
(
'RUNNER_CONFIG'
))
for
section
in
config_parser
.
sections
():
if
config_parser
.
has_option
(
section
,
parameter
):
config_parser
.
set
(
section
,
parameter
,
str
(
value
))
with
open
(
os
.
getenv
(
'RUNNER_CONFIG'
),
'wb'
)
as
configfile
:
config_parser
.
write
(
configfile
)
def
configAccount
(
self
,
username
,
password
,
email
,
name
,
rcode
):
"""Helper for configAccount"""
return
self
.
app
.
post
(
'/configAccount'
,
...
...
@@ -433,8 +444,8 @@ class SlaprunnerTestCase(unittest.TestCase):
"""Scenario 7: isSRReady won't overwrite the existing
Sofware Instance if it has been deployed yet"""
# Test that SR won't be deployed with auto_deploy=False
self
.
app
.
config
[
'auto_deploy'
]
=
False
self
.
app
.
config
[
'autorun'
]
=
False
self
.
updateConfigParameter
(
'auto_deploy'
,
False
)
self
.
updateConfigParameter
(
'autorun'
,
False
)
project
=
open
(
os
.
path
.
join
(
self
.
app
.
config
[
'etc_dir'
],
'.project'
),
"w"
)
project
.
write
(
self
.
software
+
'slaprunner-test'
)
...
...
@@ -442,7 +453,7 @@ class SlaprunnerTestCase(unittest.TestCase):
response
=
isSoftwareReleaseReady
(
self
.
app
.
config
)
self
.
assertEqual
(
response
,
"0"
)
# Test if auto_deploy parameter starts the deployment of SR
self
.
app
.
config
[
'auto_deploy'
]
=
True
self
.
updateConfigParameter
(
'auto_deploy'
,
True
)
self
.
setupSoftwareFolder
()
response
=
isSoftwareReleaseReady
(
self
.
app
.
config
)
self
.
assertEqual
(
response
,
"2"
)
...
...
@@ -522,6 +533,23 @@ class SlaprunnerTestCase(unittest.TestCase):
self
.
assertEqual
(
response
,
(
1
,
MAX_RUN_INSTANCE
))
def
test_dynamicParametersReading
(
self
):
"""Test if the value of a parameter can change in the flask application
only by changing the value of slapos.cfg config file. This can happen when
slapgrid processes the webrunner's partition.
"""
config_file
=
os
.
path
.
join
(
self
.
app
.
config
[
'etc_dir'
],
'slapos.cfg'
)
runner_config_old
=
os
.
environ
[
'RUNNER_CONFIG'
]
os
.
environ
[
'RUNNER_CONFIG'
]
=
config_file
open
(
config_file
,
'w'
).
write
(
"[section]
\
n
var=value"
)
config
=
self
.
app
.
config
self
.
assertEqual
(
config
[
'var'
],
"value"
)
open
(
config_file
,
'w'
).
write
(
"[section]
\
n
var=value_changed"
)
self
.
assertEqual
(
config
[
'var'
],
"value_changed"
)
# cleanup
os
.
environ
[
'RUNNER_CONFIG'
]
=
runner_config_old
def
main
():
# Empty parser for now - so that erp5testnode is happy when doing --help
parser
=
argparse
.
ArgumentParser
()
...
...
slapos/runner/static/css/editor.css
View file @
8cebacc6
...
...
@@ -28,6 +28,7 @@
.swith_btn
{
background
:
url(../images/gnome-session-switch.png)
center
right
no-repeat
;
width
:
105px
;}
.flist_btn
{
background
:
url(../images/list2_down.png)
center
right
no-repeat
;
width
:
26px
;}
.fmenu_btn
{
background
:
url(../images/ui_menu_blue.png)
center
right
no-repeat
;
width
:
58px
;}
.shell_btn
{
background
:
url(../images/terminal.png)
center
right
no-repeat
;
width
:
62px
;}
#tabControl
{
overflow
:
hidden
;}
#tabControl
.item
{
float
:
left
;
min-width
:
60px
;
background
:
#D5D5D5
;
height
:
22px
;
padding-top
:
8px
;
font-size
:
1em
;
...
...
@@ -43,4 +44,42 @@ border-left:1px #E4E4E4 solid; cursor:pointer; color: #5C7077; text-shadow: 0px
#tabContent
pre
.active
{
display
:
block
;}
.item-hide
{
display
:
none
;}
#shell-window
{
width
:
974px
;
height
:
350px
;
z-index
:
10
;
border
:
2px
solid
#6A93A0
;
border-top
:
none
;
background
:
#9bbed6
;
position
:
absolute
;
display
:
none
;
border-bottom-left-radius
:
5px
;
border-bottom-right-radius
:
5px
;
}
#shell-result
{
width
:
98%
;
height
:
300px
;
margin-left
:
1%
;
margin-right
:
1%
;
margin-top
:
5px
;
padding
:
3px
;
background
:
#E4E4E4
;
color
:
#074A86
;
box-sizing
:
border-box
;
border
:
2px
inset
#6A93A0
;
overflow
:
auto
;
}
.runned-command
{
font-weight
:
bold
;
}
#shell-input
{
width
:
96%
;
margin-left
:
1%
;
margin-right
:
1%
;
position
:
absolute
;
bottom
:
10px
;
background
:
#E4E4E4
;
color
:
#074A86
;
border
:
inset
1px
#678dad
;
}
slapos/runner/static/css/images/terminal.png
0 → 100644
View file @
8cebacc6
1.07 KB
slapos/runner/static/css/styles.css
View file @
8cebacc6
...
...
@@ -106,7 +106,7 @@ body {
padding-top
:
3px
;
margin-left
:
20px
;
float
:
left
;
width
:
700
px
;
width
:
695
px
;
height
:
22px
;
text-align
:
center
;
color
:
#4c6172
;
...
...
@@ -434,6 +434,10 @@ padding: 10px;height: 80px;padding-bottom:15px;}
.gradient
{
background-color
:
#f4f4f4
;
background
:
-moz-linear-gradient
(
#f4f4f4
,
#ececec
);
background
:
-webkit-linear-gradient
(
#f4f4f4
,
#ececec
);
-ms-filter
:
"progid:DXImageTransform.Microsoft.gradient(startColorstr='#f4f4f4',endColorstr='#ececec')"
;
background
:
linear-gradient
(
#f4f4f4
,
#ececec
);}
#slapstate
{
display
:
none
;
}
.log_content
{
border
:
solid
1px
#519ADA
;
padding
:
2px
;
...
...
@@ -506,6 +510,9 @@ padding: 10px;height: 80px;padding-bottom:15px;}
font-size
:
16px
;
}
.last_build
{
font-size
:
0.9em
;
}
.log_content_box
{
padding
:
10px
5px
;
font-size
:
14px
;
...
...
@@ -528,13 +535,13 @@ padding: 10px;height: 80px;padding-bottom:15px;}
display
:
block
;
float
:
left
;
}
.log_info_box
div
.state_running
span
{
.log_info_box
div
.state_running
span
,
.log_info_box
div
.state_notupdated
span
{
background
:
#FFC800
;
}
.log_info_box
div
.state_terminated
span
{
background
:
#00C800
;
}
.log_info_box
div
.state_waiting
span
,
.log_info_box
div
.state_stopped
span
{
.log_info_box
div
.state_waiting
span
,
.log_info_box
div
.state_stopped
span
,
.log_info_box
div
.state_failed
span
{
background
:
#FF3131
;
}
...
...
slapos/runner/static/images/doc.png
0 → 100644
View file @
8cebacc6
1.01 KB
slapos/runner/static/images/forum.png
0 → 100644
View file @
8cebacc6
1.49 KB
slapos/runner/static/js/scripts/account.js
View file @
8cebacc6
...
...
@@ -59,7 +59,7 @@ $(document).ready(function () {
},
success
:
function
(
data
)
{
if
(
data
.
code
===
1
)
{
url
=
'
https://
'
+
$
(
"
input#username
"
).
val
()
+
'
:
'
+
$
(
"
input#password
"
).
val
()
+
'
@
'
+
location
.
host
+
$SCRIPT_ROOT
+
'
/
'
;
var
url
=
'
https://
'
+
$
(
"
input#username
"
).
val
()
+
'
:
'
+
$
(
"
input#password
"
).
val
()
+
'
@
'
+
location
.
host
+
$SCRIPT_ROOT
+
'
/
'
;
window
.
location
.
href
=
url
;
}
else
{
$
(
"
#error
"
).
Popup
(
data
.
result
,
{
type
:
'
error
'
,
duration
:
5000
});
...
...
slapos/runner/static/js/scripts/inspectInstance.js
View file @
8cebacc6
...
...
@@ -89,9 +89,12 @@ $(document).ready(function () {
}
xml
+=
'
<instance>
\n
'
;
if
(
size
>
1
)
{
for
(
i
=
2
;
i
<=
size
;
i
+=
1
)
{
if
(
$
(
'
input#txt_
'
+
i
).
val
()
!==
''
)
{
xml
+=
'
<parameter id="
'
+
$
(
'
input#txt_
'
+
i
).
val
()
+
'
">
'
+
$
(
'
textarea#value_
'
+
i
).
val
()
+
'
</parameter>
\n
'
;
// we have to remove the 1st line, which just diplay column names
for
(
i
=
0
;
i
<
size
-
1
;
i
+=
1
)
{
var
parameter_name
=
$
(
"
#partitionParameter tr
"
).
find
(
"
input
"
)[
i
].
value
;
var
parameter_value
=
$
(
"
#partitionParameter tr
"
).
find
(
"
textarea
"
)[
i
].
value
;
if
(
parameter_name
!==
''
)
{
xml
+=
'
<parameter id="
'
+
parameter_name
+
'
">
'
+
parameter_value
+
'
</parameter>
\n
'
;
}
}
}
...
...
slapos/runner/static/js/scripts/process.js
View file @
8cebacc6
/*jslint undef: true */
/*global $, window, $SCRIPT_ROOT, setRunningState, setCookie, getCookie, deleteCookie */
/*global currentState: true, running:
true, $current: true, processType: true, currentProces
s: true */
/*global sendStop: true,
processState: true,
openedlogpage: true, logReadingPosition: true, speed: true */
/*global currentState: true, running:
false, $current: true, currentProcess: true, processType
s: true */
/*global sendStop: true, openedlogpage: true, logReadingPosition: true, speed: true */
/*global isRunning: true */
/* vim: set et sts=4: */
//Global Traitment!!!
var
url
=
$SCRIPT_ROOT
+
"
/slapgridResult
"
;
var
currentState
=
false
;
var
running
=
tru
e
;
var
processType
=
""
;
var
currentProcess
;
var
running
=
fals
e
;
var
currentProcess
=
""
;
var
processTypes
=
{
instance
:
"
instance
"
,
software
:
"
software
"
}
;
var
sendStop
=
false
;
var
forcedStop
=
false
;
var
processState
=
"
Checking
"
;
//define slapgrid running state
var
openedlogpage
=
""
;
//content software or instance if the current page is software or instance log, otherwise nothing
var
logReadingPosition
=
0
;
var
speed
=
5000
;
var
maxLogSize
=
100000
;
//Define the max limit of log to display ~ 2500 lines
var
currentLogSize
=
0
;
//Define the size of log actually displayed
var
last_run
=
""
;
var
runInstance
=
false
;
$
(
document
).
ready
(
function
()
{
$
.
get
(
"
/getSlapgridParameters
"
,
null
,
function
(
data
)
{
runInstance
=
data
.
run_instance
;
});
});
var
isRunning
=
function
()
{
"
use strict
"
;
if
(
running
)
{
...
...
@@ -50,35 +57,30 @@ function removeFirstLog() {
$
(
"
#salpgridLog p:first-child
"
).
remove
();
}
function
getRunningState
(
)
{
function
writeLogs
(
data
)
{
"
use strict
"
;
var
size
=
0
,
log_info
=
""
,
param
=
{
position
:
logReadingPosition
,
log
:
(
processState
!==
"
Checking
"
&&
openedlogpage
!==
""
)
?
processType
.
toLowerCase
()
:
""
},
jqxhr
=
$
.
post
(
url
,
param
,
function
(
data
)
{
setRunningState
(
data
);
var
log_info
=
""
,
size
=
data
.
content
.
position
-
logReadingPosition
;
if
(
size
<
0
)
{
clearAll
(
false
);
}
if
(
logReadingPosition
!==
0
&&
data
.
content
.
truncated
)
{
log_info
=
"
<p class='info' rel='0'>SLAPRUNNER INFO: SLAPGRID-LOG HAS BEEN TRUNCATED HERE. To see full log reload your log page</p>
"
;
}
logReadingPosition
=
data
.
content
.
position
;
if
(
data
.
content
.
content
!==
""
)
{
if
(
data
.
content
.
content
!==
""
)
{
$
(
"
#salpgridLog
"
).
append
(
log_info
+
"
<p rel='
"
+
size
+
"
'>
"
+
data
.
content
.
content
.
toHtmlChar
()
+
"
</p>
"
);
$
(
"
#salpgridLog
"
)
.
scrollTop
(
$
(
"
#salpgridLog
"
)[
0
].
scrollHeight
-
$
(
"
#salpgridLog
"
).
height
());
}
}
if
(
running
&&
processState
===
"
Checking
"
&&
openedlogpage
!==
""
)
{
if
(
running
&&
openedlogpage
!==
""
)
{
$
(
"
#salpgridLog
"
).
show
();
$
(
"
#manualLog
"
).
hide
();
$
(
"
#slapstate
"
).
show
();
$
(
"
#openloglist
"
).
hide
();
}
processState
=
running
?
"
Running
"
:
"
Stopped
"
;
currentLogSize
+=
parseInt
(
size
,
10
);
if
(
currentLogSize
>
maxLogSize
)
{
//Remove the first element into log div
...
...
@@ -87,6 +89,55 @@ function getRunningState() {
removeFirstLog
();
//in cas of previous <p/> size is 0
}
}
}
function
getRunningState
()
{
"
use strict
"
;
var
url
=
$SCRIPT_ROOT
+
"
/slapgridResult
"
,
build_success
=
0
,
run_success
=
0
,
param
=
{
position
:
logReadingPosition
,
log
:
(
openedlogpage
!==
""
)
?
currentProcess
:
""
},
jqxhr
=
$
.
post
(
url
,
param
,
function
(
data
)
{
running
=
data
.
result
;
if
(
data
.
instance
.
state
)
{
currentProcess
=
processTypes
.
instance
;
}
else
if
(
data
.
software
.
state
)
{
currentProcess
=
processTypes
.
software
;
}
if
(
last_run
===
""
)
{
last_run
=
data
.
instance
.
last_build
;
}
$
(
"
#last_build_software
"
).
text
(
"
last build:
"
+
data
.
software
.
last_build
);
if
(
data
.
instance
.
last_build
!==
last_run
)
{
currentProcess
=
processTypes
.
instance
;
last_run
=
data
.
instance
.
last_build
;
}
$
(
"
#last_build_instance
"
).
text
(
"
last run:
"
+
data
.
instance
.
last_build
);
writeLogs
(
data
);
setRunningState
(
data
);
//show accurate right panel
if
(
running
)
{
$
(
"
#slapstate
"
).
show
();
$
(
"
#openloglist
"
).
hide
();
}
if
(
data
.
result
)
{
if
(
currentProcess
===
processTypes
.
software
&&
runInstance
)
{
updateStatus
(
"
instance
"
,
"
waiting
"
);
}
updateStatus
(
currentProcess
,
"
running
"
);
}
else
{
build_success
=
(
data
.
software
.
success
===
0
)?
"
terminated
"
:
"
failed
"
;
if
(
last_run
<
data
.
software
.
last_build
&&
data
.
software
.
success
===
1
)
{
run_success
=
"
notupdated
"
;
}
else
{
run_success
=
(
data
.
instance
.
success
===
0
)?
"
terminated
"
:
"
failed
"
;
}
updateStatus
(
"
software
"
,
build_success
);
updateStatus
(
"
instance
"
,
run_success
);
}
}).
error
(
function
()
{
clearAll
(
false
);
});
...
...
@@ -103,20 +154,16 @@ function stopProcess() {
var
urlfor
=
$SCRIPT_ROOT
+
"
stopSlapgrid
"
,
type
=
"
slapgrid-sr
"
;
if
(
processType
===
"
Instance
"
)
{
if
(
currentProcess
===
processTypes
.
instance
)
{
type
=
"
slapgrid-cp
"
;
}
$
.
post
(
urlfor
,
{
type
:
type
},
function
(
data
)
{
//if (data.result) {
//$("#error").Popup("Failled to run Slapgrid", {type:'error', duration:3000}); });
//}
})
.
error
(
function
()
{
$
(
"
#error
"
).
Popup
(
"
Failed to stop Slapgrid process
"
,
{
type
:
'
error
'
,
duration
:
3000
});
})
.
complete
(
function
()
{
sendStop
=
false
;
processState
=
"
Stopped
"
;
forcedStop
=
true
;
});
}
...
...
@@ -129,8 +176,9 @@ function bindRun() {
stopProcess
();
}
else
{
if
(
!
isRunning
())
{
setCookie
(
"
slapgridCMD
"
,
"
Software
"
);
runProcess
(
$SCRIPT_ROOT
+
"
/runSoftwareProfile
"
).
then
(
function
()
{
window
.
location
.
href
=
$SCRIPT_ROOT
+
"
/viewLog?logfile=software.log
"
;
});
}
}
return
false
;
...
...
@@ -140,9 +188,10 @@ function bindRun() {
stopProcess
();
}
else
{
if
(
!
isRunning
())
{
setCookie
(
"
slapgridCMD
"
,
"
Instance
"
);
runProcess
(
$SCRIPT_ROOT
+
"
/runInstanceProfile
"
).
then
(
function
()
{
if
(
window
.
location
.
pathname
===
"
/viewLog
"
)
window
.
location
.
href
=
$SCRIPT_ROOT
+
"
/viewLog?logfile=instance.log
"
;
});
}
}
return
false
;
...
...
@@ -166,16 +215,13 @@ function updateStatus(elt, val) {
break
;
case
"
running
"
:
$
(
src
).
children
(
'
p
'
).
text
(
"
Processing
"
);
processType
=
elt
;
getRunningState
()
break
;
}
// in case of failure
if
(
$
(
"
#salpgridLog
"
).
text
().
indexOf
(
"
Failed to run buildout profile
"
)
!==
-
1
)
{
var
src
=
'
#
'
+
elt
+
'
_run_state
'
,
value
=
'
state_
'
+
"
stopped
"
;
$
(
src
).
removeClass
();
$
(
src
).
addClass
(
value
);
$
(
src
).
children
(
'
p
'
).
text
(
"
Buildout Failed
"
);
case
"
notupdated
"
:
$
(
src
).
children
(
'
p
'
).
text
(
"
Not updated
"
);
break
;
case
"
failed
"
:
$
(
src
).
children
(
'
p
'
).
text
(
"
Failed
"
);
break
;
}
}
...
...
@@ -186,40 +232,33 @@ function setRunningState(data) {
$
(
"
#running
"
).
show
();
running
=
true
;
//change run menu title and style
if
(
data
.
software
)
{
if
(
data
.
software
.
state
)
{
if
(
$
(
"
#running
"
).
children
(
'
span
'
).
length
===
0
)
{
$
(
"
#softrun
"
).
removeClass
(
'
slapos_run
'
);
$
(
"
#softrun
"
).
addClass
(
'
slapos_stop
'
);
if
(
$
(
"
[class=software][id=running_info]
"
).
length
===
0
)
$
(
"
#running img
"
).
before
(
'
<p id="running_info" class="software">Building software...</p>
'
);
}
processType
=
"
Software
"
;
}
if
(
data
.
instance
)
{
if
(
data
.
instance
.
state
)
{
///Draft!!
if
(
$
(
"
#running
"
).
children
(
'
span
'
).
length
===
0
)
{
$
(
"
#softrun
"
).
removeClass
(
'
slapos_run
'
);
$
(
"
#softrun
"
).
addClass
(
'
slapos_stop
'
);
if
(
$
(
"
[class=instance][id=running_info]
"
).
length
===
0
)
$
(
"
#running img
"
).
before
(
'
<p id="running_info" class="instance">Running instance...</p>
'
);
}
if
(
processType
===
"
Software
"
)
{
running
=
false
;
$
(
"
#running_info
"
).
remove
();
$
(
"
#softrun
"
).
addClass
(
'
slapos_run
'
);
$
(
"
#softrun
"
).
removeClass
(
'
slapos_stop
'
);
$
(
"
#instrun
"
).
click
();
}
processType
=
"
Instance
"
;
}
}
}
else
{
if
(
$
(
"
#running
"
).
is
(
"
:visible
"
)
)
{
$
(
"
#error
"
).
Popup
(
"
Slapgrid finished running your
"
+
processType
+
"
P
rofile
"
,
{
type
:
'
info
'
,
duration
:
3000
});
$
(
"
#error
"
).
Popup
(
"
Slapgrid finished running your
"
+
currentProcess
+
"
p
rofile
"
,
{
type
:
'
info
'
,
duration
:
3000
});
if
(
forcedStop
)
{
updateStatus
(
'
instance
'
,
'
stopped
'
);
updateStatus
(
'
software
'
,
'
stopped
'
);
}
else
{
updateStatus
(
processType
.
toLowerCase
()
,
'
terminated
'
);
updateStatus
(
currentProcess
,
'
terminated
'
);
}
//Update window!!!
$
(
"
#slapswitch
"
).
attr
(
'
rel
'
,
'
opend
'
);
...
...
@@ -227,7 +266,6 @@ function setRunningState(data) {
}
$
(
"
#running
"
).
hide
();
$
(
"
#running_info
"
).
remove
();
running
=
false
;
//nothing is currently running
$
(
"
#softrun
"
).
removeClass
(
'
slapos_stop
'
);
$
(
"
#softrun
"
).
addClass
(
'
slapos_run
'
);
if
(
$
(
"
#running
"
).
children
(
'
span
'
).
length
>
0
)
{
...
...
@@ -238,46 +276,16 @@ function setRunningState(data) {
currentState
=
data
.
result
;
}
function
runProcess
(
urlfor
,
data
)
{
function
runProcess
(
urlfor
)
{
"
use strict
"
;
if
(
!
isRunning
())
{
running
=
true
;
processState
=
"
Running
"
;
currentProcess
=
$
.
post
(
urlfor
)
.
error
(
function
()
{
$
(
"
#error
"
).
Popup
(
"
Failled to run Slapgrid
"
,
{
type
:
'
error
'
,
duration
:
3000
});
});
return
$
.
post
(
urlfor
).
then
(
function
()
{
if
(
$
(
"
#running_info
"
).
children
(
'
span
'
).
length
>
0
)
{
$
(
"
#running_info
"
).
children
(
'
p
'
).
remove
();
}
});
}
}
setInterval
(
'
GetStateRegularly()
'
,
5000
);
function
GetStateRegularly
()
{
getRunningState
();
}
function
checkSavedCmd
()
{
"
use strict
"
;
var
result
=
getCookie
(
"
slapgridCMD
"
);
if
(
!
result
)
{
return
false
;
}
forcedStop
=
false
;
if
(
result
===
"
Software
"
)
{
running
=
false
;
runProcess
((
$SCRIPT_ROOT
+
"
/runSoftwareProfile
"
),
{
result
:
true
,
instance
:
false
,
software
:
true
});
updateStatus
(
'
software
'
,
'
running
'
);
updateStatus
(
'
instance
'
,
'
waiting
'
);
}
else
if
(
result
===
"
Instance
"
)
{
running
=
false
;
runProcess
((
$SCRIPT_ROOT
+
"
/runInstanceProfile
"
),
{
result
:
true
,
instance
:
true
,
software
:
false
});
updateStatus
(
'
software
'
,
'
terminated
'
);
updateStatus
(
'
instance
'
,
'
running
'
);
}
deleteCookie
(
"
slapgridCMD
"
);
return
(
result
!==
null
);
}
getRunningState
();
setInterval
(
'
getRunningState()
'
,
3000
);
slapos/runner/static/js/scripts/shell.js
0 → 100644
View file @
8cebacc6
/*jslint undef: true */
/*global $, document, $SCRIPT_ROOT, window */
/*global path: true */
/* vim: set et sts=4: */
var
shellHistory
=
""
;
var
currentCommand
=
0
;
$
(
document
).
ready
(
function
()
{
"
use strict
"
;
var
updateHistory
=
function
()
{
$
.
getJSON
(
"
/getMiniShellHistory
"
,
function
(
data
)
{
shellHistory
=
data
;
currentCommand
=
shellHistory
.
length
;
});
};
updateHistory
();
$
(
"
#shell
"
).
click
(
function
()
{
// We have to do that because once slide effect is activated, div is considered as visible
$
(
"
#shell
"
).
css
(
"
background-color
"
,
"
#E4E4E4
"
);
if
(
!
$
(
"
#shell-window
"
).
is
(
'
:visible
'
)
)
{
$
(
"
#shell
"
).
css
(
"
background-color
"
,
"
#C7C7C7
"
);
}
$
(
"
#shell-window
"
).
slideToggle
(
"
fast
"
);
if
(
$
(
"
#shell-window
"
).
is
(
'
:visible
'
)
)
{
$
(
"
#shell-input
"
).
focus
();
}
});
$
(
"
#shell-input
"
).
keypress
(
function
(
event
)
{
//if Enter is pressed
if
(
event
.
which
===
13
)
{
event
.
preventDefault
();
var
command
=
$
(
"
#shell-input
"
).
val
();
var
data
=
{
command
:
command
};
$
(
"
#shell-result
"
).
append
(
"
<p id=
\"
waiting_for_command
\"
><img src=
\"
/static/css/images/loading-min.gif
\"
/></p>
"
)
$
(
"
#shell-result
"
).
scrollTop
(
$
(
"
#shell-result
"
)[
0
].
scrollHeight
);
$
.
ajax
({
type
:
"
POST
"
,
url
:
$SCRIPT_ROOT
+
"
/runCommand
"
,
data
:
data
,
timeout
:
600000
})
.
done
(
function
(
data
)
{
var
data
=
"
<p><span class=
\"
runned-command
\"
>
"
+
data
.
path
+
"
>>>
"
+
command
+
"
</span></p><br/><pre>
"
+
data
.
data
+
"
</pre><br/>
"
;
$
(
"
#shell-result
"
).
append
(
data
);
$
(
"
#shell-input
"
).
val
(
""
);
$
(
"
#shell-result
"
).
scrollTop
(
$
(
"
#shell-result
"
)[
0
].
scrollHeight
);
updateHistory
();
})
.
fail
(
function
(
xhr
,
status
,
error
)
{
$
(
"
#error
"
).
Popup
(
"
Error while sending command. Server answered with :
\n
"
+
xhr
.
statusCode
().
status
+
"
:
"
+
error
,
{
type
:
'
error
'
,
duration
:
3000
})
})
.
always
(
function
()
{
$
(
"
#waiting_for_command
"
).
remove
();
});
}
});
$
(
"
#shell-input
"
).
keydown
(
function
(
event
)
{
//if Key Up is pressed
if
(
event
.
which
==
38
)
{
event
.
preventDefault
();
currentCommand
--
;
if
(
currentCommand
<=
0
)
currentCommand
=
0
;
$
(
"
#shell-input
"
).
val
(
shellHistory
[
currentCommand
]);
}
//if Key Down is pressed
if
(
event
.
which
===
40
)
{
event
.
preventDefault
();
currentCommand
++
;
if
(
currentCommand
>
shellHistory
.
length
)
{
currentCommand
=
shellHistory
.
length
;
$
(
"
#shell-input
"
).
val
(
""
);
}
else
{
$
(
"
#shell-input
"
).
val
(
shellHistory
[
currentCommand
]);
}
}
//if Tab is pressed
if
(
event
.
which
===
9
)
{
event
.
preventDefault
();
$
(
"
#error
"
).
Popup
(
"
Sorry, Tab completion is not handled for the moment in MiniShell
"
,
{
type
:
'
info
'
,
duration
:
1000
})
}
});
});
slapos/runner/static/js/scripts/viewlog.js
View file @
8cebacc6
/*jslint undef: true */
/*global $, document, window,
processState,
getCookie, setCookie, setSpeed, $SCRIPT_ROOT */
/*global openedlogpage: true */
/*global $, document, window, getCookie, setCookie, setSpeed, $SCRIPT_ROOT */
/*global openedlogpage: true
, running: false
*/
/* vim: set et sts=4: */
$
(
document
).
ready
(
function
()
{
...
...
@@ -53,7 +53,7 @@ $(document).ready(function () {
}
function
updatelogBox
()
{
if
(
processState
===
"
Stopped
"
||
processState
===
"
Checking
"
||
$
(
"
#manual
"
).
is
(
"
:checked
"
))
{
if
(
!
running
||
$
(
"
#manual
"
).
is
(
"
:checked
"
))
{
$
(
"
#salpgridLog
"
).
hide
();
$
(
"
#manualLog
"
).
show
();
$
(
"
#slapstate
"
).
hide
();
...
...
@@ -113,7 +113,7 @@ $(document).ready(function () {
})
.
always
(
function
()
{
sending
=
false
;
if
(
processState
===
"
Stopped
"
||
processState
===
"
Checking
"
||
$
(
"
#manual
"
).
is
(
"
:checked
"
))
{
if
(
!
running
||
$
(
"
#manual
"
).
is
(
"
:checked
"
))
{
$
(
"
#logheader
"
).
html
(
info
);
}
else
{
$
(
"
#logheader
"
).
html
(
"
Inspecting slapgrid log - Click for more options
"
);
...
...
slapos/runner/templates/layout.html
View file @
8cebacc6
...
...
@@ -44,9 +44,6 @@
$
(
"
#error
"
).
Popup
(
$
(
"
input#fmsg
"
).
val
(),
{
type
:
'
info
'
,
duration
:
5000
,
load
:
true
});
}
bindRun
();
if
(
!
checkSavedCmd
()){
getRunningState
();
}
$
(
'
ul.sf-menu
'
).
superfish
({
delay
:
600
,
speed
:
'
fast
'
,
...
...
@@ -67,6 +64,10 @@
<div
class=
"block_header"
>
<a
href=
"{{ url_for('home') }}"
style=
"float:left;"
id=
"home"
title=
"Home"
><img
alt=
""
src=
"{{ url_for('static', filename='images/home.png') }}"
/></a>
<div
class=
"line"
></div>
<a
href=
"http://community.slapos.org/wiki/osoe-Lecture.SlapOS.Extended"
style=
"float:left;position:relative;top:1px;"
target=
"_blank"
><img
src=
"{{ url_for('static', filename="
images
/
doc
.
png
")}}"
alt=
"documentation"
title=
"Documentation"
/></a>
<div
class=
"line"
></div>
<a
href=
"http://community.slapos.org/forum"
style=
"float:left;position:relative;top:1px;"
target=
"_blank"
><img
src=
"{{ url_for('static', filename="
images
/
forum
.
png
")}}"
alt=
"forum"
title=
"Forum"
/></a>
<div
class=
"line"
></div>
<h2
class=
"info"
>
{% block title %}{% endblock %} - {{session.title}}
</h2>
<div
class=
"run"
>
<div
id=
"running"
style=
"display:none"
>
...
...
@@ -121,7 +122,7 @@
</div>
{% if request.path != '/login' %}
<div
id=
"footer"
>
SlapOS web runner
©
Vifib SARL 2011
, 2012, 2013
- All right reserved - Creative Commons Shared Alike
SlapOS web runner
©
Vifib SARL 2011
-2014
- All right reserved - Creative Commons Shared Alike
</div>
{%endif%}
</div>
...
...
slapos/runner/templates/softwareFolder.html
View file @
8cebacc6
...
...
@@ -10,6 +10,7 @@
<link
href=
"{{ url_for('static', filename='css/colorbox.css', _external=False) }}"
rel=
"stylesheet"
type=
"text/css"
media=
"screen"
/>
<script
src=
"{{ url_for('static', filename='js/jquery/jquery.colorbox-min.js') }}"
type=
"application/javascript"
charset=
"utf-8"
></script>
<script
src=
"{{ url_for('static', filename='js/scripts/softwareFolder.js') }}"
type=
"application/javascript"
charset=
"utf-8"
></script>
<script
src=
"{{ url_for('static', filename='js/scripts/shell.js') }}"
type=
"application/javascript"
charset=
"utf-8"
></script>
{% endblock %}
{% block body %}
<style>
...
...
@@ -50,11 +51,18 @@
<li
id=
"fullscreen"
><span
class=
"expand_editor"
title=
"Show Editor in Full window. Hint: Use Ctrl+E"
>
</span></li>
<li
id=
"save"
><span
class=
"save_btn"
title=
"Save current file. Hint: Use Ctrl+S"
>
</span></li>
<li
id=
"option"
><span
class=
"fmenu_btn"
title=
'Show more options'
rel=
'tooltip'
>
Menu
</span></li>
<li
id=
"shell"
><span
class=
"shell_btn"
title=
"Run a command in a shell"
>
Shell
</span></li>
</ul>
<div
id=
"tabControl"
></div>
<div
class=
"clear"
></div>
</div>
<div
class=
"clear"
></div>
<div
id=
"shell-window"
>
<div
id=
"shell-result"
>
</div>
<input
type=
"text"
name=
"command"
id=
"shell-input"
autocomplete=
"off"
placeholder=
"Type command ..."
/>
</div>
<div
class=
"clear"
></div>
<div
class=
"software_details"
>
<div
id=
"details_box"
>
<div
id=
"fileTree"
class=
"file_tree_short"
></div>
...
...
slapos/runner/templates/viewLog.html
View file @
8cebacc6
...
...
@@ -37,6 +37,8 @@
<p>
Processing
</p>
<div
class=
"clear"
></div>
</div>
<p
id=
"last_build_software"
class=
"last_build"
></p><br/>
<div
class=
"clear"
></div>
<p>
SlapOS rebuild your software from source, allowing you to easily patch or add any free software.
<a
href=
"{{ url_for('viewLog', logfile='software.log') }}"
>
Learn how!
</a></p>
</div>
...
...
@@ -49,6 +51,8 @@
<p>
Waiting for starting
</p>
<div
class=
"clear"
></div>
</div>
<p
id=
"last_build_instance"
class=
"last_build"
></p><br/>
<div
class=
"clear"
></div>
<p>
SlapOS configure your running environment to match your needs.
<a
href=
"{{ url_for('viewLog', logfile='instance.log') }}"
>
Learn how!
</a></p>
</div>
...
...
slapos/runner/utils.py
View file @
8cebacc6
...
...
@@ -3,6 +3,7 @@
# pylint: disable-msg=W0311,C0301,C0103,C0111,W0141,W0142
import
ConfigParser
import
datetime
import
json
import
logging
import
md5
...
...
@@ -275,6 +276,29 @@ def isSoftwareRunning(config=None):
return
isRunning
(
'slapgrid-sr'
)
def
slapgridResultToFile
(
config
,
step
,
returncode
,
datetime
):
filename
=
step
+
"_info.json"
file
=
os
.
path
.
join
(
config
[
'runner_workdir'
],
filename
)
result
=
{
'last_build'
:
datetime
,
'success'
:
returncode
}
open
(
file
,
"w"
).
write
(
json
.
dumps
(
result
))
def
getSlapgridResult
(
config
,
step
):
filename
=
step
+
"_info.json"
file
=
os
.
path
.
join
(
config
[
'runner_workdir'
],
filename
)
if
os
.
path
.
exists
(
file
):
result
=
json
.
loads
(
open
(
file
,
"r"
).
read
())
else
:
result
=
{
'last_build'
:
0
,
'success'
:
-
1
}
return
result
def
waitProcess
(
config
,
process
,
step
):
process
.
wait
()
date
=
datetime
.
datetime
.
now
().
strftime
(
"%Y-%m-%d %H:%M:%S"
)
slapgridResultToFile
(
config
,
step
,
process
.
returncode
,
date
)
def
runSoftwareWithLock
(
config
,
lock
=
True
):
"""
Use Slapgrid to compile current Software Release and wait until
...
...
@@ -301,10 +325,13 @@ def runSoftwareWithLock(config, lock=True):
name
=
'slapgrid-sr'
,
stdout
=
None
)
if
lock
:
slapgrid
.
wait
()
date
=
datetime
.
datetime
.
now
().
strftime
(
"%Y-%m-%d %H:%M:%S"
)
slapgridResultToFile
(
config
,
"software"
,
slapgrid
.
returncode
,
date
)
#Saves the current compile software for re-use
config_SR_folder
(
config
)
return
(
True
if
slapgrid
.
returncode
==
0
else
False
)
else
:
thread
.
start_new_thread
(
waitProcess
,
(
config
,
slapgrid
,
"software"
))
return
False
...
...
@@ -401,8 +428,11 @@ def runInstanceWithLock(config, lock=True):
name
=
'slapgrid-cp'
,
stdout
=
None
)
if
lock
:
slapgrid
.
wait
()
date
=
datetime
.
datetime
.
now
().
strftime
(
"%Y-%m-%d %H:%M:%S"
)
slapgridResultToFile
(
config
,
"instance"
,
slapgrid
.
returncode
,
date
)
return
(
True
if
slapgrid
.
returncode
==
0
else
False
)
else
:
thread
.
start_new_thread
(
waitProcess
,
(
config
,
slapgrid
,
"instance"
))
return
False
...
...
@@ -896,3 +926,17 @@ def setupDefaultSR(config):
configNewSR(config, config['
default_sr
'])
if config['
auto_deploy
']:
thread.start_new_thread(buildAndRun, (config,))
def setMiniShellHistory(config, command):
history_max_size = 10
command = command + "
\
n
"
history_file = config['
minishell_history_file
']
if os.path.exists(history_file):
history = open(history_file, 'r').readlines()
if len(history) >= history_max_size:
del history[0]
else:
history = []
history.append(command)
open(history_file, '
w
+
').write(''.join(history))
slapos/runner/views.py
View file @
8cebacc6
...
...
@@ -6,6 +6,7 @@
import
json
import
os
import
shutil
import
subprocess
import
thread
import
urllib
...
...
@@ -14,7 +15,8 @@ from flask import (Flask, request, redirect, url_for, render_template,
from
slapos.runner.process
import
killRunningProcess
from
slapos.runner.utils
import
(
checkSoftwareFolder
,
configNewSR
,
createNewUser
,
getProfilePath
,
createNewUser
,
getBuildAndRunParams
,
getProfilePath
,
getSlapgridResult
,
listFolder
,
getBuildAndRunParams
,
getProjectTitle
,
getRcode
,
getSession
,
getSlapStatus
,
getSvcStatus
,
...
...
@@ -26,6 +28,7 @@ from slapos.runner.utils import (checkSoftwareFolder, configNewSR,
removeSoftwareByName
,
runInstanceWithLock
,
runSoftwareWithLock
,
runSlapgridUntilSuccess
,
saveSession
,
saveBuildAndRunParams
,
setMiniShellHistory
,
svcStartStopProcess
,
svcStopAll
,
tail
,
updateInstanceParameter
)
...
...
@@ -93,6 +96,10 @@ def myAccount():
params
=
getBuildAndRunParams
(
app
.
config
))
def
getSlapgridParameters
():
return
jsonify
(
getBuildAndRunParams
(
app
.
config
))
def
manageRepository
():
public_key
=
open
(
app
.
config
[
'public_key'
]).
read
()
account
=
getSession
(
app
.
config
)
...
...
@@ -215,6 +222,8 @@ def getFileLog():
else
:
file_path
=
realpath
(
app
.
config
,
logfile
)
try
:
if
not
os
.
path
.
exists
(
file_path
):
raise
IOError
if
not
isText
(
file_path
):
return
jsonify
(
code
=
0
,
result
=
"Can not open binary file, please select a text file!"
)
...
...
@@ -446,7 +455,15 @@ def slapgridResult():
if
os
.
path
.
exists
(
app
.
config
[
log_file
]):
log_result
=
readFileFrom
(
open
(
app
.
config
[
log_file
]),
int
(
request
.
form
[
'position'
]))
return
jsonify
(
software
=
software_state
,
instance
=
instance_state
,
build_result
=
getSlapgridResult
(
app
.
config
,
'software'
)
run_result
=
getSlapgridResult
(
app
.
config
,
'instance'
)
software_info
=
{
'state'
:
software_state
,
'last_build'
:
build_result
[
'last_build'
],
'success'
:
build_result
[
'success'
]}
instance_info
=
{
'state'
:
instance_state
,
'last_build'
:
run_result
[
'last_build'
],
'success'
:
run_result
[
'success'
]}
return
jsonify
(
software
=
software_info
,
instance
=
instance_info
,
result
=
(
instance_state
or
software_state
),
content
=
log_result
)
...
...
@@ -691,6 +708,47 @@ def isSRReady():
return
isSoftwareReleaseReady
(
app
.
config
)
def
runCommand
():
cwd
=
open
(
app
.
config
[
'minishell_cwd_file'
],
'r'
).
read
().
strip
()
command
=
request
.
form
.
get
(
"command"
,
''
).
strip
()
parsed_commands
=
command
.
split
(
';'
);
# does the user want to change current directory ?
for
cmd
in
parsed_commands
:
if
'cd'
==
cmd
[:
2
]:
cmd
=
cmd
.
split
(
' '
);
real_cmd
=
cmd
[:]
if
len
(
cmd
)
==
1
:
cmd
.
append
(
os
.
environ
.
get
(
'HOME'
))
# shorten directory's name, to avoid things like : /a/../b
cd_dir
=
os
.
path
.
realpath
(
os
.
path
.
join
(
cwd
,
cmd
[
1
]))
if
os
.
path
.
exists
(
cd_dir
)
and
os
.
path
.
isdir
(
cd_dir
):
cwd
=
cd_dir
# save new cwd in the config file
open
(
app
.
config
[
'minishell_cwd_file'
],
'w'
).
write
(
cwd
)
# if the command was just cd, execute it. Otherwise, execute the rest
command
=
command
.
replace
(
' '
.
join
(
real_cmd
),
''
).
strip
(
';'
)
if
not
command
:
return
jsonify
(
path
=
cwd
,
data
=
"Changed directory, now in : "
+
cwd
)
try
:
setMiniShellHistory
(
app
.
config
,
command
)
command
=
"timeout 600 "
+
command
return
jsonify
(
path
=
cwd
,
data
=
subprocess
.
check_output
(
command
,
stderr
=
subprocess
.
STDOUT
,
shell
=
True
,
cwd
=
cwd
))
except
subprocess
.
CalledProcessError
as
e
:
error
=
"Error : process exited with exit code "
+
str
(
e
.
returncode
)
+
\
"
\
n
Process says :
\
n
"
+
e
.
output
return
error
def
getMiniShellHistory
():
history_file
=
app
.
config
[
'minishell_history_file'
]
if
not
os
.
path
.
exists
(
history_file
):
return
""
history
=
open
(
history_file
,
'r'
).
readlines
()
for
line
,
text
in
enumerate
(
history
):
history
[
line
]
=
text
.
strip
()
return
json
.
dumps
(
history
)
#Setup List of URLs
app
.
add_url_rule
(
'/'
,
'home'
,
home
)
app
.
add_url_rule
(
'/browseWorkspace'
,
'browseWorkspace'
,
browseWorkspace
)
...
...
@@ -773,3 +831,6 @@ app.add_url_rule("/editFile", 'editFile', editFile, methods=['GET'])
app
.
add_url_rule
(
'/shell'
,
'shell'
,
shell
)
app
.
add_url_rule
(
'/isSRReady'
,
'isSRReady'
,
isSRReady
)
app
.
add_url_rule
(
'/addUser'
,
'addUser'
,
addUser
,
methods
=
[
'POST'
])
app
.
add_url_rule
(
'/getSlapgridParameters'
,
'getSlapgridParameters'
,
getSlapgridParameters
,
methods
=
[
'GET'
])
app
.
add_url_rule
(
'/runCommand'
,
'runCommand'
,
runCommand
,
methods
=
[
'POST'
])
app
.
add_url_rule
(
"/getMiniShellHistory"
,
'getMiniShellHistory'
,
getMiniShellHistory
,
methods
=
[
'GET'
])
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