prettified r2lab
authorThierry Parmentelat <thierry.parmentelat@inria.fr>
Tue, 13 Dec 2016 16:09:49 +0000 (17:09 +0100)
committerThierry Parmentelat <thierry.parmentelat@inria.fr>
Fri, 16 Dec 2016 08:15:08 +0000 (09:15 +0100)
PLC/Leases.py
PLC/Methods/AddLeases.py
PLC/Methods/UpdateLeases.py
PLC/Table.py

index 5e99129..c1b2235 100644 (file)
@@ -50,18 +50,19 @@ class Lease(Row):
         # retrieve configured granularity
         granularity = self.api.config.PLC_RESERVATION_GRANULARITY
         # the trick for rounding up rather than down
-        if round_up: timestamp += (granularity-1)
+        if round_up:
+            timestamp += (granularity-1)
         # round down
         timestamp = (timestamp/granularity) * granularity
         # return a SQL string
         return Timestamp.sql_validate_utc(timestamp)
 
     # round UP
-    def validate_t_from(self,timestamp):
-        return self.validate_time (timestamp, round_up=True)
+    def validate_t_from(self, timestamp):
+        return self.validate_time(timestamp, round_up=True)
     # round DOWN
     def validate_t_until (self, timestamp):
-        return self.validate_time (timestamp, round_up=False)
+        return self.validate_time(timestamp, round_up=False)
 
 class Leases(Table):
     """
index 46d5242..0ae7ca3 100644 (file)
@@ -13,6 +13,7 @@ from PLC.Timestamp import Timestamp
 
 can_update = ['name', 'instantiation', 'url', 'description', 'max_nodes']
 
+
 class AddLeases(Method):
     """
     Adds a new lease.
@@ -30,32 +31,37 @@ class AddLeases(Method):
 
     accepts = [
         Auth(),
-        Mixed(Node.fields['node_id'],[Node.fields['node_id']],
-              Node.fields['hostname'],[Node.fields['hostname']],),
+        Mixed(Node.fields['node_id'], [Node.fields['node_id']],
+              Node.fields['hostname'], [Node.fields['hostname']],),
         Mixed(Slice.fields['slice_id'],
               Slice.fields['name']),
         Mixed(Lease.fields['t_from']),
         Mixed(Lease.fields['t_until']),
-        ]
-
-    returns = Parameter(dict, " 'new_ids' is the list of newly created ids, 'errors' is a list of error strings")
+    ]
 
-    def call(self, auth, node_id_or_hostname_s, slice_id_or_name, t_from, t_until):
+    returns = Parameter(
+        dict,
+        " 'new_ids' is the list of newly created ids,"
+        "'errors' is a list of error strings")
 
-        # xxx - round to plain hours somewhere
+    def call(self, auth, node_id_or_hostname_s, slice_id_or_name,
+             t_from, t_until):
 
         # Get node information
         nodes = Nodes(self.api, node_id_or_hostname_s)
         if not nodes:
-            raise PLCInvalidArgument, "No such node(s) %r"%node_id_or_hostname_s
+            raise PLCInvalidArgument(
+                "No such node(s) {}".format(node_id_or_hostname_s))
         for node in nodes:
             if node['node_type'] != 'reservable':
-                raise PLCInvalidArgument, "Node %s is not reservable"%node['hostname']
+                raise PLCInvalidArgument(
+                    "Node {} is not reservable".format(node['hostname']))
 
         # Get slice information
         slices = Slices(self.api, [slice_id_or_name])
         if not slices:
-            raise PLCInvalidArgument, "No such slice %r"%slice_id_or_name
+            raise PLCInvalidArgument(
+                "No such slice {}".format(slice_id_or_name))
         slice = slices[0]
 
         # check access
@@ -63,36 +69,48 @@ class AddLeases(Method):
             if self.caller['person_id'] in slice['person_ids']:
                 pass
             elif 'pi' not in self.caller['roles']:
-                raise PLCPermissionDenied, "Not a member of the specified slice"
+                raise PLCPermissionDenied(
+                    "Not a member of the specified slice")
             elif slice['site_id'] not in self.caller['site_ids']:
-                raise PLCPermissionDenied, "Specified slice not associated with any of your sites"
+                raise PLCPermissionDenied(
+                    "Specified slice not associated with any of your sites")
 
-        # normalize timestamps
+        # normalize timestamps - use granularity to round up limits
         t_from = Timestamp.sql_validate_utc(t_from)
         t_until = Timestamp.sql_validate_utc(t_until)
 
-        ########## create stuff
-        errors=[]
-        result_ids=[]
+        # create stuff
+        errors = []
+        result_ids = []
         for node in nodes:
             if node['peer_id'] is not None:
-                errors.append("Cannot set lease on remote node %r"%node['hostname'])
+                errors.append("Cannot set lease on remote node {}"
+                              .format(node['hostname']))
                 continue
             # let the DB check for time consistency
             try:
-                lease = Lease (self.api, {'node_id':node['node_id'], 'slice_id': slice['slice_id'],
-                                          't_from':t_from, 't_until':t_until})
+                lease = Lease(self.api, {'node_id': node['node_id'],
+                                         'slice_id': slice['slice_id'],
+                                         't_from': t_from, 't_until': t_until})
                 lease.sync()
                 result_ids.append(lease['lease_id'])
-            except Exception,e:
-                errors.append("Could not create lease on n=%s s=%s [%s .. %s] -- %r" % \
-                                  (node['hostname'],slice['name'],t_from,t_until,e))
+
+            except PLCDBError as e:
+                errors.append(
+                    "Timeslot busy - could not create overlapping lease"
+                    " on n={} s={} [{} .. {}]"
+                    .format(node['hostname'], slice['name'], t_from, t_until))
+                nodes.remove(node)
+            except Exception as e:
+                errors.append(
+                    "Could not create lease on n={} s={} [{} .. {}] -- {}"
+                    .format(node['hostname'], slice['name'], t_from, t_until, e))
                 nodes.remove(node)
 
         self.event_objects = {'Slice': [slice['slice_id']],
                               'Node': [node['node_id'] for node in nodes]}
-        self.message = "New leases %r on n=%r s=%s [%s -> %s]" % \
-            (result_ids,[node['hostname'] for node in nodes],slice['name'],t_from,t_until)
+        self.message = "New leases {} on n={} s={} [{} -> {}]"\
+            .format(result_ids, [node['hostname'] for node in nodes],
+                    slice['name'], t_from, t_until)
 
-        return {'new_ids': result_ids,
-                'errors': errors}
+        return {'new_ids': result_ids, 'errors': errors}
index 28dffb0..c760c5b 100644 (file)
@@ -1,3 +1,5 @@
+from __future__ import print_function
+
 from PLC.Faults import *
 from PLC.Method import Method
 from PLC.Parameter import Parameter, Mixed
@@ -10,6 +12,7 @@ from PLC.Slices import Slice, Slices
 
 can_update = lambda (field, value): field in ['t_from', 't_until', 'duration']
 
+
 class UpdateLeases(Method):
     """
     Updates the parameters of a (set of) existing lease(s) with the values in
@@ -30,14 +33,17 @@ class UpdateLeases(Method):
 
     accepts = [
         Auth(),
-        Mixed (Lease.fields['lease_id'],
-               [Lease.fields['lease_id']]),
+        Mixed(Lease.fields['lease_id'],
+              [Lease.fields['lease_id']]),
         lease_fields
-        ]
+    ]
 
-    returns = Parameter(dict, " 'updated_ids' is the list ids updated, 'errors' is a list of error strings")
+    returns = Parameter(
+        dict,
+        " 'updated_ids' is the list ids updated,"
+        "'errors' is a list of error strings")
 
-    debug=False
+    debug = False
 #    debug=True
 
     def call(self, auth, lease_ids, input_fields):
@@ -45,71 +51,90 @@ class UpdateLeases(Method):
 
         if 'duration' in input_fields:
             if 't_from' in input_fields and 't_until' in input_fields:
-                raise PLCInvalidArgument, "Cannot set t_from AND t_until AND duration"
+                raise PLCInvalidArgument(
+                    "Cannot set t_from AND t_until AND duration")
             # specify 'duration':0 to keep duration unchanged
-            if input_fields['duration'] : input_fields['duration']=Duration.validate(input_fields['duration'])
+            if input_fields['duration']:
+                input_fields['duration'] = Duration.validate(
+                    input_fields['duration'])
 
         # Get lease information
         leases = Leases(self.api, lease_ids)
         if not leases:
-            raise PLCInvalidArgument, "No such leases %r"%lease_ids
+            raise PLCInvalidArgument("No such leases {}".format(lease_ids))
 
         # fetch related slices
-        slices = Slices(self.api, [ lease['slice_id'] for lease in leases],['slice_id','person_ids'])
+        slices = Slices(self.api,
+                        [lease['slice_id'] for lease in leases],
+                        ['slice_id', 'person_ids'])
         # create hash on slice_id
-        slice_map = dict ( [ (slice['slice_id'],slice) for slice in slices ] )
+        slice_map = dict([(slice['slice_id'], slice) for slice in slices])
 
-        updated_ids=[]
-        errors=[]
+        updated_ids = []
+        errors = []
 
-        lease_ids=[lease['lease_id'] for lease in leases]
+        lease_ids = [lease['lease_id'] for lease in leases]
         for lease in leases:
 
             if 'admin' not in self.caller['roles']:
-                slice=slice_map[lease['slice_id']]
+                slice = slice_map[lease['slice_id']]
                 # check slices only once
-                if not slice.has_key('verified'):
+                if 'verified' not in slice:
                     if self.caller['person_id'] in slice['person_ids']:
                         pass
                     elif 'pi' not in self.caller['roles']:
-                        raise PLCPermissionDenied, "Not a member of slice %r"%slice['name']
+                        raise PLCPermissionDenied(
+                            "Not a member of slice {}".format(slice['name']))
                     elif slice['site_id'] not in self.caller['site_ids']:
-                        raise PLCPermissionDenied, "Slice %r not associated with any of your sites"%slice['name']
-            slice['verified']=True
+                        raise PLCPermissionDenied(
+                            "Slice {} not associated with any of your sites"
+                            .format(slice['name']))
+            slice['verified'] = True
 
             try:
-                # we've ruled out already the case where all 3 (from, to, duration) where specified
+                # we've ruled out already the case where all 3 (from, to,
+                # duration) where specified
                 if 'duration' not in input_fields:
-                    lease_fields=input_fields
+                    lease_fields = input_fields
                 else:
                     # all arithmetics on longs..
-                    duration=Duration.validate(input_fields['duration'])
+                    duration = Duration.validate(input_fields['duration'])
                     # specify 'duration':0 to keep duration unchanged
                     if not duration:
-                        duration = Timestamp.cast_long(lease['t_until'])-Timestamp.cast_long(lease['t_from'])
+                        duration = Timestamp.cast_long(
+                                       lease['t_until']) \
+                                 - Timestamp.cast_long(lease['t_from'])
                     if 't_from' in input_fields:
-                        lease_fields={'t_from':input_fields['t_from'],
-                                      't_until':Timestamp.cast_long(input_fields['from'])+duration}
+                        lease_fields = {
+                            't_from': input_fields['t_from'],
+                            't_until': Timestamp.cast_long(
+                                input_fields['from']) + duration}
                     elif 't_until' in input_fields:
-                        lease_fields={'t_from':Timestamp.cast_long(input_fields['t_until'])-duration,
-                                      't_until':input_fields['t_until']}
+                        lease_fields = {
+                            't_from': Timestamp.cast_long(
+                                          input_fields['t_until']) - duration,
+                            't_until': input_fields['t_until']}
                     else:
-                        lease_fields={'t_until':Timestamp.cast_long(lease['t_from'])+duration}
+                        lease_fields = {'t_until': Timestamp.cast_long(
+                            lease['t_from']) + duration}
                 if UpdateLeases.debug:
-                    print 'lease_fields',lease_fields
-                    for k in [ 't_from', 't_until'] :
+                    for k in ['t_from', 't_until']:
                         if k in lease_fields:
-                            print k,'aka',Timestamp.sql_validate_utc(lease_fields[k])
+                            print(k, 'aka', Timestamp.sql_validate_utc(
+                                lease_fields[k]))
 
                 lease.update(lease_fields)
                 lease.sync()
                 updated_ids.append(lease['lease_id'])
-            except Exception,e:
-                errors.append("Could not update lease %d - check new time limits ? -- %r"%(lease['lease_id'],e))
+            except Exception, e:
+                errors.append(
+                    "Could not update lease {} - check new time limits ? -- {}"
+                    .format(lease['lease_id'], e))
 
         # Logging variables
         self.event_objects = {'Lease': updated_ids}
-        self.message = 'lease %r updated: %s' %  (lease_ids, ", ".join(input_fields.keys()))
+        self.message = 'lease {} updated: {}'\
+                       .format(lease_ids, ", ".join(input_fields.keys()))
 
-        return {'updated_ids' : updated_ids,
-                'errors' : errors }
+        return {'updated_ids': updated_ids,
+                'errors': errors}
index 8f434bf..2365965 100644 (file)
@@ -193,12 +193,13 @@ class Row(dict):
         for this object, and are not marked as a read-only Parameter.
         """
 
-        if obj is None: obj = self
+        if obj is None:
+            obj = self
 
         db_fields = self.api.db.fields(self.table_name)
-        return dict ( [ (key,value) for (key,value) in obj.items()
+        return dict ( [ (key, value) for (key, value) in obj.items()
                         if key in db_fields and
-                        Row.is_writable(key,value,self.fields) ] )
+                        Row.is_writable(key, value, self.fields) ] )
 
     def tag_fields (self, obj=None):
         """
@@ -351,11 +352,11 @@ class Row(dict):
         else:
             # Update existing row
             columns = ["%s = %s" % (key, value) for (key, value) in zip(keys, values)]
-            sql = "UPDATE %s SET " % self.table_name + \
-                  ", ".join(columns) + \
-                  " WHERE %s = %s" % \
-                  (self.primary_key,
-                   self.api.db.param(self.primary_key, self[self.primary_key]))
+            sql = "UPDATE {} SET {} WHERE {} = {}"\
+                  .format(self.table_name,
+                          ", ".join(columns),
+                          self.primary_key,
+                          self.api.db.param(self.primary_key, self[self.primary_key]))                                               
 
         self.api.db.do(sql, db_fields)