diff --git a/resources/sql/autopatches/20140917.drydockbrokereason.1.sql b/resources/sql/autopatches/20140917.drydockbrokereason.1.sql new file mode 100644 --- /dev/null +++ b/resources/sql/autopatches/20140917.drydockbrokereason.1.sql @@ -0,0 +1,2 @@ +ALTER TABLE {$NAMESPACE}_drydock.drydock_lease + ADD brokenReason LONGTEXT NULL COLLATE utf8_bin; diff --git a/src/applications/drydock/blueprint/DrydockBlueprintImplementation.php b/src/applications/drydock/blueprint/DrydockBlueprintImplementation.php --- a/src/applications/drydock/blueprint/DrydockBlueprintImplementation.php +++ b/src/applications/drydock/blueprint/DrydockBlueprintImplementation.php @@ -172,6 +172,7 @@ if ($allocation_exception) { $lease->setStatus(DrydockLeaseStatus::STATUS_BROKEN); + $lease->setBrokenReason($allocation_exception->getMessage()); $lease->save(); $this->logException($allocation_exception); $this->closeResourceIfDesired($resource); @@ -240,6 +241,7 @@ $this->executeAcquireLease($resource, $ephemeral_lease); } catch (Exception $ex) { $lease->setStatus(DrydockLeaseStatus::STATUS_BROKEN); + $lease->setBrokenReason($ex->getMessage()); $lease->save(); $this->logException($ex); $this->closeResourceIfDesired($resource); @@ -414,6 +416,7 @@ case DrydockLeaseStatus::STATUS_PENDING: $message = pht('Breaking pending lease (resource closing).');; $lease->setStatus(DrydockLeaseStatus::STATUS_BROKEN); + $lease->setBrokenReason('Resource forcibly closed'); break; case DrydockLeaseStatus::STATUS_ACTIVE: $message = pht('Releasing active lease (resource closing).'); diff --git a/src/applications/drydock/controller/DrydockLeaseViewController.php b/src/applications/drydock/controller/DrydockLeaseViewController.php --- a/src/applications/drydock/controller/DrydockLeaseViewController.php +++ b/src/applications/drydock/controller/DrydockLeaseViewController.php @@ -118,6 +118,12 @@ pht('Status'), $status); + if ($lease->getBrokenReason() !== null) { + $view->addProperty( + pht('Reason for Broken Status'), + $lease->getBrokenReason()); + } + $view->addProperty( pht('Resource Type'), $lease->getResourceType()); diff --git a/src/applications/drydock/storage/DrydockLease.php b/src/applications/drydock/storage/DrydockLease.php --- a/src/applications/drydock/storage/DrydockLease.php +++ b/src/applications/drydock/storage/DrydockLease.php @@ -9,6 +9,7 @@ protected $ownerPHID; protected $attributes = array(); protected $status = DrydockLeaseStatus::STATUS_PENDING; + protected $brokenReason; protected $taskID; private $resource = self::ATTACHABLE; @@ -153,11 +154,18 @@ unset($unresolved[$key]); break; case DrydockLeaseStatus::STATUS_RELEASED: - throw new Exception('Lease has already been released!'); + throw new Exception( + 'Lease %d has already been released!', + $lease->getID()); case DrydockLeaseStatus::STATUS_EXPIRED: - throw new Exception('Lease has already expired!'); + throw new Exception( + 'Lease %d has already expired!', + $lease->getID()); case DrydockLeaseStatus::STATUS_BROKEN: - throw new Exception('Lease has been broken!'); + throw new Exception(pht( + 'Lease %d has been broken! Reason was: %s', + $lease->getID(), + $lease->getBrokenReason())); case DrydockLeaseStatus::STATUS_PENDING: case DrydockLeaseStatus::STATUS_ACQUIRING: break; diff --git a/src/applications/drydock/worker/DrydockAllocatorWorker.php b/src/applications/drydock/worker/DrydockAllocatorWorker.php --- a/src/applications/drydock/worker/DrydockAllocatorWorker.php +++ b/src/applications/drydock/worker/DrydockAllocatorWorker.php @@ -54,8 +54,8 @@ $lease->reload(); if ($lease->getStatus() == DrydockLeaseStatus::STATUS_PENDING || $lease->getStatus() == DrydockLeaseStatus::STATUS_ACQUIRING) { - $lease->setStatus(DrydockLeaseStatus::STATUS_BROKEN); + $lease->setBrokenReason($ex->getMessage()); $lease->save(); } @@ -178,12 +178,22 @@ foreach ($blueprints as $key => $candidate_blueprint) { if (!$candidate_blueprint->isEnabled()) { + $this->logToDrydock( + pht( + '%s is not currently enabled', + get_class($candidate_blueprint))); + unset($blueprints[$key]); continue; } if ($candidate_blueprint->getType() !== $lease->getResourceType()) { + $this->logToDrydock( + pht( + '%s does not allocate resources of the required type', + get_class($candidate_blueprint))); + unset($blueprints[$key]); continue; } @@ -207,11 +217,21 @@ foreach ($blueprints as $key => $candidate_blueprint) { $rpool = idx($resources_per_blueprint, $key, array()); if (!$candidate_blueprint->canAllocateMoreResources($rpool)) { + $this->logToDrydock( + pht( + '\'%s\' can\'t allocate more resources', + $candidate_blueprint->getInstance()->getBlueprintName())); + unset($blueprints[$key]); continue; } if (!$candidate_blueprint->canAllocateResourceForLease($lease)) { + $this->logToDrydock( + pht( + '\'%s\' can\'t allocate a resource for this particular lease', + $candidate_blueprint->getInstance()->getBlueprintName())); + unset($blueprints[$key]); continue; } @@ -221,12 +241,16 @@ pht('%d Blueprints Can Allocate', count($blueprints))); if (!$blueprints) { + $reason = pht( + "There are no resources of type '%s' available, and no ". + "blueprints which can allocate new ones.", + $type); + $lease->setStatus(DrydockLeaseStatus::STATUS_BROKEN); + $lease->setBrokenReason($reason); $lease->save(); - $this->logToDrydock( - "There are no resources of type '{$type}' available, and no ". - "blueprints which can allocate new ones."); + $this->logToDrydock($reason); $lock->unlock(); return;