# along with this program; if not, write to the Free Software
# Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
-import string, re, time, ldap, optparse, sys, os, pwd, posix, socket, base64, hashlib, shutil, errno, tarfile, grp
-import lockfile
+import string, re, time, ldap, optparse, sys, os, pwd, posix, socket, base64, hashlib, shutil, errno, tarfile, grp, fcntl
from userdir_ldap import *
from userdir_exceptions import *
import UDLdap
else:
raise e
-def get_lock(fn, wait=5*60, max_age=3600*6):
- try:
- stat = os.stat(fn + '.lock')
- if stat.st_mtime < time.time() - max_age:
- sys.stderr.write("Removing stale lock %s"%(fn + '.lock'))
- os.unlink(fn + '.lock')
- except OSError, error:
- if error.errno == errno.ENOENT:
- pass
- else:
- raise
+def get_lock(fn, wait=5*60):
+ f = open(fn, "w")
+ sl = 0.1
+ ends = time.time() + wait
- lock = lockfile.FileLock(fn)
- try:
- lock.acquire(timeout=wait)
- except lockfile.LockTimeout:
- return None
-
- return lock
+ while True:
+ success = False
+ try:
+ fcntl.flock(f.fileno(), fcntl.LOCK_EX | fcntl.LOCK_NB)
+ return f
+ except IOError:
+ pass
+ if time.time() >= ends:
+ return None
+ sl = min(sl*2, 10, ends - time.time())
+ time.sleep(sl)
+ return None
def Sanitize(Str):
return IPAdresses
# Generate the ssh known hosts file
-def GenSSHKnown(host_attrs, File, mode=None):
+def GenSSHKnown(host_attrs, File, mode=None, lockfilename=None):
F = None
try:
OldMask = os.umask(0022)
hosts = HostToIP(x)
if 'sshdistAuthKeysHost' in x[1]:
hosts += x[1]['sshdistAuthKeysHost']
- Line = 'command="rsync --server --sender -pr . /var/cache/userdir-ldap/hosts/%s",no-port-forwarding,no-X11-forwarding,no-agent-forwarding,from="%s" %s' % (Host, ",".join(hosts), I)
+ clientcommand='rsync --server --sender -pr . /var/cache/userdir-ldap/hosts/%s'%(Host)
+ clientcommand="flock -s %s -c '%s'"%(lockfilename, clientcommand)
+ Line = 'command="%s",no-port-forwarding,no-X11-forwarding,no-agent-forwarding,from="%s" %s' % (clientcommand, ",".join(hosts), I)
else:
Line = "%s %s" %(",".join(HostNames + HostToIP(x, False)), I)
Line = Sanitize(Line) + "\n"
GenCDB(accounts, global_dir + "mail-forward.cdb", 'emailForward')
GenCDB(accounts, global_dir + "mail-contentinspectionaction.cdb", 'mailContentInspectionAction')
GenPrivate(accounts, global_dir + "debian-private")
- GenSSHKnown(host_attrs, global_dir+"authorized_keys", 'authorized_keys')
+ GenSSHKnown(host_attrs, global_dir+"authorized_keys", 'authorized_keys', global_dir+'ud-generate.lock')
GenMailBool(accounts, global_dir + "mail-greylist", "mailGreylisting")
GenMailBool(accounts, global_dir + "mail-callout", "mailCallout")
GenMailList(accounts, global_dir + "mail-rbl", "mailRBL")
return last
+def getLastKeyringChangeTime():
+ krmod = 0
+ for k in Keyrings:
+ mt = os.path.getmtime(k)
+ if mt > krmod:
+ krmod = mt
+
+ return krmod
+
def getLastBuildTime(gdir):
- cache_last_mod = 0
+ cache_last_ldap_mod = 0
+ cache_last_unix_mod = 0
try:
fd = open(os.path.join(gdir, "last_update.trace"), "r")
cache_last_mod=fd.read().split()
try:
- cache_last_mod = cache_last_mod[0]
- except IndexError:
+ cache_last_ldap_mod = cache_last_mod[0]
+ cache_last_unix_mod = int(cache_last_mod[1])
+ except IndexError, ValueError:
pass
fd.close()
except IOError, e:
else:
raise e
- return cache_last_mod
-
+ return (cache_last_ldap_mod, cache_last_unix_mod)
def ud_generate():
parser = optparse.OptionParser()
parser.print_help()
sys.exit(1)
-
- l = make_ldap_conn()
-
if options.generatedir is not None:
generate_dir = os.environ['UD_GENERATEDIR']
elif 'UD_GENERATEDIR' in os.environ:
generate_dir = os.environ['UD_GENERATEDIR']
+ else:
+ generate_dir = GenerateDir
+
+ lockf = os.path.join(generate_dir, 'ud-generate.lock')
+ lock = get_lock( lockf )
+ if lock is None:
+ sys.stderr.write("Could not acquire lock %s.\n"%(lockf))
+ sys.exit(1)
+
+ l = make_ldap_conn()
+
+ time_started = int(time.time())
ldap_last_mod = getLastLDAPChangeTime(l)
- cache_last_mod = getLastBuildTime(generate_dir)
- need_update = ldap_last_mod > cache_last_mod
+ unix_last_mod = getLastKeyringChangeTime()
+ cache_last_ldap_mod, cache_last_unix_mod = getLastBuildTime(generate_dir)
+
+ need_update = (ldap_last_mod > cache_last_ldap_mod) or (unix_last_mod > cache_last_unix_mod)
if not options.force and not need_update:
fd = open(os.path.join(generate_dir, "last_update.trace"), "w")
- fd.write("%s\n%s\n" % (ldap_last_mod, int(time.time())))
+ fd.write("%s\n%s\n" % (ldap_last_mod, time_started))
fd.close()
sys.exit(0)
- lock = None
- try:
- lockf = os.path.join(generate_dir, 'ud-generate.lock')
- lock = get_lock( lockf )
- if lock is None:
- sys.stderr.write("Could not acquire lock %s.\n"%(lockf))
- sys.exit(1)
-
- tracefd = open(os.path.join(generate_dir, "last_update.trace"), "w")
- generate_all(generate_dir, l)
- tracefd.write("%s\n%s\n" % (ldap_last_mod, int(time.time())))
- tracefd.close()
+ tracefd = open(os.path.join(generate_dir, "last_update.trace"), "w")
+ generate_all(generate_dir, l)
+ tracefd.write("%s\n%s\n" % (ldap_last_mod, time_started))
+ tracefd.close()
- finally:
- if lock is not None:
- lock.release()
if __name__ == "__main__":
- ud_generate()
-
+ if 'UD_PROFILE' in os.environ:
+ import cProfile
+ import pstats
+ cProfile.run('ud_generate()', "udg_prof")
+ p = pstats.Stats('udg_prof')
+ ##p.sort_stats('time').print_stats()
+ p.sort_stats('cumulative').print_stats()
+ else:
+ ud_generate()
# vim:set et:
# vim:set ts=3: