From 9017bb9925e851dc073eb491376e7ca9a48aedc8 Mon Sep 17 00:00:00 2001 From: epriestley Date: Fri, 9 Dec 2016 08:04:10 -0800 Subject: [PATCH] Add a setup check for installation on a burstable instance type Summary: Fixes T11544. Attempt to detect if we're on a tiny, burstable-CPU AWS instance and complain. Test Plan: - Completely faked this locally. - Hit the URI on an EC2 instance to check that it's correct (got back "m3.large", since that was the instance class). Reviewers: chad Reviewed By: chad Maniphest Tasks: T11544 Differential Revision: https://secure.phabricator.com/D17014 --- .../check/PhabricatorWebServerSetupCheck.php | 45 ++++++++++++++++++- 1 file changed, 43 insertions(+), 2 deletions(-) diff --git a/src/applications/config/check/PhabricatorWebServerSetupCheck.php b/src/applications/config/check/PhabricatorWebServerSetupCheck.php index 346dd2de1e..398ebd6376 100644 --- a/src/applications/config/check/PhabricatorWebServerSetupCheck.php +++ b/src/applications/config/check/PhabricatorWebServerSetupCheck.php @@ -42,7 +42,7 @@ final class PhabricatorWebServerSetupCheck extends PhabricatorSetupCheck { ->setPath($send_path) ->setQueryParam($expect_key, $expect_value); - $future = id(new HTTPSFuture($base_uri)) + $self_future = id(new HTTPSFuture($base_uri)) ->addHeader('X-Phabricator-SelfCheck', 1) ->addHeader('Accept-Encoding', 'gzip') ->setHTTPBasicAuthCredentials( @@ -50,8 +50,49 @@ final class PhabricatorWebServerSetupCheck extends PhabricatorSetupCheck { new PhutilOpaqueEnvelope($expect_pass)) ->setTimeout(5); + // Make a request to the metadata service available on EC2 instances, + // to test if we're running on a T2 instance in AWS so we can warn that + // this is a bad idea. Outside of AWS, this request will just fail. + $ec2_uri = 'http://169.254.169.254/latest/meta-data/instance-type'; + $ec2_future = id(new HTTPSFuture($ec2_uri)) + ->setTimeout(1); + + $futures = array( + $self_future, + $ec2_future, + ); + $futures = new FutureIterator($futures); + foreach ($futures as $future) { + // Just resolve the futures here. + } + + try { - list($body, $headers) = $future->resolvex(); + list($body) = $ec2_future->resolvex(); + $body = trim($body); + if (preg_match('/^t2/', $body)) { + $message = pht( + 'Phabricator appears to be installed on a very small EC2 instance '. + '(of class "%s") with burstable CPU. This is strongly discouraged. '. + 'Phabricator regularly needs CPU, and these instances are often '. + 'choked to death by CPU throttling. Use an instance with a normal '. + 'CPU instead.', + $body); + + $this->newIssue('ec2.burstable') + ->setName(pht('Installed on Burstable CPU Instance')) + ->setSummary( + pht( + 'Do not install Phabricator on an instance class with '. + 'burstable CPU.')) + ->setMessage($message); + } + } catch (Exception $ex) { + // If this fails, just continue. We're probably not running in EC2. + } + + try { + list($body, $headers) = $self_future->resolvex(); } catch (Exception $ex) { // If this fails for whatever reason, just ignore it. Hopefully, the // error is obvious and the user can correct it on their own, but we