Scalr::LaunchServer PHP Method

LaunchServer() public static method

Launches server
public static LaunchServer ( ServerCreateInfo $ServerCreateInfo = null, DBServer $DBServer = null, boolean $delayed = false, integer | array $reason, Scalr_Account_User | integer $user = null ) : DBServer | null
$ServerCreateInfo ServerCreateInfo optional The server create info
$DBServer DBServer optional The DBServer object
$delayed boolean optional
$reason integer | array optional
$user Scalr_Account_User | integer optional The Scalr_Account_User object or its unique identifier
return DBServer | null Returns the DBServer object on cussess or null otherwise
    public static function LaunchServer(ServerCreateInfo $ServerCreateInfo = null, DBServer $DBServer = null, $delayed = false, $reason = 0, $user = null)
    {
        $db = self::getDb();
        $farm = null;
        //Ensures handling identifier of the user instead of the object
        if ($user !== null && !$user instanceof \Scalr_Account_User) {
            try {
                $user = Scalr_Account_User::init()->loadById(intval($user));
            } catch (\Exception $e) {
            }
        }
        if (!$DBServer && $ServerCreateInfo) {
            $ServerCreateInfo->SetProperties(array(SERVER_PROPERTIES::SZR_KEY => self::GenerateRandomKey(40), SERVER_PROPERTIES::SZR_KEY_TYPE => SZR_KEY_TYPE::ONE_TIME));
            $DBServer = DBServer::Create($ServerCreateInfo, false, true);
        } elseif (!$DBServer && !$ServerCreateInfo) {
            // incorrect arguments
            self::getContainer()->logger(LOG_CATEGORY::FARM)->error(sprintf("Cannot create server"));
            return null;
        } else {
            if ($DBServer && empty($DBServer->cloudLocation)) {
                trigger_error('Cloud location is missing in DBServer', E_USER_WARNING);
            }
        }
        $propsToSet = array();
        if ($user instanceof \Scalr_Account_User) {
            $propsToSet[SERVER_PROPERTIES::LAUNCHED_BY_ID] = $user->id;
            $propsToSet[SERVER_PROPERTIES::LAUNCHED_BY_EMAIL] = $user->getEmail();
        }
        //We should keep role_id and farm_role_id in server properties to use in cost analytics
        if (!empty($DBServer->farmRoleId)) {
            $propsToSet[SERVER_PROPERTIES::FARM_ROLE_ID] = $DBServer->farmRoleId;
            $propsToSet[SERVER_PROPERTIES::ROLE_ID] = $DBServer->farmRoleId ? $DBServer->GetFarmRoleObject()->RoleID : 0;
        }
        try {
            // Ensures the farm object will be fetched as correctly as possible
            $farm = $DBServer->farmId ? $DBServer->GetFarmObject() : null;
            $farmRole = $DBServer->farmRoleId ? $DBServer->GetFarmRoleObject() : null;
            if (!$farmRole instanceof DBFarmRole) {
                $farmRole = null;
            } else {
                if (!$farm instanceof DBFarm) {
                    // Gets farm through FarmRole object in this case
                    $farm = $farmRole->GetFarmObject();
                }
            }
            if ($farm instanceof DBFarm) {
                $propsToSet[SERVER_PROPERTIES::FARM_CREATED_BY_ID] = $farm->ownerId ?: $farm->GetSetting(Entity\FarmSetting::CREATED_BY_ID);
                $propsToSet[SERVER_PROPERTIES::FARM_CREATED_BY_EMAIL] = $farm->ownerId ? Entity\Account\User::findPk($farm->ownerId)->email : $farm->GetSetting(Entity\FarmSetting::CREATED_BY_EMAIL);
                $projectId = $farm->GetSetting(Entity\FarmSetting::PROJECT_ID);
                if (!empty($projectId)) {
                    try {
                        $projectEntity = ProjectEntity::findPk($projectId);
                        if ($projectEntity instanceof ProjectEntity) {
                            /* @var $projectEntity ProjectEntity */
                            $ccId = $projectEntity->ccId;
                        } else {
                            $projectId = null;
                        }
                    } catch (Exception $e) {
                        $projectId = null;
                    }
                }
                $propsToSet[SERVER_PROPERTIES::FARM_PROJECT_ID] = $projectId;
            }
            if ($farmRole instanceof DBFarmRole) {
                $role = $farmRole->GetRoleObject();
                $DBServer->isScalarized = $role->isScalarized;
                if (!$DBServer->isScalarized) {
                    $propsToSet[SERVER_PROPERTIES::SZR_VESION] = '';
                }
                $DBServer->Save();
            }
            if (!empty($ccId)) {
                $propsToSet[SERVER_PROPERTIES::ENV_CC_ID] = $ccId;
            } elseif ($DBServer->envId && ($environment = $DBServer->GetEnvironmentObject()) instanceof Scalr_Environment) {
                $propsToSet[SERVER_PROPERTIES::ENV_CC_ID] = $environment->getPlatformConfigValue(Scalr_Environment::SETTING_CC_ID);
            }
        } catch (Exception $e) {
            self::getContainer()->logger(LOG_CATEGORY::FARM)->error(sprintf("Could not load related object for recently created server %s. It says: %s", $DBServer->serverId, $e->getMessage()));
        }
        if (!empty($propsToSet)) {
            $DBServer->SetProperties($propsToSet);
        }
        $fnGetReason = function ($reasonId) {
            $args = func_get_args();
            $args[0] = DBServer::getLaunchReason($reasonId);
            return [call_user_func_array('sprintf', $args), $reasonId];
        };
        if ($reason) {
            list($reasonMsg, $reasonId) = is_array($reason) ? call_user_func_array($fnGetReason, $reason) : $fnGetReason($reason);
            $DBServer->SetProperties([SERVER_PROPERTIES::LAUNCH_REASON => $reasonMsg, SERVER_PROPERTIES::LAUNCH_REASON_ID => $reasonId]);
        } else {
            $reasonMsg = $DBServer->GetProperty(SERVER_PROPERTIES::LAUNCH_REASON);
            $reasonId = $DBServer->GetProperty(SERVER_PROPERTIES::LAUNCH_REASON_ID);
        }
        if ($delayed) {
            $DBServer->updateStatus(SERVER_STATUS::PENDING_LAUNCH);
            return $DBServer;
        }
        if ($ServerCreateInfo && $ServerCreateInfo->roleId) {
            $dbRole = DBRole::loadById($ServerCreateInfo->roleId);
            if ($dbRole->generation == 1) {
                $DBServer->updateStatus(SERVER_STATUS::PENDING_LAUNCH);
                $DBServer->SetProperties([SERVER_PROPERTIES::LAUNCH_ERROR => "ami-scripts servers no longer supported", SERVER_PROPERTIES::LAUNCH_ATTEMPT => $DBServer->GetProperty(SERVER_PROPERTIES::LAUNCH_ATTEMPT) + 1, SERVER_PROPERTIES::LAUNCH_LAST_TRY => (new DateTime())->format('Y-m-d H:i:s')]);
                return $DBServer;
            }
        }
        // Limit amount of pending servers
        if ($DBServer->isOpenstack()) {
            $config = self::getContainer()->config;
            if ($config->defined("scalr.{$DBServer->platform}.pending_servers_limit")) {
                $pendingServersLimit = $config->get("scalr.{$DBServer->platform}.pending_servers_limit");
                $pendingServers = $db->GetOne("SELECT COUNT(*) FROM servers WHERE platform=? AND status=? AND server_id != ?", array($DBServer->platform, SERVER_STATUS::PENDING, $DBServer->serverId));
                if ($pendingServers >= $pendingServersLimit) {
                    self::getContainer()->logger("SERVER_LAUNCH")->warn("{$pendingServers} servers in PENDING state on {$DBServer->platform}. Limit is: {$pendingServersLimit}. Waiting.");
                    $DBServer->updateStatus(SERVER_STATUS::PENDING_LAUNCH);
                    $DBServer->SetProperties([SERVER_PROPERTIES::LAUNCH_ATTEMPT => $DBServer->GetProperty(SERVER_PROPERTIES::LAUNCH_ATTEMPT) + 1, SERVER_PROPERTIES::LAUNCH_LAST_TRY => (new DateTime())->format('Y-m-d H:i:s')]);
                    return $DBServer;
                } else {
                    self::getContainer()->logger("SERVER_LAUNCH")->warn("{$pendingServers} servers in PENDING state on {$DBServer->platform}. Limit is: {$pendingServersLimit}. Launching server.");
                }
            }
        }
        try {
            $account = Scalr_Account::init()->loadById($DBServer->clientId);
            $account->validateLimit(Scalr_Limits::ACCOUNT_SERVERS, 1);
            PlatformFactory::NewPlatform($DBServer->platform)->LaunchServer($DBServer);
            $DBServer->status = SERVER_STATUS::PENDING;
            $DBServer->Save();
            try {
                $DBServer->getServerHistory()->markAsLaunched($reasonMsg, $reasonId);
                $DBServer->updateTimelog('ts_launched');
                if ($DBServer->imageId) {
                    //Update Image last used date
                    /* @var $server Entity\Server */
                    $server = Entity\Server::findPk($DBServer->serverId);
                    $image = $server->getImage();
                    if ($image) {
                        $image->update(['dtLastUsed' => new DateTime()]);
                    }
                    if ($server->farmRoleId && empty($server->getFarmRole())) {
                        trigger_error(sprintf("Call to a member function getRole() on null. Server: %s, FarmRole: %d", $server->serverId, $server->farmRoleId), E_USER_WARNING);
                    }
                    if ($server->farmRoleId && !empty($server->getFarmRole()->getRole())) {
                        //Update Role last used date
                        $server->getFarmRole()->getRole()->update(['lastUsed' => new DateTime()]);
                    }
                }
            } catch (Exception $e) {
                self::getContainer()->logger('SERVER_HISTORY')->error(sprintf("Cannot update servers history: {$e->getMessage()}"));
            }
        } catch (Exception $e) {
            self::getContainer()->logger(LOG_CATEGORY::FARM)->error(new FarmLogMessage($DBServer, sprintf("Cannot launch server on '%s' platform: %s", !empty($DBServer->platform) ? $DBServer->platform : null, $e->getMessage())));
            $existingLaunchError = $DBServer->GetProperty(SERVER_PROPERTIES::LAUNCH_ERROR);
            $DBServer->SetProperties([SERVER_PROPERTIES::LAUNCH_ERROR => $e->getMessage(), SERVER_PROPERTIES::LAUNCH_ATTEMPT => $DBServer->GetProperty(SERVER_PROPERTIES::LAUNCH_ATTEMPT) + 1, SERVER_PROPERTIES::LAUNCH_LAST_TRY => (new DateTime())->format('Y-m-d H:i:s')]);
            $DBServer->updateStatus(SERVER_STATUS::PENDING_LAUNCH);
            if ($DBServer->farmId && !$existingLaunchError) {
                self::FireEvent($DBServer->farmId, new InstanceLaunchFailedEvent($DBServer, $e->getMessage()));
            }
        }
        if ($DBServer->status == SERVER_STATUS::PENDING) {
            self::FireEvent($DBServer->farmId, new BeforeInstanceLaunchEvent($DBServer));
            $DBServer->SetProperty(SERVER_PROPERTIES::LAUNCH_ERROR, "");
        }
        return $DBServer;
    }

Usage Example

Esempio n. 1
0
 /**
  * {@inheritdoc}
  * @see Scalr_System_Cronjob_MultiProcess_DefaultWorker::startForking()
  */
 function startForking($workQueue)
 {
     // Reopen DB connection after daemonizing
     $this->db = $this->getContainer()->adodb;
     // Check that time has come to cleanup dead servers
     $doCleanup = false;
     sem_acquire($this->cleanupSem);
     try {
         if (time() - (int) $this->lastCleanup->get(0) >= $this->cleanupInterval) {
             $doCleanup = true;
             $this->lastCleanup->put(0, time());
         }
     } catch (Exception $e) {
         sem_release($this->cleanupSem);
     }
     sem_release($this->cleanupSem);
     if ($doCleanup) {
         $this->logger->info("Cleanup dead servers");
         try {
             $importing_servers = $this->db->GetAll("\n                    SELECT server_id FROM servers\n                    WHERE status IN(?, ?)\n                    AND `dtadded` < NOW() - INTERVAL 1 DAY\n                ", array(SERVER_STATUS::IMPORTING, SERVER_STATUS::TEMPORARY));
             foreach ($importing_servers as $ts) {
                 $dbServer = DBServer::LoadByID($ts['server_id']);
                 if ($dbServer->status == SERVER_STATUS::TEMPORARY) {
                     try {
                         $dbServer->terminate(DBServer::TERMINATE_REASON_TEMPORARY_SERVER_ROLE_BUILDER);
                     } catch (Exception $e) {
                     }
                 } else {
                     if ($dbServer->status == SERVER_STATUS::IMPORTING) {
                         $dbServer->Remove();
                     }
                 }
             }
             $pending_launch_servers = $this->db->GetAll("SELECT server_id FROM servers WHERE status=?", array(SERVER_STATUS::PENDING_LAUNCH));
             try {
                 foreach ($pending_launch_servers as $ts) {
                     $DBServer = DBServer::LoadByID($ts['server_id']);
                     if ($DBServer->status == SERVER_STATUS::PENDING_LAUNCH) {
                         $account = Scalr_Account::init()->loadById($DBServer->clientId);
                         if ($account->status == Scalr_Account::STATUS_ACTIVE) {
                             Scalr::LaunchServer(null, $DBServer);
                         }
                     }
                 }
             } catch (Exception $e) {
                 Logger::getLogger(LOG_CATEGORY::FARM)->error(sprintf("Can't load server with ID #'%s'", $ts['server_id'], $e->getMessage()));
             }
         } catch (Exception $e) {
             $this->logger->fatal("Poller::cleanup failed: {$e->getMessage()}");
         }
     }
 }
All Usage Examples Of Scalr::LaunchServer