/** * * @param VagrantVmDetails $vmDetails * @param array $provisioningVars * @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', 'osName', 'homeFolder') as $param) { if (!isset($vmDetails->{$param})) { throw new E5xx_ActionFailed(__METHOD__, "missing vmDetails['{$param}']"); } } // make sure the folder exists $config = $this->st->getConfig(); if (!isset($config->storyplayer->modules->vagrant)) { throw new E5xx_ActionFailed(__METHOD__, "'vagrant' section missing in your storyplayer.json config file"); } if (!isset($config->storyplayer->modules->vagrant->dir)) { throw new E5xx_ActionFailed(__METHOD__, "'dir' setting missing from 'vagrant' section of your storyplayer.json config file"); } $pathToHomeFolder = $config->storyplayer->modules->vagrant->dir . '/' . $vmDetails->homeFolder; if (!is_dir($pathToHomeFolder)) { throw new E5xx_ActionFailed(__METHOD__, "VM dir '{$pathToHomeFolder}' does not exist"); } // remember where the Vagrantfile is $vmDetails->dir = $pathToHomeFolder; // make sure the VM is stopped, if it is running $log->addStep("stop vagrant VM in '{$pathToHomeFolder}' if already running", function () use($vmDetails) { $command = "vagrant destroy --force"; $this->runCommandAgainstHostManager($vmDetails, $command); }); // remove any existing hosts table entry usingHostsTable()->removeHost($vmDetails->hostId); // remove any roles usingRolesTable()->removeHostFromAllRoles($vmDetails->hostId); // let's start the VM $command = "vagrant up"; $result = $log->addStep("create vagrant VM in '{$pathToHomeFolder}'", function () use($command, $vmDetails) { return $this->runCommandAgainstHostManager($vmDetails, $command); }); // did it work? if ($result->returnCode !== 0) { $log->endAction("VM failed to start or provision :("); throw new E5xx_ActionFailed(__METHOD__); } // yes it did!! // now, we need to know how to contact this VM $vmDetails->ipAddress = $this->determineIpAddress($vmDetails); $vmDetails->hostname = $this->determineHostname($vmDetails); // mark the box as provisioned // we will use this in stopBox() to avoid destroying VMs that failed // to provision $vmDetails->provisioned = true; // remember this vm, now that it is running usingHostsTable()->addHost($vmDetails->hostId, $vmDetails); // now, let's get this VM into our SSH known_hosts file, to avoid // prompting people when we try and provision this VM $log->addStep("get the VM into the SSH known_hosts file", function () use($vmDetails) { usingHost($vmDetails->hostId)->runCommand("ls"); }); // all done $log->endAction("VM successfully started; IP address is {$vmDetails->ipAddress}"); }