#!/usr/local/bin/python # -*- coding:utf-8 -*- import time import paramiko from subprocess import CalledProcessError from web.utils.log import Logger logger = Logger("web.utils.remoteshell") __author__ = 'Rocky Peng' class RemoteShell(object): def __init__(self, host, port, user, passwd): self.host = host self.port = port self.user = user self.passwd = passwd self.connect() def connect(self): self.ssh = paramiko.SSHClient() self.ssh.set_missing_host_key_policy(paramiko.AutoAddPolicy()) self.ssh.connect(self.host, self.port, self.user, self.passwd, timeout=10) def exec_command(self, shell): logger.debug("remote shell: %s" % shell) # stdin, stdout, stderr = self.ssh.exec_command(shell)
# -*- coding:utf-8 -*- __author__ = 'Rocky Peng' import traceback import json import time import random import string from hashlib import md5 from web.utils.log import Logger logger = Logger("WEBHOOK") from web import app from web.services.users import users from web.services.hosts import hosts from web.services.deploys import deploys from web.services.projects import projects from web.utils.error import Error from .login import authorize from flask import request, jsonify, g #@app.route('/api/deploy/push_events', methods=["POST"]) #@authorize #def push_events(): # project = Project(user_id=g.user.get_id()) # args = request.args.to_dict() # data = request.json # logger.debug(args) # logger.debug(data)
#!/usr/local/bin/python # -*- coding:utf-8 -*- from web.utils.localshell import LocalShell from web.utils.error import Error from web.utils.log import Logger logger = Logger("web.utils.git") __author__ = 'Rocky Peng' class Git(object): def __init__(self, dest, url): self.dest = dest self.url = url def local_branch(self): shell = "cd {0} && git fetch -q -a && git branch".format(self.dest) stdout = LocalShell.check_output(shell, shell=True) stdout = stdout.strip().split("\n") stdout = [s.strip("* ") for s in stdout] return stdout def remote_branch(self): shell = "cd {0} && git fetch -q -a && git branch -r".format(self.dest) stdout = LocalShell.check_output(shell, shell=True) stdout = stdout.strip().split("\n") stdout = [s.strip(" ").split("/", 1)[1] for s in stdout if "->" not in s] return stdout def tag(self):
#!/usr/local/bin/python # -*- coding:utf-8 -*- from web import db from web.models.sessions import Sessions from .base import Base from web.utils.log import Logger logger = Logger("web.services.sessions") __author__ = 'Rocky Peng' class SessionsService(Base): __model__ = Sessions sessions = SessionsService()
import sys import time import random import string from hashlib import md5 from web import db from web.utils.log import Logger from web.models.users import Users from web.services.hosts import hosts from web.services.projects import projects from .base import Base from web.utils.error import Error from .sessions import sessions logger = Logger("web.services.users") if sys.version_info > (3, ): string.letters = string.ascii_letters __author__ = 'Rocky Peng' class UsersService(Base): __model__ = Users def login(self, username, password): password = md5(password.encode("utf-8")).hexdigest().upper() user = self.first(name=username, password=password) if user is None: raise Error(13000) session = sessions.first(user_id=user.id) expired = datetime.fromtimestamp(time.time() +
#!/usr/local/bin/python # -*- coding:utf-8 -*- __author__ = 'Rocky Peng' from web import db from web.utils.log import Logger from web.models.sessions import Sessions from .base import Base logger = Logger("session service") class SessionsService(Base): __model__ = Sessions sessions = SessionsService()
#!/usr/local/bin/python # -*- coding:utf-8 -*- __author__ = 'Rocky Peng' from web import db from web.utils.log import Logger from web.models.hosts import Hosts from .base import Base logger = Logger("host service") class HostsService(Base): __model__ = Hosts hosts = HostsService()
#!/usr/local/bin/python # -*- coding:utf-8 -*- __author__ = 'Rocky Peng' from web import db from web.utils.log import Logger from web.models.projects import Projects from web.utils.git import Git from .base import Base logger = Logger("project service") class ProjectsService(Base): __model__ = Projects def git_clone(self, project_id): project = self.get(project_id) git = Git(project.checkout_dir, project.repo_url) git.clone() def git_branch(self, project_id): project = self.get(project_id) git = Git(project.checkout_dir, project.repo_url) return git.branch() def git_log(self, project_id, branch): project = self.get(project_id) git = Git(project.checkout_dir, project.repo_url) return git.log(branch)
#!/usr/local/bin/python # -*- coding:utf-8 -*- from subprocess import Popen, PIPE, CalledProcessError from web.utils.log import Logger logger = Logger("web.utils.localshell") __author__ = 'Rocky Peng' class LocalShell(object): @staticmethod def check_output(*args, **kargs): cmd = kargs.get("args") or args[0] logger.debug("local shell: %s" % cmd) process = Popen(*args, stdout=PIPE, stderr=PIPE, **kargs) stdout, stderr = process.communicate() stdout = stdout.decode("utf-8") stderr = stderr.decode("utf-8") rc = process.poll() logger.debug("rc: %d" % rc) logger.debug("stdout: %s" % stdout) logger.warn("stderr: %s" % stderr) if rc: raise CalledProcessError(rc, cmd, stdout) return stdout @staticmethod def call(*args, **kargs): cmd = kargs.get("args") or args[0] logger.debug("local shell: %s" % cmd)
#!/usr/local/bin/python # -*- coding:utf-8 -*- import traceback import os import threading from web import db from web.models.deploys import Deploys from .base import Base from web.utils.git import Git from web.utils.localshell import LocalShell from web.utils.remoteshell import RemoteShell from web.utils.error import Error import web.config as config from web.utils.log import Logger logger = Logger("web.deploys.deploys") __author__ = 'Rocky Peng' class DeploysService(Base): __model__ = Deploys def deploy(self, deploy): if self.count(status=2, project_id=deploy.project_id): logger.debug("deploy thread wait in quene") return first_deploy = self.first(status=3, project_id=deploy.project_id) if first_deploy.mode == 0 or first_deploy.mode == 1: t = threading.Thread(target=deploy_thread, args=(deploy.project_id, ), name="pydelo-deploy[%d]" % deploy.id)
#!/usr/local/bin/python # -*- coding:utf-8 -*- from web import db from web import db_session from web.utils.log import Logger logger = Logger("web.services.base") __author__ = 'Rocky Peng' class Base(object): __model__ = None def __init__(self, session=None): self.session = session or db_session def save(self, model): self.session.add(model) self.session.commit() return model def find(self, **kargs): query = self.session.query(self.__model__).filter_by(**kargs) return query def first(self, **kargs): return self.session.query(self.__model__).filter_by(**kargs).first() def get(self, id): self.session.expire_all() return self.session.query(self.__model__).get(id)
import time import random import string from hashlib import md5 from web import db from web.utils.log import Logger from web.models.users import Users from web.services.hosts import hosts from web.services.projects import projects from .base import Base from web.utils.error import Error from .sessions import sessions logger = Logger("user service") class UsersService(Base): __model__ = Users def login(self, username, password): password = md5(password).hexdigest().upper() user = self.first(name=username, password=password) if user is None: raise Error(13000) session = sessions.first(user_id=user.id) expired = datetime.fromtimestamp(time.time() + 24 * 60 * 60).isoformat() if session is None: sign = ''.join(
import sys from hashlib import md5 from flask import request, jsonify, g from web import db from web import app from web.services.users import users from web.services.hosts import hosts from web.services.deploys import deploys from web.services.projects import projects from web.utils.error import Error from .login import authorize from web.utils.log import Logger logger = Logger("web.controller.api") if sys.version_info > (3, ): string.letters = string.ascii_letters __author__ = 'Rocky Peng' @app.errorhandler(Error) def error(err): return jsonify(dict(rc=err.rc, msg=err.msg)) @app.route("/api/accounts/password", methods=["PUT"]) @authorize def api_update_accounts(): password = request.form.get("password")
#!/usr/local/bin/python # -*- coding:utf-8 -*- from web import db from web.models.projects import Projects from web.utils.git import Git from .base import Base from web.utils.log import Logger logger = Logger("web.services.projects") __author__ = 'Rocky Peng' class ProjectsService(Base): __model__ = Projects def git_clone(self, project): git = Git(project.checkout_dir, project.repo_url) git.clone() def git_branch(self, project): git = Git(project.checkout_dir, project.repo_url) return git.remote_branch() def git_tag(self, project): git = Git(project.checkout_dir, project.repo_url) return git.tag() def git_branch_commit_log(self, project, branch): git = Git(project.checkout_dir, project.repo_url) git.checkout_branch(branch) return git.log()
# -*- coding:utf-8 -*- import time from flask import request, jsonify, g from web import app from web.services.users import users from web.services.hosts import hosts from web.services.deploys import deploys from web.services.projects import projects from .login import authorize from web.utils.log import Logger logger = Logger("web.controllers.webhooks") # 添加git的webhook像这样:http://10.169.123.172:9998/api/webhooks/push_events?apikey=FWi14sULr0CwdYqhyBwQfbpdSEV7M8dp&project_id=9&host_id=1 @app.route('/api/webhooks/push_events', methods=["POST"]) @authorize def webhooks_push_events(): project_id = request.args.get("project_id") host_id = request.args.get("host_id") data = request.json branch = data["ref"].split("/", 2)[-1] version = data["after"][:7] logger.debug(repr(data)) # 只针对dev分支进行deploy if data["ref"] == "refs/heads/dev" and data["total_commits_count"] > 0: deploy = deploys.create( user_id=g.user.id, project_id=project_id, host_id=host_id,
#!/usr/local/bin/python # -*- coding:utf-8 -*- __author__ = 'Rocky Peng' from subprocess import Popen, PIPE, CalledProcessError from web.utils.log import Logger logger = Logger("LocalShell") class LocalShell(object): @staticmethod def check_output(*args, **kargs): cmd = kargs.get("args") or args[0] logger.debug("local shell: %s" % cmd) process = Popen(*args, stdout=PIPE, stderr=PIPE, **kargs) stdout, stderr = process.communicate() rc = process.poll() logger.debug("rc: %d" % rc) logger.debug("stdout: %s" % stdout) logger.warn("stderr: %s" % stderr) if rc: raise CalledProcessError(rc, cmd, stdout) return stdout @staticmethod def call(*args, **kargs): cmd = kargs.get("args") or args[0] logger.debug("local shell: %s" % cmd) process = Popen(*args, stdout=PIPE, stderr=PIPE, **kargs) stdout, stderr = process.communicate()
#!/usr/local/bin/python # -*- coding:utf-8 -*- __author__ = 'Rocky Peng' import time import paramiko from web.utils.log import Logger logger = Logger("RemoteShell") class RemoteShell(object): def __init__(self, host, port, user, passwd): self.host = host self.port = port self.user = user self.passwd = passwd self.connect() def connect(self): self.ssh = paramiko.SSHClient() self.ssh.set_missing_host_key_policy(paramiko.AutoAddPolicy()) self.ssh.connect(self.host, self.port, self.user, self.passwd, timeout=10) def exec_command(self, shell): logger.debug("remote shell: %s" % shell) # stdin, stdout, stderr = self.ssh.exec_command(shell)
#!/usr/local/bin/python # -*- coding:utf-8 -*- from web import db from web.models.homes import Home from .base import Base from web.utils.log import Logger logger = Logger("home service") __author__ = 'Rocky Peng' class HomeService(Base): __model__ = Home homes = HomeService()
#!/usr/local/bin/python # -*- coding:utf-8 -*- __author__ = 'Rocky Peng' from web.utils.localshell import LocalShell from web.utils.log import Logger from web.utils.error import Error logger = Logger("GIT") class Git(object): def __init__(self, dest, url): self.dest = dest self.url = url def branch(self): shell = "cd {0} && git fetch -q -a && git branch -r".format(self.dest) stdout = LocalShell.check_output(shell, shell=True) stdout = stdout.strip().split("\n") stdout = [ s.strip(" ").split("/", 1)[1] for s in stdout if "->" not in s ] return stdout def log(self, branch): shell = ("cd {0} && git checkout -q {1} && git fetch -q --all && " "git log -20 --pretty=\"%h %an %s\"").format( self.dest, branch) stdout = LocalShell.check_output(shell, shell=True) stdout = stdout.strip().split("\n")