| OLD | NEW | 
|    1 # Copyright 2014 The Chromium Authors. All rights reserved. |    1 # Copyright 2014 The Chromium Authors. All rights reserved. | 
|    2 # Use of this source code is governed by a BSD-style license that can be |    2 # Use of this source code is governed by a BSD-style license that can be | 
|    3 # found in the LICENSE file. |    3 # found in the LICENSE file. | 
|    4  |    4  | 
|    5 import datetime |    5 import datetime | 
|    6 import itertools |    6 import itertools | 
|    7 import json |    7 import json | 
|    8 import logging |    8 import logging | 
|    9 import urlparse |    9 import urlparse | 
|   10  |   10  | 
| (...skipping 72 matching lines...) Expand 10 before | Expand all | Expand 10 after  Loading... | 
|   83  |   83  | 
|   84  |   84  | 
|   85 def current_identity_cannot(action_format, *args): |   85 def current_identity_cannot(action_format, *args): | 
|   86   action = action_format % args |   86   action = action_format % args | 
|   87   msg = 'User %s cannot %s' % (auth.get_current_identity().to_bytes(), action) |   87   msg = 'User %s cannot %s' % (auth.get_current_identity().to_bytes(), action) | 
|   88   logging.warning(msg) |   88   logging.warning(msg) | 
|   89   raise auth.AuthorizationError(msg) |   89   raise auth.AuthorizationError(msg) | 
|   90  |   90  | 
|   91  |   91  | 
|   92 class BuildBucketService(object): |   92 class BuildBucketService(object): | 
|   93   def add( |   93   @ndb.tasklet | 
|   94       self, bucket, tags=None, parameters=None, lease_expiration_date=None): |   94   def add_async( | 
 |   95       self, bucket, tags=None, parameters=None, lease_expiration_date=None, | 
 |   96       client_operation_id=None): | 
|   95     """Adds the build entity to the build bucket. |   97     """Adds the build entity to the build bucket. | 
|   96  |   98  | 
|   97     Requires the current user to have permissions to add builds to the |   99     Requires the current user to have permissions to add builds to the | 
|   98     |bucket|. |  100     |bucket|. | 
|   99  |  101  | 
|  100     Args: |  102     Args: | 
|  101       bucket (str): destination bucket. Required. |  103       bucket (str): destination bucket. Required. | 
|  102       tags (model.Tags): build tags. |  104       tags (model.Tags): build tags. | 
|  103       parameters (dict): arbitrary build parameters. Cannot be changed after |  105       parameters (dict): arbitrary build parameters. Cannot be changed after | 
|  104         build creation. |  106         build creation. | 
|  105       lease_expiration_date (datetime.datetime): if not None, the build is |  107       lease_expiration_date (datetime.datetime): if not None, the build is | 
|  106         created as leased and its lease_key is not None. |  108         created as leased and its lease_key is not None. | 
 |  109       client_operation_id (str): client-supplied operation id. If an | 
 |  110         a build with the same client operation id was added during last minute, | 
 |  111         it will be returned instead. | 
|  107  |  112  | 
|  108     Returns: |  113     Returns: | 
|  109       A new Build. |  114       A new Build. | 
|  110     """ |  115     """ | 
 |  116     if client_operation_id is not None: | 
 |  117       if not isinstance(client_operation_id, basestring):  # pragma: no cover | 
 |  118         raise errors.InvalidInputError('client_operation_id must be string') | 
 |  119       if '/' in client_operation_id:  # pragma: no cover | 
 |  120         raise errors.InvalidInputError('client_operation_id must not contain /') | 
|  111     validate_bucket_name(bucket) |  121     validate_bucket_name(bucket) | 
|  112     assert parameters is None or isinstance(parameters, dict) |  122     assert parameters is None or isinstance(parameters, dict) | 
|  113     validate_lease_expiration_date(lease_expiration_date) |  123     validate_lease_expiration_date(lease_expiration_date) | 
|  114     validate_tags(tags) |  124     validate_tags(tags) | 
|  115     tags = tags or [] |  125     tags = tags or [] | 
|  116  |  126  | 
 |  127     ctx = ndb.get_context() | 
|  117     identity = auth.get_current_identity() |  128     identity = auth.get_current_identity() | 
|  118     if not acl.can_add_build(bucket, identity): |  129     if not acl.can_add_build(bucket, identity): | 
|  119       raise current_identity_cannot('add builds to bucket %s', bucket) |  130       raise current_identity_cannot('add builds to bucket %s', bucket) | 
|  120  |  131  | 
 |  132     if client_operation_id is not None: | 
 |  133       client_operation_cache_key = ( | 
 |  134           'client_op/%s/%s/add_build' % ( | 
 |  135               identity.to_bytes(), client_operation_id)) | 
 |  136       build_id = yield ctx.memcache_get(client_operation_cache_key) | 
 |  137       if build_id: | 
 |  138         build = yield model.Build.get_by_id_async(build_id) | 
 |  139         if build:  # pragma: no branch | 
 |  140           raise ndb.Return(build) | 
 |  141  | 
|  121     build = model.Build( |  142     build = model.Build( | 
|  122         id=model.new_build_id(), |  143         id=model.new_build_id(), | 
|  123         bucket=bucket, |  144         bucket=bucket, | 
|  124         tags=tags, |  145         tags=tags, | 
|  125         parameters=parameters, |  146         parameters=parameters, | 
|  126         status=model.BuildStatus.SCHEDULED, |  147         status=model.BuildStatus.SCHEDULED, | 
|  127         created_by=identity, |  148         created_by=identity, | 
|  128     ) |  149     ) | 
|  129     if lease_expiration_date is not None: |  150     if lease_expiration_date is not None: | 
|  130       build.lease_expiration_date = lease_expiration_date |  151       build.lease_expiration_date = lease_expiration_date | 
|  131       build.leasee = auth.get_current_identity() |  152       build.leasee = auth.get_current_identity() | 
|  132       build.regenerate_lease_key() |  153       build.regenerate_lease_key() | 
|  133     build.put() |  154     yield build.put_async() | 
|  134     logging.info( |  155     logging.info( | 
|  135         'Build %s was created by %s', build.key.id(), identity.to_bytes()) |  156         'Build %s was created by %s', build.key.id(), identity.to_bytes()) | 
|  136     return build |  157  | 
 |  158     if client_operation_id is not None: | 
 |  159       yield ctx.memcache_set(client_operation_cache_key, build.key.id(), 60) | 
 |  160     raise ndb.Return(build) | 
 |  161  | 
 |  162   def add(self, *args, **kwargs): | 
 |  163     """Sync version of add_async.""" | 
 |  164     return self.add_async(*args, **kwargs).get_result() | 
|  137  |  165  | 
|  138   def get(self, build_id): |  166   def get(self, build_id): | 
|  139     """Gets a build by |build_id|. |  167     """Gets a build by |build_id|. | 
|  140  |  168  | 
|  141     Requires the current user to have permissions to view the build. |  169     Requires the current user to have permissions to view the build. | 
|  142     """ |  170     """ | 
|  143     build = model.Build.get_by_id(build_id) |  171     build = model.Build.get_by_id(build_id) | 
|  144     if not build: |  172     if not build: | 
|  145       return None |  173       return None | 
|  146     identity = auth.get_current_identity() |  174     identity = auth.get_current_identity() | 
| (...skipping 458 matching lines...) Expand 10 before | Expand all | Expand 10 after  Loading... | 
|  605  |  633  | 
|  606   def reset_expired_builds(self): |  634   def reset_expired_builds(self): | 
|  607     """For all building expired builds, resets their lease_key and state.""" |  635     """For all building expired builds, resets their lease_key and state.""" | 
|  608     q = model.Build.query( |  636     q = model.Build.query( | 
|  609         model.Build.is_leased == True, |  637         model.Build.is_leased == True, | 
|  610         model.Build.lease_expiration_date <= datetime.datetime.utcnow(), |  638         model.Build.lease_expiration_date <= datetime.datetime.utcnow(), | 
|  611     ) |  639     ) | 
|  612     for key in q.iter(keys_only=True): |  640     for key in q.iter(keys_only=True): | 
|  613       if self._reset_expired_build(key):  # pragma: no branch |  641       if self._reset_expired_build(key):  # pragma: no branch | 
|  614         logging.info('Expired build %s was reset' % key.id()) |  642         logging.info('Expired build %s was reset' % key.id()) | 
| OLD | NEW |