root / snf-network-mac-prefix @ 4e98adfd
History | View | Annotate | Download (2.4 kB)
1 |
#!/usr/bin/python |
---|---|
2 |
|
3 |
import fcntl |
4 |
import errno |
5 |
import os |
6 |
import logging |
7 |
import sys |
8 |
import simplejson |
9 |
import fcntl |
10 |
|
11 |
starting_mac_prefix='aa:00:00' |
12 |
|
13 |
class FileLock(object): |
14 |
def __init__(self, fd, filename): |
15 |
self.fd = fd |
16 |
self.filename = filename |
17 |
|
18 |
@classmethod |
19 |
def Open(cls, filename): |
20 |
# Using "os.open" is necessary to allow both opening existing file |
21 |
# read/write and creating if not existing. Vanilla "open" will truncate an |
22 |
# existing file -or- allow creating if not existing. |
23 |
return cls(os.fdopen(os.open(filename, os.O_RDWR | os.O_CREAT), "w+"), |
24 |
filename) |
25 |
|
26 |
def __del__(self): |
27 |
self.Close() |
28 |
|
29 |
def Close(self): |
30 |
if hasattr(self, "fd") and self.fd: |
31 |
self.fd.close() |
32 |
self.fd = None |
33 |
|
34 |
def _flock(self, flag): |
35 |
self._Lock(self.fd, flag) |
36 |
|
37 |
@staticmethod |
38 |
def _Lock(fd, flag): |
39 |
fcntl.flock(fd, flag) |
40 |
|
41 |
def Exclusive(self): |
42 |
self._flock(fcntl.LOCK_EX) |
43 |
|
44 |
def Unlock(self): |
45 |
self._flock(fcntl.LOCK_UN) |
46 |
|
47 |
|
48 |
def get_data(): |
49 |
f = open('test', 'r') |
50 |
data = simplejson.load(f) |
51 |
f.close() |
52 |
high = data['high'] |
53 |
pool = set(data['pool']) |
54 |
return high, pool |
55 |
|
56 |
def update_data(high, pool): |
57 |
data = dict() |
58 |
data['pool'] = list(pool) |
59 |
data['high'] = high |
60 |
f = open('test', 'w') |
61 |
f.write(simplejson.dumps(data, indent=2)) |
62 |
f.close() |
63 |
|
64 |
def init(prefix): |
65 |
pool=set() |
66 |
high=prefix |
67 |
update_data(high, pool) |
68 |
|
69 |
def find_prefix(high, pool): |
70 |
try: |
71 |
prefix = pool.pop() |
72 |
new_high = high |
73 |
except KeyError: |
74 |
a = hex(int(high.replace(":",""),16) + 1).replace("0x",'') |
75 |
prefix = ":".join([a[x:x+2] for x in xrange(0,len(a),2)]) |
76 |
new_high = prefix |
77 |
|
78 |
return prefix, new_high, pool |
79 |
|
80 |
|
81 |
|
82 |
|
83 |
|
84 |
|
85 |
def main(argv): |
86 |
if len(argv) < 2: |
87 |
print "Usage: " + argv[0] + "init/get/put" |
88 |
return 1 |
89 |
|
90 |
action=argv[1] |
91 |
|
92 |
lock = FileLock.Open('prefix.lock') |
93 |
lock.Exclusive() |
94 |
|
95 |
|
96 |
if action == "get": |
97 |
(high, pool) = get_data() |
98 |
(prefix, new_high, new_pool) = find_prefix(high, pool) |
99 |
update_data(new_high, new_pool) |
100 |
print prefix |
101 |
|
102 |
elif action == "put": |
103 |
if len(argv) < 3 : |
104 |
lock.Unlock() |
105 |
print "Usage: " + argv[0] + "put prefix" |
106 |
return 1 |
107 |
|
108 |
(high, pool) = get_data() |
109 |
prefix = argv[2] |
110 |
pool.add(prefix) |
111 |
update_data(high, pool) |
112 |
|
113 |
elif action == "init": |
114 |
if len(argv) < 3: |
115 |
lock.Unlock() |
116 |
print "Usage: " + argv[0] + "init prefix" |
117 |
return 1 |
118 |
|
119 |
prefix = argv[2] |
120 |
init(prefix) |
121 |
|
122 |
lock.Unlock() |
123 |
return 0 |
124 |
|
125 |
if __name__ == '__main__': |
126 |
sys.exit(main(sys.argv)) |
127 |
|