Move the remctl code into invirt.remctl
[invirt/packages/invirt-base.git] / python / invirt / common.py
1 from __future__ import with_statement
2
3 import unittest
4 from fcntl import flock, LOCK_EX, LOCK_SH, LOCK_UN
5 import contextlib as clib
6
7 class struct(object):
8     'A simple namespace object.'
9     def __init__(self, d = {}, **kwargs):
10         'd is the dictionary to update my __dict__ with.'
11         self.__dict__.update(d)
12         self.__dict__.update(kwargs)
13
14 def dicts2struct(x):
15     """
16     Given a tree of lists/dicts, perform a deep traversal to transform all the
17     dicts to structs.
18     """
19     if type(x) == dict:
20         return struct((k, dicts2struct(v)) for k,v in x.iteritems())
21     elif type(x) == list:
22         return [dicts2struct(v) for v in x]
23     else:
24         return x
25
26 @clib.contextmanager
27 def lock_file(path, exclusive = True):
28     with clib.closing(file(path, 'w')) as f:
29         if exclusive:
30             locktype = LOCK_EX
31         else:
32             locktype = LOCK_SH
33         flock(f, locktype)
34         try:
35             yield
36         finally:
37             flock(f, LOCK_UN)
38
39 #
40 # Exceptions.
41 #
42
43 class InvalidInput(Exception):
44     """Exception for user-provided input is invalid but maybe in good faith.
45
46     This would include setting memory to negative (which might be a
47     typo) but not setting an invalid boot CD (which requires bypassing
48     the select box).
49     """
50     def __init__(self, err_field, err_value, expl=None):
51         MyException.__init__(self, expl)
52         self.err_field = err_field
53         self.err_value = err_value
54
55 class CodeError(Exception):
56     """Exception for internal errors or bad faith input."""
57     pass
58
59 #
60 # Tests.
61 #
62
63 class common_tests(unittest.TestCase):
64     def test_dicts2structs(self):
65         dicts = {
66                 'atom': 0,
67                 'dict': { 'atom': 'atom', 'list': [1,2,3] },
68                 'list': [ 'atom', {'key': 'value'} ]
69                 }
70         structs = dicts2struct(dicts)
71         self.assertEqual(structs.atom,        dicts['atom'])
72         self.assertEqual(structs.dict.atom,   dicts['dict']['atom'])
73         self.assertEqual(structs.dict.list,   dicts['dict']['list'])
74         self.assertEqual(structs.list[0],     dicts['list'][0])
75         self.assertEqual(structs.list[1].key, dicts['list'][1]['key'])
76
77 if __name__ == '__main__':
78     unittest.main()