#!/usr/bin/python import fcntl import errno import os import logging import sys import simplejson import fcntl starting_mac_prefix='aa:00:00' class FileLock(object): def __init__(self, fd, filename): self.fd = fd self.filename = filename @classmethod def Open(cls, filename): # Using "os.open" is necessary to allow both opening existing file # read/write and creating if not existing. Vanilla "open" will truncate an # existing file -or- allow creating if not existing. return cls(os.fdopen(os.open(filename, os.O_RDWR | os.O_CREAT), "w+"), filename) def __del__(self): self.Close() def Close(self): if hasattr(self, "fd") and self.fd: self.fd.close() self.fd = None def _flock(self, flag): self._Lock(self.fd, flag) @staticmethod def _Lock(fd, flag): fcntl.flock(fd, flag) def Exclusive(self): self._flock(fcntl.LOCK_EX) def Unlock(self): self._flock(fcntl.LOCK_UN) def get_data(): f = open('test', 'r') data = simplejson.load(f) f.close() high = data['high'] pool = set(data['pool']) return high, pool def update_data(high, pool): data = dict() data['pool'] = list(pool) data['high'] = high f = open('test', 'w') f.write(simplejson.dumps(data, indent=2)) f.close() def init(prefix): pool=set() high=prefix update_data(high, pool) def find_prefix(high, pool): try: prefix = pool.pop() new_high = high except KeyError: a = hex(int(high.replace(":",""),16) + 1).replace("0x",'') prefix = ":".join([a[x:x+2] for x in xrange(0,len(a),2)]) new_high = prefix return prefix, new_high, pool def main(argv): if len(argv) < 2: print "Usage: " + argv[0] + "init/get/put" return 1 action=argv[1] lock = FileLock.Open('prefix.lock') lock.Exclusive() if action == "get": (high, pool) = get_data() (prefix, new_high, new_pool) = find_prefix(high, pool) update_data(new_high, new_pool) print prefix elif action == "put": if len(argv) < 3 : lock.Unlock() print "Usage: " + argv[0] + "put prefix" return 1 (high, pool) = get_data() prefix = argv[2] pool.add(prefix) update_data(high, pool) elif action == "init": if len(argv) < 3: lock.Unlock() print "Usage: " + argv[0] + "init prefix" return 1 prefix = argv[2] init(prefix) lock.Unlock() return 0 if __name__ == '__main__': sys.exit(main(sys.argv))