checking in all work done so far because what if my SSD dies?
This commit is contained in:
119
git/remotehooks.py
Executable file
119
git/remotehooks.py
Executable file
@@ -0,0 +1,119 @@
|
||||
#!/usr/bin/env python3
|
||||
|
||||
import ast # Needed for localhost cmd strings
|
||||
import json
|
||||
import os
|
||||
import re
|
||||
import sys
|
||||
modules = {}
|
||||
try:
|
||||
import git
|
||||
modules['git'] = True
|
||||
except ImportError:
|
||||
import subprocess
|
||||
modules['git'] = False
|
||||
try:
|
||||
import paramiko
|
||||
import socket
|
||||
modules['ssh'] = True
|
||||
except ImportError:
|
||||
modules['ssh'] = False
|
||||
|
||||
|
||||
|
||||
repos = {}
|
||||
repos['bdisk'] = {'remotecmds': {'g.rainwreck.com': {'gitbot': {'cmds': ['git -C /var/lib/gitbot/clonerepos/BDisk pull',
|
||||
'git -C /var/lib/gitbot/clonerepos/BDisk pull --tags',
|
||||
'asciidoctor /var/lib/gitbot/clonerepos/BDisk/docs/manual/HEAD.adoc -o /srv/http/bdisk/index.html']}}}}
|
||||
repos['test'] = {'remotecmds': {'g.rainwreck.com': {'gitbot': {'cmds': ['echo $USER']}}}}
|
||||
repos['games-site'] = {'remotecmds': {'games.square-r00t.net':
|
||||
{'gitbot':
|
||||
{'cmds': ['cd /srv/http/games-site && git pull']}}}}
|
||||
repos['aif-ng'] = {'cmds': [['asciidoctor', '/opt/git/repo.checkouts/aif-ng/docs/README.adoc', '-o', '/srv/http/aif/index.html']]}
|
||||
|
||||
def execHook(gitinfo = False):
|
||||
if not gitinfo:
|
||||
gitinfo = getGitInfo()
|
||||
repo = gitinfo['repo'].lower()
|
||||
print('Executing hooks for {0}:{1}...'.format(repo, gitinfo['branch']))
|
||||
print('This commit: {0}\nLast commit: {1}'.format(gitinfo['currev'], gitinfo['oldrev']))
|
||||
# Execute local commands first
|
||||
if 'cmds' in repos[repo].keys():
|
||||
for cmd in repos[repo]['cmds']:
|
||||
print('\tExecuting {0}...'.format(' '.join(cmd)))
|
||||
subprocess.call(cmd)
|
||||
if 'remotecmds' in repos[repo].keys():
|
||||
for host in repos[repo]['remotecmds'].keys():
|
||||
if 'port' in repos[repo]['remotecmds'][host].keys():
|
||||
port = int(repos[repo]['remotecmds'][host]['port'])
|
||||
else:
|
||||
port = 22
|
||||
for user in repos[repo]['remotecmds'][host].keys():
|
||||
print('{0}@{1}:'.format(user, host))
|
||||
if paramikomodule:
|
||||
ssh = paramiko.SSHClient()
|
||||
ssh.set_missing_host_key_policy(paramiko.AutoAddPolicy())
|
||||
ssh.connect(host, username = user, port = port)
|
||||
try:
|
||||
for cmd in repos[repo]['remotecmds'][host][user]['cmds']:
|
||||
print('\tExecuting \'{0}\'...'.format(cmd))
|
||||
stdin, stdout, stderr = ssh.exec_command(cmd)
|
||||
stdout = stdout.read().decode('utf-8')
|
||||
stderr = stderr.read().decode('utf-8')
|
||||
print(stdout)
|
||||
if stderr != '':
|
||||
print(stderr)
|
||||
except paramiko.AuthenticationException:
|
||||
print('({0}@{1}) AUTHENTICATION FAILED!'.format(user, host))
|
||||
except paramiko.BadHostKeyException:
|
||||
print('({0}@{1}) INCORRECT HOSTKEY!'.format(user, host))
|
||||
except paramiko.SSHException:
|
||||
print('({0}@{1}) FAILED TO ESTABLISH SSH!'.format(user, host))
|
||||
except socket.error:
|
||||
print('({0}@{1}) SOCKET CONNECTION FAILURE! (DNS, timeout/firewall, etc.)'.format(user, host))
|
||||
else:
|
||||
for cmd in repos[repo]['remotecmds'][host][user]['cmds']:
|
||||
try:
|
||||
print('\tExecuting \'{0}\'...'.format(cmd))
|
||||
subprocess.call(['ssh', '{0}@{1}'.format(user, host), cmd])
|
||||
except:
|
||||
print('({0}@{1}) An error occurred!'.format(user, host))
|
||||
|
||||
def getGitInfo():
|
||||
refs = sys.argv[1].split('/')
|
||||
gitinfo = {}
|
||||
if refs[1] == 'tags':
|
||||
gitinfo['branch'] = False
|
||||
gitinfo['tag'] = refs[2]
|
||||
elif refs[1] == 'heads':
|
||||
gitinfo['branch'] = refs[2]
|
||||
gitinfo['tag'] = False
|
||||
gitinfo['repo'] = os.environ['GL_REPO']
|
||||
gitinfo['user'] = os.environ['GL_USER']
|
||||
clientinfo = os.environ['SSH_CONNECTION'].split()
|
||||
gitinfo['ssh'] = {'client': {'ip': clientinfo[0], 'port': clientinfo[1]},
|
||||
'server': {'ip': clientinfo[2], 'port': clientinfo[3]},
|
||||
'user': os.environ['USER']
|
||||
}
|
||||
if os.environ['GIT_DIR'] == '.':
|
||||
gitinfo['dir'] = os.environ['PWD']
|
||||
else:
|
||||
#gitinfo['dir'] = os.path.join(os.environ['GL_REPO_BASE'], gitinfo['repo'], '.git')
|
||||
gitinfo['dir'] = os.path.abspath(os.path.expanduser(os.environ['GIT_DIR']))
|
||||
if gitmodule:
|
||||
# This is preferred, because it's a lot more faster and a lot more flexible.
|
||||
#https://gitpython.readthedocs.io/en/stable
|
||||
gitobj = git.Repo(gitinfo['dir'])
|
||||
commits = list(gitobj.iter_commits(gitobj.head.ref.name, max_count = 2))
|
||||
else:
|
||||
commits = subprocess.check_output(['git', 'rev-parse', 'HEAD..HEAD^1']).decode('utf-8').splitlines()
|
||||
gitinfo['oldrev'] = re.sub('^\^', '', commits[1])
|
||||
gitinfo['currev'] = re.sub('^\^', '', commits[0])
|
||||
return(gitinfo)
|
||||
#sys.exit(0)
|
||||
|
||||
def main():
|
||||
execHook()
|
||||
|
||||
if __name__ == '__main__':
|
||||
main()
|
||||
69
git/remotehooks2.py
Executable file
69
git/remotehooks2.py
Executable file
@@ -0,0 +1,69 @@
|
||||
#!/usr/bin/env python3
|
||||
|
||||
import json
|
||||
import os
|
||||
import re
|
||||
import sys
|
||||
# Can we use paramiko for remotecmds?
|
||||
try:
|
||||
import paramiko
|
||||
import socket
|
||||
has_ssh = True
|
||||
except ImportError:
|
||||
has_ssh = False
|
||||
# Can we use the python git module?
|
||||
try:
|
||||
import git # "python-gitpython" in Arch; https://github.com/gitpython-developers/gitpython
|
||||
has_git = True
|
||||
except ImportError:
|
||||
has_git = False
|
||||
|
||||
|
||||
class repoHooks(object):
|
||||
def __init__(self):
|
||||
with open(os.path.join(os.environ['HOME'],
|
||||
'.gitolite',
|
||||
'local',
|
||||
'hooks',
|
||||
'repo-specific',
|
||||
'githooks.json'), 'r') as f:
|
||||
self.cfg = json.loads(f.read())
|
||||
self.repos = list(self.cfg.keys())
|
||||
self.env = os.environ.copy()
|
||||
if 'GIT_DIR' in self.env.keys():
|
||||
del(self.env['GIT_DIR'])
|
||||
self.repo = self.env['GL_REPO']
|
||||
|
||||
def remoteExec(self):
|
||||
for _host in self.repos[self.repo]['remotecmds'].keys():
|
||||
if len(_host.split(':')) == 2:
|
||||
_server, _port = [i.strip() for i in _host.split(':')]
|
||||
else:
|
||||
_port = 22
|
||||
_server = _host.split(':')[0]
|
||||
_h = self.repos[self.repo]['remotecmds'][_host]
|
||||
for _user in _h.keys():
|
||||
_u = _h[_user]
|
||||
if has_ssh:
|
||||
_ssh = paramiko.SSHClient()
|
||||
_ssh.load_system_host_keys()
|
||||
_ssh.missing_host_key_policy(paramiko.AutoAddPolicy())
|
||||
_ssh.connect(_server,
|
||||
int(_port),
|
||||
_user)
|
||||
for _cmd in _h.keys():
|
||||
pass # DO STUFF HERE
|
||||
else:
|
||||
return() # no-op; no paramiko
|
||||
|
||||
def localExec(self):
|
||||
pass
|
||||
|
||||
def main():
|
||||
h = repoHooks()
|
||||
if h.repo not in h.repos:
|
||||
return()
|
||||
|
||||
|
||||
if __name__ == '__main__':
|
||||
main()
|
||||
27
git/sample.githooks..json
Normal file
27
git/sample.githooks..json
Normal file
@@ -0,0 +1,27 @@
|
||||
# remotehooks.py should go in your <gitolite repo>/local/hooks/repo-specific directory,
|
||||
# along with the (uncommented) format of this file configured for your particular hooks
|
||||
# "cmds" is a list of commands performed locally on the gitolite server,
|
||||
# "remotecmds" contains a recursive directory of commands to run remotely
|
||||
|
||||
{
|
||||
"<REPO_NAME>": {
|
||||
"remotecmds": {
|
||||
"<HOST_OR_IP_ADDRESS>": {
|
||||
"<USER>": {
|
||||
"cmds": [
|
||||
"<COMMAND_1>",
|
||||
"<COMMAND_2>"
|
||||
]
|
||||
}
|
||||
}
|
||||
}
|
||||
},
|
||||
"<REPO2_NAME>": {
|
||||
"cmds": [
|
||||
[
|
||||
"<LOCAL_COMMAND_1>",
|
||||
"<LOCAL_COMMAND_2>"
|
||||
]
|
||||
]
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user