one-file-projects/deployserver.py

130 lines
3.2 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="frontend",branch="master",commands=[ExecCommand("./deploy_master.sh",shell=True)]),
Deploy(key="frontend",branch="develop",commands=[ExecCommand("./deploy_develop.sh",shell=True)])
],logger=FileLogger("deploy.log"))