Scalr\Modules\Platforms\Cloudstack\CloudstackPlatformModule::LaunchServer PHP Méthode

LaunchServer() public méthode

See also: Scalr\Modules\PlatformModuleInterface::LaunchServer()
public LaunchServer ( DBServer $DBServer, Scalr_Server_LaunchOptions $launchOptions = null )
$DBServer DBServer
$launchOptions Scalr_Server_LaunchOptions
    public function LaunchServer(DBServer $DBServer, Scalr_Server_LaunchOptions $launchOptions = null)
    {
        $environment = $DBServer->GetEnvironmentObject();
        $governance = new Scalr_Governance($environment->id);
        $diskOffering = null;
        $size = null;
        $cs = $environment->cloudstack($this->platform);
        if (!$launchOptions) {
            $farmRole = $DBServer->GetFarmRoleObject();
            $launchOptions = new Scalr_Server_LaunchOptions();
            $dbRole = $farmRole->GetRoleObject();
            $launchOptions->imageId = $dbRole->__getNewRoleObject()->getImage($this->platform, $DBServer->GetFarmRoleObject()->CloudLocation)->imageId;
            $launchOptions->serverType = $DBServer->GetFarmRoleObject()->GetSetting(Entity\FarmRoleSetting::INSTANCE_TYPE);
            $launchOptions->cloudLocation = $DBServer->GetFarmRoleObject()->CloudLocation;
            /*
             * User Data
             */
            $u_data = '';
            foreach ($DBServer->GetCloudUserData() as $k => $v) {
                $u_data .= "{$k}={$v};";
            }
            $launchOptions->userData = trim($u_data, ";");
            $diskOffering = $farmRole->GetSetting(Entity\FarmRoleSetting::CLOUDSTACK_DISK_OFFERING_ID);
            if ($diskOffering === false || $diskOffering === null) {
                $diskOffering = null;
            }
            $sharedIp = $farmRole->GetSetting(Entity\FarmRoleSetting::CLOUDSTACK_SHARED_IP_ID);
            $networkType = $farmRole->GetSetting(Entity\FarmRoleSetting::CLOUDSTACK_NETWORK_TYPE);
            $networkId = $farmRole->GetSetting(Entity\FarmRoleSetting::CLOUDSTACK_NETWORK_ID);
            $useStaticNat = $farmRole->GetSetting(Entity\FarmRoleSetting::CLOUDSTACK_USE_STATIC_NAT);
            $roleName = $farmRole->GetRoleObject()->name;
            $osType = $farmRole->GetRoleObject()->getOs()->family == 'windows' ? 'windows' : 'linux';
        } else {
            $launchOptions->userData = '';
            $roleName = 'TemporaryScalrServer' . rand(100, 999);
            $osType = 'linux';
        }
        $launchOptions->architecture = 'x86_64';
        \Scalr::getContainer()->logger("CloudStack")->warn(new FarmLogMessage($DBServer, "[ServerLaunch] Network ID: {$networkId}, NetworkType: {$networkType}, SharedIp: {$sharedIp}"));
        if (!$sharedIp && !$useStaticNat && $networkId != 'SCALR_MANUAL') {
            if ($networkId && !$networkType) {
                foreach ($cs->network->describe(array('id' => $networkId)) as $network) {
                    if ($network->id == $networkId) {
                        $farmRole->SetSetting(Entity\FarmRoleSetting::CLOUDSTACK_NETWORK_TYPE, $network->type, Entity\FarmRoleSetting::TYPE_LCL);
                        $networkType = $network->type;
                        \Scalr::getContainer()->logger("CloudStack")->warn(new FarmLogMessage($DBServer, "[ServerLaunch] Network found. Type: {$networkType}"));
                    }
                }
            }
            if ($networkId && ($networkType == 'Virtual' || $networkType == 'Isolated') || !$networkType) {
                $sharedIpId = $environment->keychain($DBServer->platform)->properties[Entity\CloudCredentialsProperty::CLOUDSTACK_SHARED_IP_ID . ".{$launchOptions->cloudLocation}"];
                $sharedIpFound = false;
                if ($sharedIpId) {
                    try {
                        $requestObject = new ListIpAddressesData();
                        $requestObject->id = $sharedIpId;
                        $info = $cs->listPublicIpAddresses($requestObject);
                    } catch (Exception $e) {
                        \Scalr::getContainer()->logger('CLOUDSTACK')->error("SHARED IP CHECK: {$e->getMessage()}");
                    }
                    if (!empty($info[0])) {
                        $sharedIpFound = true;
                        \Scalr::getContainer()->logger('CLOUDSTACK')->error("SHARED IP CHECK: " . json_encode($info));
                    }
                }
                $config = \Scalr::getContainer()->config;
                $instancesConnectionPolicy = $config->defined("scalr.{$this->platform}.instances_connection_policy") ? $config("scalr.{$this->platform}.instances_connection_policy") : null;
                if ($instancesConnectionPolicy === null) {
                    $instancesConnectionPolicy = $config('scalr.instances_connection_policy');
                }
                \Scalr::getContainer()->logger("CloudStack")->warn(new FarmLogMessage($DBServer, "[ServerLaunch] Shared IP ID: {$sharedIpId}"));
                if ((!$sharedIpId || !$sharedIpFound) && $instancesConnectionPolicy != 'local') {
                    \Scalr::getContainer()->logger('CLOUDSTACK')->error("No shared IP. Generating new one");
                    $requestObject = new AssociateIpAddressData();
                    $requestObject->zoneid = $launchOptions->cloudLocation;
                    if ($networkId) {
                        $requestObject->networkid = $networkId;
                    }
                    $ipResult = $cs->associateIpAddress($requestObject);
                    $ipId = $ipResult->id;
                    \Scalr::getContainer()->logger('CLOUDSTACK')->error("New IP allocated: {$ipId}");
                    if ($ipId) {
                        while (true) {
                            $requestObject = new ListIpAddressesData();
                            $requestObject->id = $ipId;
                            $ipInfo = $cs->listPublicIpAddresses($requestObject);
                            $ipInfo = !empty($ipInfo[0]) ? $ipInfo[0] : null;
                            if (!$ipInfo) {
                                throw new Exception("Cannot allocate IP address: listPublicIpAddresses -> failed");
                            }
                            if ($ipInfo->state == 'Allocated') {
                                $environment->keychain($DBServer->platform)->properties->saveSettings([Entity\CloudCredentialsProperty::CLOUDSTACK_SHARED_IP_ID . ".{$launchOptions->cloudLocation}" => $ipId, Entity\CloudCredentialsProperty::CLOUDSTACK_SHARED_IP . ".{$launchOptions->cloudLocation}" => $ipInfo->ipaddress, Entity\CloudCredentialsProperty::CLOUDSTACK_SHARED_IP_INFO . ".{$launchOptions->cloudLocation}" => serialize($ipInfo)]);
                                $sharedIpId = $ipId;
                                break;
                            } else {
                                if ($ipInfo->state == 'Allocating') {
                                    sleep(1);
                                } else {
                                    throw new Exception("Cannot allocate IP address: ipAddress->state = {$ipInfo->state}");
                                }
                            }
                        }
                    } else {
                        throw new Exception("Cannot allocate IP address: associateIpAddress -> failed");
                    }
                }
            }
        }
        if ($DBServer->status == SERVER_STATUS::TEMPORARY) {
            $keyName = "SCALR-ROLESBUILDER-" . SCALR_ID;
            $farmId = NULL;
        } else {
            $keyName = "FARM-{$DBServer->farmId}-" . SCALR_ID;
            $farmId = $DBServer->farmId;
        }
        //
        $sgs = null;
        try {
            $zones = $cs->zone->describe(['name' => $launchOptions->cloudLocation]);
            $zoneSecurityGroupsEnabled = 1;
            if ($zones[0]) {
                if (isset($zones[0]->securitygroupsenabled)) {
                    $zoneSecurityGroupsEnabled = (int) $zones[0]->securitygroupsenabled;
                }
            }
            $features = (array) $cs->listCapabilities();
            if ($features['securitygroupsenabled'] && $zoneSecurityGroupsEnabled == 1) {
                $sgs = $this->GetServerSecurityGroupsList($DBServer, $cs, $governance);
            }
        } catch (Exception $e) {
            \Scalr::getContainer()->logger("CloudStack")->error(new FarmLogMessage($DBServer, "Unable to get list of securoty groups: {$e->getMessage()}"));
        }
        $sshKey = new SshKey();
        try {
            if (!$sshKey->loadGlobalByName($DBServer->envId, $this->platform, "", $keyName)) {
                $result = $cs->sshKeyPair->create(array('name' => $keyName));
                if (!empty($result->privatekey)) {
                    $sshKey->farmId = $farmId;
                    $sshKey->envId = $DBServer->envId;
                    $sshKey->type = SshKey::TYPE_GLOBAL;
                    $sshKey->platform = $this->platform;
                    $sshKey->cloudLocation = "";
                    //$launchOptions->cloudLocation;
                    $sshKey->cloudKeyName = $keyName;
                    $sshKey->privateKey = $result->privatekey;
                    $sshKey->publicKey = $sshKey->generatePublicKey();
                    $sshKey->save();
                }
            }
        } catch (Exception $e) {
            \Scalr::getContainer()->logger("CloudStack")->error(new FarmLogMessage($DBServer, "Unable to generate keypair: {$e->getMessage()}"));
        }
        $vResult = $cs->instance->deploy(['serviceofferingid' => $launchOptions->serverType, 'templateid' => $launchOptions->imageId, 'zoneid' => $launchOptions->cloudLocation, 'diskofferingid' => $diskOffering, 'displayname' => $DBServer->serverId, 'group' => $roleName, 'keypair' => $keyName, 'networkids' => $networkId != 'SCALR_MANUAL' ? $networkId : null, 'size' => $size, 'userdata' => base64_encode($launchOptions->userData), 'securitygroupids' => !empty($sgs) ? implode(",", $sgs) : null]);
        if (!empty($vResult->id)) {
            $instanceTypeInfo = $this->getInstanceType($launchOptions->serverType, $environment, $launchOptions->cloudLocation);
            /* @var $instanceTypeInfo CloudInstanceType */
            $DBServer->SetProperties([CLOUDSTACK_SERVER_PROPERTIES::SERVER_ID => $vResult->id, CLOUDSTACK_SERVER_PROPERTIES::CLOUD_LOCATION => $launchOptions->cloudLocation, CLOUDSTACK_SERVER_PROPERTIES::LAUNCH_JOB_ID => $vResult->jobid, SERVER_PROPERTIES::ARCHITECTURE => $launchOptions->architecture, SERVER_PROPERTIES::INFO_INSTANCE_VCPUS => $instanceTypeInfo ? $instanceTypeInfo->vcpus : null]);
            $DBServer->cloudLocation = $launchOptions->cloudLocation;
            $DBServer->imageId = $launchOptions->imageId;
            $params = ['type' => $launchOptions->serverType];
            if ($instanceTypeInfo) {
                $params['instanceTypeName'] = $instanceTypeInfo->name;
            }
            $DBServer->setOsType($osType);
            $DBServer->update($params);
            //We set/update server history here
            $DBServer->getServerHistory()->update(['cloudServerId' => $vResult->id]);
            return $DBServer;
        } else {
            throw new Exception(sprintf("Cannot launch new instance: %s", $vResult->errortext));
        }
    }