private function activateLease(DrydockLease $lease) { $actual_status = $lease->getStatus(); if ($actual_status != DrydockLeaseStatus::STATUS_ACQUIRED) { throw new PhabricatorWorkerPermanentFailureException(pht('Trying to activate lease from wrong status ("%s").', $actual_status)); } $resource_id = $lease->getResourceID(); $resource = id(new DrydockResourceQuery())->setViewer($this->getViewer())->withIDs(array($resource_id))->executeOne(); if (!$resource) { throw new PhabricatorWorkerPermanentFailureException(pht('Trying to activate lease on invalid resource ("%s").', $resource_id)); } $resource_status = $resource->getStatus(); if ($resource_status == DrydockResourceStatus::STATUS_PENDING) { // TODO: This is explicitly a temporary failure -- we are waiting for // the resource to come up. throw new Exception(pht('Resource still activating.')); } if ($resource_status != DrydockResourceStatus::STATUS_OPEN) { throw new PhabricatorWorkerPermanentFailureException(pht('Trying to activate lease on a dead resource (in status "%s").', $resource_status)); } // NOTE: We can race resource destruction here. Between the time we // performed the read above and now, the resource might have closed, so // we may activate leases on dead resources. At least for now, this seems // fine: a resource dying right before we activate a lease on it should not // be distinguisahble from a resource dying right after we activate a lease // on it. We end up with an active lease on a dead resource either way, and // can not prevent resources dying from lightning strikes. $blueprint = $resource->getBlueprint(); $blueprint->activateLease($resource, $lease); $this->validateActivatedLease($blueprint, $resource, $lease); }
private function buildPropertyListView(DrydockLease $lease, PhabricatorActionListView $actions) { $view = new PHUIPropertyListView(); $view->setActionList($actions); switch ($lease->getStatus()) { case DrydockLeaseStatus::STATUS_ACTIVE: $status = pht('Active'); break; case DrydockLeaseStatus::STATUS_RELEASED: $status = pht('Released'); break; case DrydockLeaseStatus::STATUS_EXPIRED: $status = pht('Expired'); break; case DrydockLeaseStatus::STATUS_PENDING: $status = pht('Pending'); break; case DrydockLeaseStatus::STATUS_BROKEN: $status = pht('Broken'); break; default: $status = pht('Unknown'); break; } $view->addProperty(pht('Status'), $status); $view->addProperty(pht('Resource Type'), $lease->getResourceType()); $view->addProperty(pht('Resource'), $lease->getResourceID()); $attributes = $lease->getAttributes(); if ($attributes) { $view->addSectionHeader(pht('Attributes')); foreach ($attributes as $key => $value) { $view->addProperty($key, $value); } } return $view; }
/** * Make sure that a lease was really acquired properly. * * @param DrydockBlueprint Blueprint which created the resource. * @param DrydockResource Resource which was acquired. * @param DrydockLease The lease which was supposedly acquired. * @return void * @task lease */ private function validateAcquiredLease(DrydockBlueprint $blueprint, DrydockResource $resource, DrydockLease $lease) { if (!$lease->isAcquiredLease()) { throw new Exception(pht('Blueprint "%s" (of type "%s") is not properly implemented: it ' . 'returned from "%s" without acquiring a lease.', $blueprint->getBlueprintName(), $blueprint->getClassName(), 'acquireLease()')); } $lease_id = $lease->getResourceID(); $resource_id = $resource->getID(); if ($lease_id !== $resource_id) { // TODO: Destroy the lease? throw new Exception(pht('Blueprint "%s" (of type "%s") is not properly implemented: it ' . 'returned from "%s" with a lease acquired on the wrong resource.', $blueprint->getBlueprintName(), $blueprint->getClassName(), 'acquireLease()')); } }