This repository was archived by the owner on Jan 3, 2019. It is now read-only.
forked from nicholasdavidson/pybit
-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathpybit-watcher
executable file
·176 lines (142 loc) · 5.95 KB
/
pybit-watcher
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
#!/usr/bin/python
# Copyright 2012:
#
# Nick Davidson <nickd@toby-churchill.com>,
# Simon Haswell <simonh@toby-churchill.com>,
# Neil Williams <neilw@toby-churchill.com>,
# James Bennet <github@james-bennet.com / James.Bennet@toby-churchill.com>
#
# This program is free software; you can redistribute it and/or modify
# it under the terms of the GNU General Public License as published by
# the Free Software Foundation; either version 2 of the License, or
# (at your option) any later version.
#
# This program is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
# GNU General Public License for more details.
#
# You should have received a copy of the GNU General Public License
# along with this program; if not, write to the Free Software
# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston,
# MA 02110-1301, USA.
# -*- coding: utf-8 -*-
import optparse
import pyinotify
import daemon
import pybit
import os
import sys
import logging
import signal
import subprocess
import time
from pybit.daemonlogger import LoggingDaemonContext, FileLikeLogger
from pyinotify import ProcessEvent
META="PYBIT_WATCHER_"
PIDFILE = "/var/run/pybit-watcher.pid"
def signal_handler(signal, frame):
try:
print '\nClosing %s' % os.path.basename(__file__)
sys.exit (os.EX_OK)
except Exception as e:
raise Exception('Error in signal handler: ' + str(e))
return
def getDaemonLogger (filePath, format = None) :
FORMAT = format or '%(asctime)s %(msg)s'
logging.basicConfig(filename=filePath, format=FORMAT, level=logging.DEBUG)
return logging.getLogger()
class EventHandler(pyinotify.ProcessEvent):
def process_IN_CREATE(self, event):
if os.path.isfile(event.pathname) and event.pathname.endswith(".changes"):
logging.debug("Sleeping for %ss" % self.sleeptime)
time.sleep(self.sleeptime)
cmd = "reprepro -b %s processincoming %s" % (self.settings['repobase'], self.settings['rule'])
if ('user' in self.settings and
self.settings['user'] != ''):
cmd = "su %s -c '%s'" % (self.settings['user'], cmd)
if ('dryrun' not in self.settings or
self.settings['dryrun'] == False):
process = subprocess.Popen(cmd, stdout=subprocess.PIPE, stderr=subprocess.PIPE, shell=True)
(stdout, stderr) = process.communicate()
if process.returncode:
logging.debug(stderr)
logging.debug("reprepo command failed with code: %s" % process.returncode)
else:
logging.debug(cmd)
else:
logging.debug("dry-run: %s" % cmd)
def __init__(self, settings):
self.settings = settings
self.sleeptime = 3
if 'sleeptime' in self.settings:
self.sleeptime = self.settings['sleeptime']
ProcessEvent.__init__(self)
def run(settings):
try:
signal.signal(signal.SIGINT, signal_handler)
signal.signal(signal.SIGTERM, signal_handler)
except Exception as e:
raise Exception('Error configuring signal handler: ' + str(e))
wm = pyinotify.WatchManager()
mask = pyinotify.IN_CREATE
if 'dryrun' in settings and settings['dryrun'] == True:
logging.debug("Starting in dryrun mode")
handler = EventHandler(settings)
notifier = pyinotify.Notifier(wm, handler)
wdd = wm.add_watch(settings['path'], mask, rec=True)
notifier.loop()
if __name__ == '__main__':
parser = optparse.OptionParser()
#options we can override in the config file.
groupConfigFile = optparse.OptionGroup(parser,
"Config File Defaults","All the options which have defaults read from a config file.")
groupConfigFile.add_option("--path", dest="path",
help="Path to listen on.", metavar=META + "PATH")
groupConfigFile.add_option("--repobase", dest="repobase",
help="Base of the repository.", metavar=META + "REPOBASE")
groupConfigFile.add_option("--dry-run", dest="dryrun", action="store_true",
help="Controls if we simulate or do we actually run.", metavar=META + "DRYRUN")
groupConfigFile.add_option("--user", dest="user",
help="Which user do we run as?", metavar=META + "USER")
groupConfigFile.add_option("--sleeptime", dest="sleeptime",
help="The number of seconds we wait after a changes file is created before we run the reprepro command.",
metavar=META + "SLEEPTIME")
parser.add_option("--conf_file", dest="conf_file", default="watcher/watcher.conf",
help="Config file to read settings from, defaults to watcher.conf which will be read from configs/watcher and /etc/pybit/watcher in turn.",
metavar=META + "CONF_FILE")
parser.add_option("-v", dest="verbose", action="store_true", default=False,
help="Turn on verbose messages.", metavar=META+"VERBOSE")
parser.add_option("-d", dest="daemonise", action="store_true", default=False,
help="Daemonise with output going to /var/log/pybit-watcher", metavar=META+"DAEMONISE")
(options, args) = parser.parse_args()
context = None
if options.daemonise :
testLogger = getDaemonLogger('/var/log/pybitwatcher.log')
stdoutLogger = getDaemonLogger('/dev/null')
stderrLogger = getDaemonLogger('/dev/null')
context = LoggingDaemonContext()
context.loggers_preserve=[testLogger]
context.stdout_logger = stdoutLogger
context.stderr_logger = stderrLogger
logging.debug ("I: Daemonised")
else :
# FORMAT = format or '%(asctime)s %(msg)s'
logging.basicConfig(level=logging.DEBUG)
logging.debug ("I: Not daemonised")
(settings, opened_path) = pybit.load_settings(options.conf_file)
if settings == {}:
logging.debug("Couldn't load configuration from %s" % opened_path)
sys.exit(-1)
if 'configured' in settings and settings['configured'] == False:
logging.debug ("Please configure the Reprepro watcher. Edit %s" % opened_path)
sys.exit(os.EX_OK)
settings = pybit.merge_options(settings, groupConfigFile, options)
if options.daemonise:
with context :
pid = str(os.getpid())
file(PIDFILE, 'w').write(pid)
run(settings)
else:
logging.debug ("I: Running watcher...")
run(settings)