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
Thomas Leymonerie
slapos.toolbox
Commits
decbd4b3
Commit
decbd4b3
authored
Jun 29, 2012
by
Alain Takoudjou
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
Adding comments
parent
5d472df2
Changes
3
Hide whitespace changes
Inline
Side-by-side
Showing
3 changed files
with
205 additions
and
4 deletions
+205
-4
slapos/runner/gittools.py
slapos/runner/gittools.py
+33
-0
slapos/runner/utils.py
slapos/runner/utils.py
+161
-4
slapos/runner/views.py
slapos/runner/views.py
+11
-0
No files found.
slapos/runner/gittools.py
View file @
decbd4b3
...
...
@@ -23,6 +23,15 @@ class Popen(subprocess.Popen):
self
.
stdin
=
None
def
cloneRepo
(
data
):
"""Clonne a repository
Args:
data: a dictionnary of parameters to use:
data['path'] is the path of the new project
data['repo'] is the url of the repository to be cloned
data['email'] is the user email
data['user'] is the name of the user
Returns:
a jsonify data"""
workDir
=
data
[
'path'
]
if
not
workDir
:
return
jsonify
(
code
=
0
,
...
...
@@ -47,6 +56,11 @@ def cloneRepo(data):
return
jsonify
(
code
=
code
,
result
=
json
)
def
gitStatus
(
project
):
"""Run git status and return status of specified project folder
Args:
project: path of the projet ti get status
Returns:
a parsed string that contains the result of git status"""
code
=
0
json
=
""
try
:
...
...
@@ -61,6 +75,12 @@ def gitStatus(project):
return
jsonify
(
code
=
code
,
result
=
json
,
branch
=
branch
,
dirty
=
isdirty
)
def
switchBranch
(
project
,
name
):
"""Switch a git branch
Args:
project: directory of the local git repository
name: switch from current branch to `name` branch
Returns:
a jsonify data"""
code
=
0
json
=
""
try
:
...
...
@@ -78,6 +98,13 @@ def switchBranch(project, name):
return
jsonify
(
code
=
code
,
result
=
json
)
def
addBranch
(
project
,
name
,
onlyCheckout
=
False
):
"""Add new git branch to the repository
Args:
project: directory of the local git repository
name: name of the new branch
onlyCheckout: if True then the branch `name` is created before checkout
Returns:
a jsonify data"""
code
=
0
json
=
""
try
:
...
...
@@ -93,6 +120,7 @@ def addBranch(project, name, onlyCheckout=False):
return
jsonify
(
code
=
code
,
result
=
json
)
def
getDiff
(
project
):
"""Get git diff for the specified project directory"""
result
=
""
try
:
repo
=
Repo
(
project
)
...
...
@@ -104,6 +132,10 @@ def getDiff(project):
return
result
def
gitPush
(
project
,
msg
):
"""Commit and Push changes for the specified repository
Args:
project: directory of the local repository
msg: commit message"""
code
=
0
json
=
""
undo_commit
=
False
...
...
@@ -145,5 +177,6 @@ def gitPull(project):
return
jsonify
(
code
=
code
,
result
=
result
)
def
safeResult
(
result
):
"""Parse string and remove credential of the user"""
regex
=
re
.
compile
(
"(https:
\
/
\
/)([
\
w
\
d
\
._-]+:[
\
w
\
d
\
._-]+)
\
@([
\
S]+
\
s)
"
, re.VERBOSE)
return regex.sub(r'
\
1
\
3
', result)
\ No newline at end of file
slapos/runner/utils.py
View file @
decbd4b3
...
...
@@ -41,6 +41,17 @@ def html_escape(text):
return
""
.
join
(
html_escape_table
.
get
(
c
,
c
)
for
c
in
text
)
def
checkLogin
(
config
,
login
,
pwd
):
"""
User authentication method
Args:
config: Slaprunner configuration.
login: username of the user.
pwd: password associate to username.
Returns:
a list of user informations or False if authentication fail.
"""
user
=
getSession
(
config
)
salt
=
"runner81"
#to be changed
current_pwd
=
hashlib
.
md5
(
salt
+
pwd
).
hexdigest
()
...
...
@@ -49,6 +60,11 @@ def checkLogin(config, login, pwd):
return
False
def
getSession
(
config
):
"""
Get the session data of current user.
Returns:
a list of user informations or False if fail to read data.
"""
user_path
=
os
.
path
.
join
(
config
[
'runner_workdir'
],
'.users'
)
user
=
""
if
os
.
path
.
exists
(
user_path
):
...
...
@@ -63,6 +79,17 @@ def getSession(config):
return
user
def
saveSession
(
config
,
session
,
account
):
"""
Save account information for the current user
Args:
config: Slaprunner configuration
session: Flask session
account: New session data to be save
Returns:
True if all goes well or str (error message) if fail
"""
user
=
os
.
path
.
join
(
config
[
'runner_workdir'
],
'.users'
)
backup
=
False
try
:
...
...
@@ -88,6 +115,10 @@ def saveSession(config, session, account):
return
str
(
e
)
def
updateProxy
(
config
):
"""
Configure Slapos Node computer and partitions.
Send current Software Release to Slapproxy for compilation and deployment.
"""
if
not
os
.
path
.
exists
(
config
[
'instance_root'
]):
os
.
mkdir
(
config
[
'instance_root'
])
slap
=
slapos
.
slap
.
slap
()
...
...
@@ -141,6 +172,7 @@ def updateProxy(config):
return
True
def
readPid
(
file
):
"""Read process pid from file `file`"""
if
os
.
path
.
exists
(
file
):
data
=
open
(
file
).
read
().
strip
()
try
:
...
...
@@ -151,9 +183,17 @@ def readPid(file):
def
writePid
(
file
,
pid
):
"""Save process pid into a file `file`"""
open
(
file
,
'w'
).
write
(
str
(
pid
))
def
updateInstanceParameter
(
config
,
software_type
=
None
):
"""
Reconfigure Slapproxy to re-deploy current Software Instance with parameters.
Args:
config: Slaprunner configuration.
software_type: reconfigure Software Instance with software type.
"""
slap
=
slapos
.
slap
.
slap
()
slap
.
initializeConnection
(
config
[
'master_url'
])
#Get current software release profile
...
...
@@ -163,7 +203,7 @@ def updateInstanceParameter(config, software_type=None):
profile
=
realpath
(
config
,
os
.
path
.
join
(
software_folder
,
config
[
'software_profile'
]))
except
:
r
eturn
False
r
aise
Exception
(
"Software Release profile not found"
)
#get instance parameter
param_path
=
os
.
path
.
join
(
config
[
'runner_workdir'
],
".parameter.xml"
)
xml_result
=
readParameters
(
param_path
)
...
...
@@ -175,6 +215,7 @@ def updateInstanceParameter(config, software_type=None):
filter_kw
=
None
,
state
=
None
,
shared
=
False
)
def
startProxy
(
config
):
"""Start Slapproxy server"""
proxy_pid
=
os
.
path
.
join
(
config
[
'runner_workdir'
],
'proxy.pid'
)
pid
=
readPid
(
proxy_pid
)
running
=
False
...
...
@@ -193,6 +234,7 @@ def startProxy(config):
def
stopProxy
(
config
):
"""Stop Slapproxy server"""
pid
=
readPid
(
os
.
path
.
join
(
config
[
'runner_workdir'
],
'proxy.pid'
))
if
pid
:
try
:
...
...
@@ -202,10 +244,15 @@ def stopProxy(config):
def
removeProxyDb
(
config
):
"""Remove Slapproxy database, this is use to initialize proxy for example when
configuring new Software Release"""
if
os
.
path
.
exists
(
config
[
'database_uri'
]):
os
.
unlink
(
config
[
'database_uri'
])
def
isSoftwareRunning
(
config
):
"""
Return True if slapgrid-sr is still running and false if slapgrid if not
"""
slapgrid_pid
=
os
.
path
.
join
(
config
[
'runner_workdir'
],
'slapgrid-sr.pid'
)
pid
=
readPid
(
slapgrid_pid
)
if
pid
:
...
...
@@ -221,6 +268,10 @@ def isSoftwareRunning(config):
def
runSoftwareWithLock
(
config
):
"""
Use Slapgrid to compile current Software Release and wait until
compilation is done
"""
slapgrid_pid
=
os
.
path
.
join
(
config
[
'runner_workdir'
],
'slapgrid-sr.pid'
)
if
not
isSoftwareRunning
(
config
):
if
not
os
.
path
.
exists
(
config
[
'software_root'
]):
...
...
@@ -262,6 +313,9 @@ def runSoftwareWithLock(config):
def
isInstanceRunning
(
config
):
"""
Return True if slapgrid-cp is still running and false if slapgrid if not
"""
slapgrid_pid
=
os
.
path
.
join
(
config
[
'runner_workdir'
],
'slapgrid-cp.pid'
)
pid
=
readPid
(
slapgrid_pid
)
if
pid
:
...
...
@@ -276,6 +330,7 @@ def isInstanceRunning(config):
return
running
def
killRunningSlapgrid
(
config
,
ptype
):
"""Kill slapgrid process and all running children process"""
slapgrid_pid
=
os
.
path
.
join
(
config
[
'runner_workdir'
],
ptype
)
pid
=
readPid
(
slapgrid_pid
)
if
pid
:
...
...
@@ -304,6 +359,10 @@ def pidppid(pid):
return
list
(
int
(
p
)
for
p
,
pp
in
ppid
if
int
(
pp
)
==
pid
)
def
runInstanceWithLock
(
config
):
"""
Use Slapgrid to deploy current Software Release and wait until
deployment is done.
"""
slapgrid_pid
=
os
.
path
.
join
(
config
[
'runner_workdir'
],
'slapgrid-cp.pid'
)
if
not
isInstanceRunning
(
config
):
startProxy
(
config
)
...
...
@@ -317,13 +376,24 @@ def runInstanceWithLock(config):
return
True
return
False
def
getProfilePath
(
peojectDir
,
profile
):
if
not
os
.
path
.
exists
(
os
.
path
.
join
(
peojectDir
,
".project"
)):
def
getProfilePath
(
projectDir
,
profile
):
"""
Return the path of the current Software Release `profile`
Args:
projectDir: Slaprunner workspace location.
profile: file to search into the workspace.
Returns:
String, path of current Software Release profile
"""
if
not
os
.
path
.
exists
(
os
.
path
.
join
(
projectDir
,
".project"
)):
return
False
projectFolder
=
open
(
os
.
path
.
join
(
p
e
ojectDir
,
".project"
)).
read
()
projectFolder
=
open
(
os
.
path
.
join
(
p
r
ojectDir
,
".project"
)).
read
()
return
os
.
path
.
join
(
projectFolder
,
profile
)
def
getSlapStatus
(
config
):
"""Return all Slapos Partitions with associate informations"""
slap
=
slapos
.
slap
.
slap
()
slap
.
initializeConnection
(
config
[
'master_url'
])
partition_list
=
[]
...
...
@@ -354,10 +424,12 @@ def runBuildoutAnnotate(config):
return
False
def
svcStopAll
(
config
):
"""Stop all Instance process on this computer"""
return
Popen
([
config
[
'supervisor'
],
config
[
'configuration_file_path'
],
'shutdown'
]).
communicate
()[
0
]
def
removeInstanceRoot
(
config
):
"""Clean instance directory and stop all its running process"""
if
os
.
path
.
exists
(
config
[
'instance_root'
]):
svcStopAll
(
config
)
for
root
,
dirs
,
files
in
os
.
walk
(
config
[
'instance_root'
]):
...
...
@@ -369,6 +441,7 @@ def removeInstanceRoot(config):
shutil
.
rmtree
(
config
[
'instance_root'
])
def
getSvcStatus
(
config
):
"""Return all Softwares Instances process Informations"""
result
=
Popen
([
config
[
'supervisor'
],
config
[
'configuration_file_path'
],
'status'
]).
communicate
()[
0
]
regex
=
"(^unix:.+
\
.socke
t
)|(^error:).*$"
...
...
@@ -382,15 +455,40 @@ def getSvcStatus(config):
return supervisord
def getSvcTailProcess(config, process):
"""Get log for the specifie process
Args:
config: Slaprunner configuration
process: process name. this value is pass to supervisord.
Returns:
a string that contains the log of the process.
"""
return Popen([config['
supervisor
'], config['
configuration_file_path
'],
"tail", process]).communicate()[0]
def svcStartStopProcess(config, process, action):
"""Send start or stop process command to supervisord
Args:
config: Slaprunner configuration.
process: process to start or stop.
action: current state which is used to generate the new process state.
"""
cmd = {"RESTART":"restart", "STOPPED":"start", "RUNNING":"stop", "EXITED":"start", "STOP":"stop"}
return Popen([config['
supervisor
'], config['
configuration_file_path
'],
cmd[action], process]).communicate()[0]
def getFolderContent(config, folder):
"""
Read all file and folder into specified directory
Args:
config: Slaprunner configuration.
folder: the directory to read.
Returns:
Html formated string or error message when fail.
"""
r=['
<
ul
class
=
"jqueryFileTree"
style
=
"display: none;"
>
']
try:
folder = str(folder)
...
...
@@ -418,6 +516,16 @@ def getFolderContent(config, folder):
return jsonify(result=''.join(r))
def getFolder(config, folder):
"""
Read list of folder for the specified directory
Args:
config: Slaprunner configuration.
folder: the directory to read.
Returns:
Html formated string or error message when fail.
"""
r=['
<
ul
class
=
"jqueryFileTree"
style
=
"display: none;"
>
']
try:
folder = str(folder)
...
...
@@ -442,6 +550,13 @@ def getFolder(config, folder):
return jsonify(result=''.join(r))
def getProjectList(folder):
"""Return the list of projet (folder) into the workspace
Agrs:
folder: path of the workspace
Returns:
a list that contains each folder name.
"""
project = []
project_list = sorted(os.listdir(folder), key=str.lower)
for elt in project_list:
...
...
@@ -449,6 +564,14 @@ def getProjectList(folder):
return project
def configNewSR(config, projectpath):
"""Configure a Software Release as current Software Release
Args:
config: slaprunner configuration
projectpath: path of the directory that contains the software realease to configure
Returns:
True if all is done well, otherwise return false.
"""
folder = realpath(config, projectpath)
if folder:
if isInstanceRunning(config):
...
...
@@ -465,6 +588,13 @@ def configNewSR(config, projectpath):
return False
def newSoftware(folder, config, session):
"""
Create a new Software Release folder with default profiles
Args:
folder: directory of the new software release
config: slraprunner configuration
session: Flask session directory"""
json = ""
code = 0
runner_dir = config['
runner_workdir
']
...
...
@@ -498,12 +628,14 @@ def newSoftware(folder, config, session):
return jsonify(code=code, result=json)
def checkSoftwareFolder(path, config):
"""Check id `path` is a valid Software Release folder"""
realdir = realpath(config, path)
if realdir and os.path.exists(os.path.join(realdir, config['
software_profile
'])):
return jsonify(result=path)
return jsonify(result="")
def getProjectTitle(config):
"""Generate the name of the current software Release (for slaprunner UI)"""
conf = os.path.join(config['
runner_workdir
'], ".project")
if os.path.exists(conf):
project = open(conf, "r").read().split("/")
...
...
@@ -512,6 +644,7 @@ def getProjectTitle(config):
return "No Profile"
def getSoftwareReleaseName(config):
"""Get the name of the current Software Release"""
sr_profile = os.path.join(config['
runner_workdir
'], ".project")
if os.path.exists(sr_profile):
project = open(sr_profile, "r").read().split("/")
...
...
@@ -520,6 +653,12 @@ def getSoftwareReleaseName(config):
return "No_name"
def loadSoftwareData(runner_dir):
"""Get All Compiled Softwares Releases name and directory
Agrs:
runner_dir: base directory of slapos web runner.
Returns:
a dictionnary that contains all compiled Software Release with path"""
import pickle
file_path = os.path.join(runner_dir, '
.
softdata
')
if not os.path.exists(file_path):
...
...
@@ -530,6 +669,12 @@ def loadSoftwareData(runner_dir):
return data
def writeSoftwareData(runner_dir, data):
"""Save the list of compiled Software Release into a file
Args:
runner_dir: base directory of slapos web runner.
data: dictionnary data about real name and directory of each software release
"""
import pickle
file_path = os.path.join(runner_dir, '
.
softdata
')
pkl_file = open(file_path, '
wb
')
...
...
@@ -538,6 +683,11 @@ def writeSoftwareData(runner_dir, data):
pkl_file.close()
def removeSoftwareByName(config, folderName):
"""Remove all content of the specified software release
Args:
config: slaprunner configuration
foldername: the name given to the software release"""
if isSoftwareRunning(config) or isInstanceRunning(config):
raise Exception("Software installation or instantiation in progress, cannot remove")
path = os.path.join(config['
software_root
'], folderName)
...
...
@@ -662,6 +812,13 @@ def realpath(config, path, check_exist=True):
return False
def readParameters(path):
"""Read Instance parameters stored into a local file.
Agrs:
path: path of the xml file that contains parameters
Return:
a dictionnary of instance parameters."""
if os.path.exists(path):
try:
xmldoc = minidom.parse(path)
...
...
slapos/runner/views.py
View file @
decbd4b3
...
...
@@ -77,6 +77,7 @@ def inspectSoftware():
return
render_template
(
'runResult.html'
,
softwareRoot
=
'software_root'
,
softwares
=
loadSoftwareData
(
app
.
config
[
'runner_workdir'
]))
#remove content of compiled software release
@
app
.
route
(
'/removeSoftware'
)
def
removeSoftware
():
file_config
=
os
.
path
.
join
(
app
.
config
[
'runner_workdir'
],
".softdata"
)
...
...
@@ -114,6 +115,7 @@ def editInstanceProfile():
return
render_template
(
'updateInstanceProfile.html'
,
workDir
=
'workspace'
,
profile
=
profile
,
projectList
=
getProjectList
(
app
.
config
[
'workspace'
]))
# get status of all computer partitions and process state
@
app
.
route
(
'/inspectInstance'
,
methods
=
[
'GET'
])
def
inspectInstance
():
file_content
=
''
...
...
@@ -127,6 +129,7 @@ def inspectInstance():
file_path
=
file_content
,
supervisor
=
result
,
slap_status
=
getSlapStatus
(
app
.
config
),
supervisore
=
result
,
partition_amount
=
app
.
config
[
'partition_amount'
])
#Reload instance process ans returns new value to ajax
@
app
.
route
(
'/supervisordStatus'
,
methods
=
[
'GET'
])
def
supervisordStatus
():
result
=
getSvcStatus
(
app
.
config
)
...
...
@@ -253,6 +256,7 @@ def getProjectStatus():
else
:
return
jsonify
(
code
=
0
,
result
=
"Can not read folder: Permission Denied"
)
#view for current software release files
@
app
.
route
(
"/editCurrentProject"
)
def
editCurrentProject
():
project
=
os
.
path
.
join
(
app
.
config
[
'runner_workdir'
],
".project"
)
...
...
@@ -262,6 +266,7 @@ def editCurrentProject():
projectList
=
getProjectList
(
app
.
config
[
'workspace'
]))
return
redirect
(
url_for
(
'configRepo'
))
#create file or directory
@
app
.
route
(
"/createFile"
,
methods
=
[
'POST'
])
def
createFile
():
path
=
realpath
(
app
.
config
,
request
.
form
[
'file'
],
False
)
...
...
@@ -277,6 +282,7 @@ def createFile():
except
Exception
,
e
:
return
jsonify
(
code
=
0
,
result
=
str
(
e
))
#remove file or directory
@
app
.
route
(
"/removeFile"
,
methods
=
[
'POST'
])
def
removeFile
():
try
:
...
...
@@ -296,6 +302,7 @@ def removeSoftwareDir():
except
Exception
,
e
:
return
jsonify
(
code
=
0
,
result
=
str
(
e
))
#read file and return content to ajax
@
app
.
route
(
"/getFileContent"
,
methods
=
[
'POST'
])
def
getFileContent
():
file_path
=
realpath
(
app
.
config
,
request
.
form
[
'file'
])
...
...
@@ -379,6 +386,7 @@ def getmd5sum():
else
:
return
jsonify
(
code
=
0
,
result
=
"Can not get md5sum for this file!"
)
#return informations about state of slapgrid process
@
app
.
route
(
"/slapgridResult"
,
methods
=
[
'POST'
])
def
slapgridResult
():
software_state
=
isSoftwareRunning
(
app
.
config
)
...
...
@@ -415,6 +423,7 @@ def getPath():
else
:
return
jsonify
(
code
=
1
,
result
=
realfile
)
#update instance parameter into a local xml file
@
app
.
route
(
"/saveParameterXml"
,
methods
=
[
'POST'
])
def
saveParameterXml
():
project
=
os
.
path
.
join
(
app
.
config
[
'runner_workdir'
],
".project"
)
...
...
@@ -441,6 +450,7 @@ def saveParameterXml():
return
jsonify
(
code
=
0
,
result
=
"An error occurred while applying your settings!<br/>"
+
str
(
e
))
return
jsonify
(
code
=
1
,
result
=
""
)
#read instance parameters into the local xml file and return a dict
@
app
.
route
(
"/getParameterXml/<request>"
,
methods
=
[
'GET'
])
def
getParameterXml
(
request
):
param_path
=
os
.
path
.
join
(
app
.
config
[
'runner_workdir'
],
".parameter.xml"
)
...
...
@@ -457,6 +467,7 @@ def getParameterXml(request):
else
:
return
jsonify
(
code
=
1
,
result
=
parameters
)
#update user account data
@
app
.
route
(
"/updateAccount"
,
methods
=
[
'POST'
])
def
updateAccount
():
account
=
[]
...
...
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