[projects/git-slug: 58/170] Introduce watch daemon
glen
glen at pld-linux.org
Mon Sep 21 21:43:41 CEST 2015
commit 85265450223ffc83c735e509425dd076740b1feb
Author: Kacper Kornet <draenog at pld-linux.org>
Date: Wed Sep 21 14:02:46 2011 +0200
Introduce watch daemon
To avoid global lock on all repositories post-receive hook does not
longer modifies REFREPO. Instead it creates a file with unique name in
WATCHDIR directory. REFREPO is updated by a daemon which watches the
WATCHDIR by a inotify mechanism.
git_slug/serverconst.py | 3 +++
post-receive | 19 +++++---------
watch.py | 69 +++++++++++++++++++++++++++++++++++++++++++++++++
3 files changed, 79 insertions(+), 12 deletions(-)
---
diff --git a/git_slug/serverconst.py b/git_slug/serverconst.py
new file mode 100644
index 0000000..3d176ea
--- /dev/null
+++ b/git_slug/serverconst.py
@@ -0,0 +1,3 @@
+from os.path import join, expanduser
+
+WATCHDIR = expanduser('~/watchdir')
diff --git a/post-receive b/post-receive
index 751ad3a..d1c5f04 100755
--- a/post-receive
+++ b/post-receive
@@ -2,11 +2,13 @@
import fcntl
import os
+import tempfile
import sys
import subprocess
from git_slug.refsdata import RemoteRefsData
from git_slug.gitconst import REFREPO, REFFILE
+from git_slug.serverconst import WATCHDIR
from git_slug.gitrepo import GitRepo
@@ -23,15 +25,8 @@ if gitrepo.startswith('packages/'):
else:
sys.exit()
-with open(os.path.join(os.getenv('HOME'), REFREPO, REFFILE), 'r+') as headfile:
- fcntl.lockf(headfile, fcntl.LOCK_EX)
- print('Lock obtained')
- refs = RemoteRefsData(headfile, '*')
- refs.put(gitrepo, data)
- headfile.seek(0)
- headfile.truncate()
- refs.dump(headfile)
- headfile.flush()
- os.fsync(headfile.fileno())
- headrepo = GitRepo(os.path.join(os.getenv('HOME'), REFREPO), os.path.join(os.getenv('GL_REPO_BASE_ABS'), REFREPO+'.git'))
- headrepo.commitfile(REFFILE, 'Changes by {}'.format(os.getenv('GL_USER')))
+(tfile, name) = tempfile.mkstemp(prefix=gitrepo+'.', dir=WATCHDIR)
+os.write(tfile,(os.getenv('GL_USER')+'\n').encode('utf-8'))
+os.write(tfile,(gitrepo+'\n').encode('utf-8'))
+os.write(tfile,''.join(data).encode('utf-8'))
+os.close(tfile)
diff --git a/watch.py b/watch.py
new file mode 100755
index 0000000..7ee9625
--- /dev/null
+++ b/watch.py
@@ -0,0 +1,69 @@
+#!/usr/bin/python3
+
+import heapq
+import os
+import pyinotify
+import shutil
+
+from git_slug.gitconst import REFREPO, REFFILE
+from git_slug.serverconst import WATCHDIR
+from git_slug.refsdata import RemoteRefsData
+from git_slug.gitrepo import GitRepo
+
+
+PIDFILE = os.path.expanduser('~/watch.pid')
+REFFILE_NEW = REFFILE + '.new'
+REFREPO_WDIR = os.path.expanduser('~/Refs')
+REFREPO_GDIR = os.path.join(os.path.expanduser('~/repositories'), REFREPO+'.git')
+
+WATCHDIR=WATCHDIR
+
+wm = pyinotify.WatchManager() # Watch Manager
+mask = pyinotify.IN_CLOSE_WRITE # watched events
+
+def convertstream(stream):
+ for line in stream:
+ (sha1, ref, repo) = line.split()
+ yield (repo, ref, 1, sha1)
+
+def processnewfile(stream):
+ repo = stream.readline().strip()
+ for line in stream:
+ (sha1old, sha1, ref) = line.split()
+ if ref.startswith('refs/heads/'):
+ yield (repo, ref, 0, sha1)
+
+
+def process_file(pathname):
+ if not os.path.isfile(pathname):
+ print('{} is not an ordinary file'.format(pathname))
+ return
+ with open(os.path.join(REFREPO_WDIR, REFFILE),'r') as headfile, open(os.path.join(REFREPO_WDIR, REFFILE_NEW),'w') as headfile_new, open(pathname, 'r') as newfile:
+ committer = newfile.readline().strip()
+ oldtuple = None
+ for (repo, ref, number, sha1) in heapq.merge(sorted(processnewfile(newfile)), convertstream(headfile)):
+ if (repo, ref) == oldtuple:
+ continue
+ oldtuple = (repo, ref)
+ print(sha1, ref, repo, file=headfile_new)
+ shutil.copyfile(os.path.join(REFREPO_WDIR, REFFILE_NEW), os.path.join(REFREPO_WDIR, REFFILE))
+
+ headrepo = GitRepo(REFREPO_WDIR, REFREPO_GDIR)
+ headrepo.commitfile(REFFILE, 'Changes by {}'.format(committer))
+ os.remove(pathname)
+
+class EventHandler(pyinotify.ProcessEvent):
+ def process_IN_CLOSE_WRITE(self, event):
+ process_file(event.pathname)
+
+if not os.path.isdir(WATCHDIR):
+ print('Creating {}'.format(WATCHDIR))
+ os.mkdir(WATCHDIR)
+notifier = pyinotify.Notifier(wm, EventHandler())
+wdd = wm.add_watch(WATCHDIR, mask, rec=False)
+
+for filename in sorted(os.listdir(WATCHDIR), key=lambda f: os.stat(os.path.join(WATCHDIR, f)).st_mtime):
+ process_file(os.path.join(WATCHDIR,filename))
+
+notifier.loop(daemonize=True, pid_file=os.path.expanduser(PIDFILE),
+ stdout=os.path.expanduser('~/watch.stdout'))
================================================================
---- gitweb:
http://git.pld-linux.org/gitweb.cgi/projects/git-slug.git/commitdiff/4ed64f73960519a2f4fd04c42950b2c96ae795c5
More information about the pld-cvs-commit
mailing list