129 lines
3.1 KiB
Python
129 lines
3.1 KiB
Python
|
from bottle import route, run, request, Response, post
|
||
|
from subprocess import call, CalledProcessError
|
||
|
from threading import Thread
|
||
|
from datetime import datetime
|
||
|
import os
|
||
|
|
||
|
class Logger:
|
||
|
def log(self,text):
|
||
|
pass
|
||
|
|
||
|
class NullLogger(Logger):
|
||
|
pass
|
||
|
|
||
|
class StdoutLogger(Logger):
|
||
|
def log(self,text):
|
||
|
print text
|
||
|
|
||
|
class FileLogger(Logger):
|
||
|
def __init__(self,filepath):
|
||
|
self.fh = open(filepath,"a")
|
||
|
|
||
|
def log(self,text):
|
||
|
self.fh.write("[%s] %s\n" % (datetime.now().strftime("%d.%m.%Y %H:%M"), text))
|
||
|
|
||
|
class Command:
|
||
|
def run(self):
|
||
|
pass
|
||
|
|
||
|
class ExecCommand(Command):
|
||
|
def __init__(self,execp,shell=False):
|
||
|
self.execp = execp
|
||
|
self.shell = shell
|
||
|
|
||
|
def run(self, logger):
|
||
|
try:
|
||
|
logger.log( "Running %s with shell=%s" % ( str(self.execp), str(self.shell) ) )
|
||
|
call(self.execp,shell=self.shell)
|
||
|
logger.log( "Execution succeeded." )
|
||
|
return True
|
||
|
except CalledProcessError as e:
|
||
|
logger.log( "Exception failed. (returncode=%d, cmd=%s, output=%s)" % (e.returncode, e.cmd, e.output) )
|
||
|
return False
|
||
|
|
||
|
class GitPullCommand(ExecCommand):
|
||
|
def __init__(self):
|
||
|
ExecCommand.__init__(self,"git pull",shell=True)
|
||
|
|
||
|
class Deploy:
|
||
|
def __init__(self,key,branch=None,commands=[],cwd=None):
|
||
|
self.key = key
|
||
|
self.branch = branch
|
||
|
self.commands = commands
|
||
|
self.cwd = cwd
|
||
|
|
||
|
def invoke(self, logger):
|
||
|
if self.cwd is not None:
|
||
|
os.chdir(self.cwd)
|
||
|
for command in self.commands:
|
||
|
if command.run(logger) == False:
|
||
|
return
|
||
|
|
||
|
def run(self,logger=NullLogger(),threaded=True):
|
||
|
if threaded:
|
||
|
Thread(target=self.invoke,args=(logger,)).start()
|
||
|
else:
|
||
|
self.invoke(logger)
|
||
|
|
||
|
class DeployManager:
|
||
|
def __init__(self, deploys=[]):
|
||
|
self.deploys = {}
|
||
|
self.addAll(deploys)
|
||
|
|
||
|
def addAll(self, deploys=[]):
|
||
|
for deploy in deploys:
|
||
|
self.add(deploy)
|
||
|
|
||
|
def add(self, deploy):
|
||
|
self.deploys[(deploy.key,deploy.branch)] = deploy
|
||
|
|
||
|
def get(self, key, branch=None):
|
||
|
if self.deploys.has_key( (key,branch) ):
|
||
|
return self.deploys[ (key,branch) ]
|
||
|
elif self.deploys.has_key( (key,None) ):
|
||
|
return self.deploys[ (key,None) ]
|
||
|
else:
|
||
|
return None
|
||
|
|
||
|
def run(self, key, branch=None, threaded=True, logger=NullLogger()):
|
||
|
deploy = self.get(key=key, branch=branch)
|
||
|
if deploy is not None:
|
||
|
deploy.run(threaded=threaded, logger=logger)
|
||
|
return True
|
||
|
else:
|
||
|
return False
|
||
|
|
||
|
class Object:
|
||
|
pass
|
||
|
|
||
|
server = Object()
|
||
|
|
||
|
@post('/deploy/<key>')
|
||
|
def serve(key=None):
|
||
|
if key is None:
|
||
|
return Response(body="No key.",status=404)
|
||
|
|
||
|
server.logger.log("Deploy key: %s" % key)
|
||
|
|
||
|
if not request.json.has_key("ref"):
|
||
|
return Response(body="No ref.",status=500)
|
||
|
|
||
|
branch = request.json["ref"].split("/")[-1]
|
||
|
|
||
|
if server.deploymanager.run(key = key, branch = branch, logger = server.logger):
|
||
|
server.logger.log("Done.")
|
||
|
return "Done."
|
||
|
else:
|
||
|
server.logger.log("Failed.")
|
||
|
return Response(body="key %s not found" % key, status=404 )
|
||
|
|
||
|
def deploy(port=1234,deploys=[],logger=NullLogger()):
|
||
|
server.deploymanager = DeployManager(deploys)
|
||
|
server.logger = logger
|
||
|
|
||
|
run(host="",port=port)
|
||
|
|
||
|
deploy(deploys=[
|
||
|
Deploy(key="foo",commands=[ExecCommand("touch fu.txt",shell=True)], cwd="/home/madmaurice/Public/")
|
||
|
],logger=FileLogger("deploy.log"))
|