public static function Create(ServerCreateInfo $creInfo, $isImport = false, $setPendingStatus = false)
{
$db = \Scalr::getDb();
$startWithLetter = in_array($creInfo->platform, array(SERVER_PLATFORMS::CLOUDSTACK, SERVER_PLATFORMS::IDCF, SERVER_PLATFORMS::GCE));
if ($isImport) {
$startWithLetter = true;
}
$server_id = Scalr::GenerateUID(false, $startWithLetter);
$status = !$isImport ? SERVER_STATUS::PENDING_LAUNCH : SERVER_STATUS::IMPORTING;
if ($setPendingStatus) {
$status = SERVER_STATUS::PENDING;
}
// Assigns Farm index to the server
if (!$isImport) {
// This query select the least lower vacant Farm index from the available.
// If there are no available indexes the query returns NULL so we need cast result to integer
// to make sure it will use Farm index equal to 1 in this case.
// We ingore terminated and pending terminating instances to release their indexes.
$farmIndex = 1 + intval($db->GetOne("\n SELECT s.farm_index\n FROM servers s\n WHERE s.farm_id = ? AND s.status NOT IN (?, ?)\n AND NOT EXISTS (SELECT 1 FROM servers WHERE farm_id = s.farm_id AND farm_index = s.farm_index + 1 AND status NOT IN (?, ?))\n ORDER BY s.farm_index\n LIMIT 1\n ", [$creInfo->farmId ? $creInfo->farmId : $creInfo->dbFarmRole->FarmID, SERVER_STATUS::TERMINATED, SERVER_STATUS::PENDING_TERMINATE, SERVER_STATUS::TERMINATED, SERVER_STATUS::PENDING_TERMINATE]));
} else {
// Default Farm index value is considered to equal 1
$farmIndex = 1;
}
// IF no index defined
if (!$creInfo->index && !$isImport) {
$indexes = $db->GetAll("SELECT `index` FROM servers WHERE farm_roleid = ? AND status NOT IN (?, ?)", [$creInfo->dbFarmRole->ID, SERVER_STATUS::TERMINATED, SERVER_STATUS::PENDING_TERMINATE]);
$usedIndexes = [];
if (!empty($indexes)) {
foreach ($indexes as $index) {
$usedIndexes[$index['index']] = true;
}
}
for ($i = 1;; $i++) {
if (!isset($usedIndexes[$i])) {
$creInfo->index = $i;
break;
}
}
} elseif ($isImport) {
$creInfo->index = 0;
}
$client_id = $creInfo->clientId ? $creInfo->clientId : $creInfo->dbFarmRole->GetFarmObject()->ClientID;
$instanceTypeName = null;
$instanceTypeId = $creInfo->dbFarmRole ? $creInfo->dbFarmRole->getInstanceType() : null;
if (in_array($creInfo->platform, [SERVER_PLATFORMS::EC2, SERVER_PLATFORMS::GCE])) {
$instanceTypeName = $instanceTypeId;
}
$db->Execute("\n INSERT INTO servers\n SET `server_id` = ?,\n `farm_id` = ?,\n `env_id` = ?,\n `farm_roleid` = ?,\n `client_id` = ?,\n `platform` = ?,\n `status` = ?,\n `remote_ip` = ?,\n `local_ip` = ?,\n `dtadded` = NOW(),\n `index` = ?,\n `farm_index` = ?,\n `cloud_location` = ?,\n `type` = ?,\n `instance_type_name`= ?\n ", [$server_id, $creInfo->farmId ? $creInfo->farmId : $creInfo->dbFarmRole->FarmID, $creInfo->envId, $creInfo->dbFarmRole ? $creInfo->dbFarmRole->ID : 0, $client_id, $creInfo->platform, $status, $creInfo->remoteIp, $creInfo->localIp, $creInfo->index, $farmIndex, $creInfo->dbFarmRole ? $creInfo->dbFarmRole->CloudLocation : null, $instanceTypeId, $instanceTypeName]);
$DBServer = DBServer::LoadByID($server_id);
$DBServer->SetProperties($creInfo->GetProperties());
$DBServer->setOsType($DBServer->osType);
try {
if ($DBServer->farmRoleId) {
$db->Execute("\n INSERT INTO servers_launch_timelog\n SET `server_id` = ?,\n `os_family` = ?,\n `os_version` = ?,\n `cloud` = ?,\n `cloud_location` = ?,\n `server_type` = ?,\n `behaviors` = ?,\n `ts_created` = ?\n ", [$server_id, $DBServer->GetFarmRoleObject()->GetRoleObject()->getOs()->family, $DBServer->GetFarmRoleObject()->GetRoleObject()->getOs()->version, $DBServer->platform, $DBServer->cloudLocation, $DBServer->getType(), implode(",", $DBServer->GetFarmRoleObject()->GetRoleObject()->getBehaviors()), time()]);
}
} catch (Exception $e) {
}
return $DBServer;
}
/** * @param string $platform * @param string $cloudLocation * @param string $cloudServerId * @param string $name * @param bool $createImage * @throws Exception */ public function xInitiateImportAction($platform, $cloudLocation, $cloudServerId, $name, $createImage = false) { if (!Role::isValidName($name)) { throw new Exception(_("Name is incorrect")); } if (!$createImage) { $this->request->restrictAccess(Acl::RESOURCE_ROLES_ENVIRONMENT, Acl::PERM_ROLES_ENVIRONMENT_MANAGE); } if (!$createImage && Role::isNameUsed($name, $this->user->getAccountId(), $this->getEnvironmentId())) { throw new Exception('Selected role name is already used. Please select another one.'); } $cryptoKey = Scalr::GenerateRandomKey(40); $creInfo = new ServerCreateInfo($platform, null, 0, 0); $creInfo->clientId = $this->user->getAccountId(); $creInfo->envId = $this->getEnvironmentId(); $creInfo->farmId = 0; $creInfo->SetProperties(array(SERVER_PROPERTIES::SZR_IMPORTING_ROLE_NAME => $name, SERVER_PROPERTIES::SZR_IMPORTING_OBJECT => $createImage ? BundleTask::BUNDLETASK_OBJECT_IMAGE : BundleTask::BUNDLETASK_OBJECT_ROLE, SERVER_PROPERTIES::SZR_KEY => $cryptoKey, SERVER_PROPERTIES::SZR_KEY_TYPE => SZR_KEY_TYPE::PERMANENT, SERVER_PROPERTIES::SZR_VESION => "0.14.0", SERVER_PROPERTIES::SZR_IMPORTING_VERSION => 2, SERVER_PROPERTIES::SZR_IMPORTING_STEP => 1, SERVER_PROPERTIES::LAUNCHED_BY_ID => $this->user->id, SERVER_PROPERTIES::LAUNCHED_BY_EMAIL => $this->user->getEmail())); $platformObj = PlatformFactory::NewPlatform($platform); $availZone = null; $osType = ''; if ($platform == SERVER_PLATFORMS::EC2) { $client = $this->environment->aws($cloudLocation)->ec2; $r = $client->instance->describe($cloudServerId); $instance = $r->get(0)->instancesSet->get(0); $availZone = $instance->placement->availabilityZone; $osType = $instance->platform == 'windows' ? 'windows' : 'linux'; $creInfo->SetProperties(array(EC2_SERVER_PROPERTIES::REGION => $cloudLocation, EC2_SERVER_PROPERTIES::INSTANCE_ID => $cloudServerId, EC2_SERVER_PROPERTIES::AMIID => $instance->imageId, EC2_SERVER_PROPERTIES::AVAIL_ZONE => $instance->placement->availabilityZone)); } else { if ($platform == SERVER_PLATFORMS::GCE) { $gce = $platformObj->getClient($this->environment); $result = $gce->instances->get($this->environment->keychain(SERVER_PLATFORMS::GCE)->properties[CloudCredentialsProperty::GCE_PROJECT_ID], $cloudLocation, $cloudServerId); $creInfo->SetProperties(array(GCE_SERVER_PROPERTIES::SERVER_NAME => $cloudServerId, GCE_SERVER_PROPERTIES::CLOUD_LOCATION => $cloudLocation)); } else { if ($platform == SERVER_PLATFORMS::AZURE) { //$this->getEnvironment()->azure()->compute->virtualMachine->getInstanceViewInfo() // $r->properties->osProfile->linuxConfiguration != NULL } else { if (PlatformFactory::isOpenstack($platform)) { $creInfo->SetProperties(array(OPENSTACK_SERVER_PROPERTIES::CLOUD_LOCATION => $cloudLocation, OPENSTACK_SERVER_PROPERTIES::SERVER_ID => $cloudServerId)); } else { if (PlatformFactory::isCloudstack($platform)) { $creInfo->SetProperties(array(CLOUDSTACK_SERVER_PROPERTIES::CLOUD_LOCATION => $cloudLocation, CLOUDSTACK_SERVER_PROPERTIES::SERVER_ID => $cloudServerId)); } } } } } $dbServer = DBServer::Create($creInfo, true); $dbServer->osType = $osType; $ips = $platformObj->GetServerIPAddresses($dbServer); $dbServer->localIp = $ips['localIp']; $dbServer->remoteIp = $ips['remoteIp']; $dbServer->cloudLocation = $cloudLocation; if ($platform == SERVER_PLATFORMS::GCE) { $dbServer->cloudLocationZone = $cloudLocation; } else { $dbServer->cloudLocationZone = $availZone; } $dbServer->Save(); $this->response->data(array('command' => $this->getSzrCmd($dbServer), 'installCommand' => $this->getInstallCmd($dbServer), 'osType' => $dbServer->osType, 'serverId' => $dbServer->serverId)); }