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 """Reserve resources, so that jobs can't take them.
32
33 """
34
35 from ganeti import errors
36
37
39 """A temporary resource reservation manager.
40
41 This is used to reserve resources in a job, before using them, making sure
42 other jobs cannot get them in the meantime.
43
44 """
46 self._ec_reserved = {}
47
49 for holder_reserved in self._ec_reserved.values():
50 if resource in holder_reserved:
51 return True
52 return False
53
54 - def Reserve(self, ec_id, resource):
55 if self.Reserved(resource):
56 raise errors.ReservationError("Duplicate reservation for resource '%s'"
57 % str(resource))
58 if ec_id not in self._ec_reserved:
59 self._ec_reserved[ec_id] = set([resource])
60 else:
61 self._ec_reserved[ec_id].add(resource)
62
64 if ec_id in self._ec_reserved:
65 del self._ec_reserved[ec_id]
66
68 all_reserved = set()
69 for holder_reserved in self._ec_reserved.values():
70 all_reserved.update(holder_reserved)
71 return all_reserved
72
74 """ Used when you want to retrieve all reservations for a specific
75 execution context. E.g when commiting reserved IPs for a specific
76 network.
77
78 """
79 ec_reserved = set()
80 if ec_id in self._ec_reserved:
81 ec_reserved.update(self._ec_reserved[ec_id])
82 return ec_reserved
83
84 - def Generate(self, existing, generate_one_fn, ec_id):
85 """Generate a new resource of this type
86
87 """
88 assert callable(generate_one_fn)
89
90 all_elems = self.GetReserved()
91 all_elems.update(existing)
92 retries = 64
93 while retries > 0:
94 new_resource = generate_one_fn()
95 if new_resource is not None and new_resource not in all_elems:
96 break
97 else:
98 raise errors.ConfigurationError("Not able generate new resource"
99 " (last tried: %s)" % new_resource)
100 self.Reserve(ec_id, new_resource)
101 return new_resource
102