DataSift\Storyplayer\HostLib\Ec2Vm::createHost PHP Method

createHost() public method

public createHost ( Ev2VmDetails $vmDetails, array $provisioningVars = [] ) : void
$vmDetails Ev2VmDetails
$provisioningVars array
return void
    public function createHost($vmDetails, $provisioningVars = array())
    {
        // what are we doing?
        $log = usingLog()->startAction('provision new VM');
        // make sure we like the provided details
        foreach (array('name', 'environment', 'osName', 'amiId', 'securityGroup') as $param) {
            if (!isset($vmDetails->{$param})) {
                throw new E5xx_ActionFailed(__METHOD__, "missing vmDetails['{$param}']");
            }
        }
        // because EC2 is a shared resource, our VMs need namespacing
        $vmDetails->ec2Name = $vmDetails->environment . '.' . $vmDetails->hostId;
        // get our Ec2 client from the SDK
        $client = fromAws()->getEc2Client();
        // make sure the VM is stopped, if it is running
        $log->addStep("stop EC2 VM '{$vmDetails->ec2Name}' if already running", function () use($vmDetails, $client) {
            if (fromEc2Instance($vmDetails->hostId)->getInstanceisRunning()) {
                // stop the host
                usingEc2()->destroyVm($vmDetails->hostId);
            }
        });
        // remove any existing hosts table entry
        usingHostsTable()->removeHost($vmDetails->hostId);
        // let's start the VM
        $response = null;
        try {
            $log->addStep("create EC2 VM using AMI '{$vmDetails->amiId}'", function () use($client, $vmDetails, &$response) {
                $response = $client->runInstances(array('ImageId' => $vmDetails->amiId, 'MinCount' => 1, 'MaxCount' => 1, 'KeyName' => $vmDetails->keyPairName, 'InstanceType' => $vmDetails->instanceType));
                // we need to name this instance
                if (isset($response['Instances'], $response['Instances'][0], $response['Instances'][0]['InstanceId'])) {
                    $client->createTags(array('Resources' => array($response['Instances'][0]['InstanceId']), 'Tags' => array(array('Key' => 'Name', 'Value' => $vmDetails->ec2Name))));
                }
            });
        } catch (Exception $e) {
            // something went wrong
            $log->endAction("VM failed to provision :(");
            throw new E5xx_ActionFailed(__METHOD__, $e->getMessage());
        }
        // we'll need this for future API calls
        $instanceId = $response['Instances'][0]['InstanceId'];
        try {
            // now, we need to wait until this instance is running
            $log->addStep("wait for EC2 VM '{$instanceId}' to finish booting", function () use($client, $vmDetails, $response, $instanceId) {
                $client->waitUntilInstanceRunning(array('InstanceIds' => array($instanceId), 'waiter.interval' => 10, 'waiter.max_attempts' => 10));
                // remember the instance data, to save us time in the future
                $vmDetails->ec2Instance = $response['Instances'][0];
            });
        } catch (Exception $e) {
            // something went wrong
            $log->endAction("VM failed to start :(");
            throw new E5xx_ActionFailed(__METHOD__, $e->getMessage());
        }
        // yes it did!!
        //
        // remember this vm, now that it is running
        usingHostsTable()->addHost($vmDetails->hostId, $vmDetails);
        // now, we need its IP address
        $ipAddress = $this->determineIpAddress($vmDetails);
        // store the IP address for future use
        $vmDetails->ipAddress = $ipAddress;
        // mark the box as provisioned
        // we will use this in stopBox() to avoid destroying VMs that failed
        // to provision
        $vmDetails->provisioned = true;
        // all done
        $log->endAction("VM successfully started; IP address is {$ipAddress}");
    }