public function xExecuteAction() { $this->request->restrictAccess(Acl::RESOURCE_FARMS_SCRIPTS, Acl::PERM_FARMS_SCRIPTS_EXECUTE); $this->request->defineParams(array('farmId' => array('type' => 'int'), 'farmRoleId' => array('type' => 'int'), 'serverId' => array('type' => 'string'), 'scriptId' => array('type' => 'int'), 'scriptIsSync' => array('type' => 'int'), 'scriptTimeout' => array('type' => 'int'), 'scriptVersion' => array('type' => 'int'), 'scriptOptions' => array('type' => 'array'), 'createMenuLink' => array('type' => 'int'))); $eventName = Scalr_Scripting_Manager::generateEventName('CustomEvent'); if ($this->getParam('serverId')) { $dbServer = DBServer::LoadByID($this->getParam('serverId')); $this->user->getPermissions()->validate($dbServer); $target = Scalr_Script::TARGET_INSTANCE; $serverId = $dbServer->serverId; $farmRoleId = $dbServer->farmRoleId; $farmId = $dbServer->farmId; } else { if ($this->getParam('farmRoleId')) { $dbFarmRole = DBFarmRole::LoadByID($this->getParam('farmRoleId')); $this->user->getPermissions()->validate($dbFarmRole); $target = Scalr_Script::TARGET_ROLE; $farmRoleId = $dbFarmRole->ID; $farmId = $dbFarmRole->FarmID; } else { if (!$this->getParam('farmId')) { $target = Scalr_Script::TARGET_ALL; } else { $dbFarm = DBFarm::LoadByID($this->getParam('farmId')); $this->user->getPermissions()->validate($dbFarm); $target = Scalr_Script::TARGET_FARM; $farmId = $dbFarm->ID; } } } if (!$this->getParam('eventName')) { if ($this->getParam('createMenuLink')) { $this->db->Execute("INSERT INTO farm_role_scripts SET\n scriptid\t= ?,\n farmid\t\t= ?,\n farm_roleid\t= ?,\n params\t\t= ?,\n event_name\t= ?,\n target\t\t= ?,\n version\t\t= ?,\n timeout\t\t= ?,\n issync\t\t= ?,\n ismenuitem\t= ?\n ", array($this->getParam('scriptId'), (int) $farmId, (int) $farmRoleId, serialize($this->getParam('scriptOptions')), $eventName, $target, $this->getParam('scriptVersion'), $this->getParam('scriptTimeout'), $this->getParam('scriptIsSync'), $this->getParam('createMenuLink'))); } $farmScriptId = $this->db->Insert_ID(); $executeScript = true; } else { $info = $this->db->Execute("SELECT farmid FROM farm_role_scripts WHERE event_name=?", array($this->getParam('eventName'))); if ($info['farmid'] != $dbFarm->ID) { throw new Exception("You cannot change farm for script shortcut"); } if ($this->getParam('isShortcut')) { $this->db->Execute("UPDATE farm_role_scripts SET\n scriptid\t= ?,\n farm_roleid\t= ?,\n params\t\t= ?,\n target\t\t= ?,\n version\t\t= ?,\n timeout\t\t= ?,\n issync\t\t= ?\n WHERE event_name = ? AND farmid = ?\n ", array($this->getParam('scriptId'), (int) $farmRoleId, serialize($this->getParam('scriptOptions')), $target, $this->getParam('scriptVersion'), $this->getParam('scriptTimeout'), $this->getParam('scriptIsSync'), $this->getParam('eventName'), $farmId)); } if (!$this->getParam('isShortcut')) { $executeScript = true; } } if ($executeScript) { switch ($target) { case Scalr_Script::TARGET_FARM: $servers = $this->db->GetAll("SELECT server_id FROM servers WHERE status IN (?,?) AND farm_id=?", array(SERVER_STATUS::INIT, SERVER_STATUS::RUNNING, $farmId)); break; case Scalr_Script::TARGET_ROLE: $servers = $this->db->GetAll("SELECT server_id FROM servers WHERE status IN (?,?) AND farm_roleid=?", array(SERVER_STATUS::INIT, SERVER_STATUS::RUNNING, $farmRoleId)); break; case Scalr_Script::TARGET_INSTANCE: $servers = $this->db->GetAll("SELECT server_id FROM servers WHERE status IN (?,?) AND server_id=?", array(SERVER_STATUS::INIT, SERVER_STATUS::RUNNING, $serverId)); break; case Scalr_Script::TARGET_ALL: $servers = $this->db->GetAll("SELECT server_id FROM servers WHERE status IN (?,?) AND env_id = ?", array(SERVER_STATUS::INIT, SERVER_STATUS::RUNNING, $this->getEnvironmentId())); break; } $scriptSettings = array('version' => $this->getParam('scriptVersion'), 'scriptid' => $this->getParam('scriptId'), 'timeout' => $this->getParam('scriptTimeout'), 'issync' => $this->getParam('scriptIsSync'), 'params' => serialize($this->getParam('scriptOptions'))); // send message to start executing task (starts script) if (count($servers) > 0) { foreach ($servers as $server) { $DBServer = DBServer::LoadByID($server['server_id']); $msg = new Scalr_Messaging_Msg_ExecScript("Manual"); $msg->setServerMetaData($DBServer); $script = Scalr_Scripting_Manager::prepareScript($scriptSettings, $DBServer); $itm = new stdClass(); // Script $itm->asynchronous = $script['issync'] == 1 ? '0' : '1'; $itm->timeout = $script['timeout']; if ($script['body']) { $itm->name = $script['name']; $itm->body = $script['body']; } else { $itm->path = $script['path']; } $itm->executionId = $script['execution_id']; $msg->scripts = array($itm); try { $msg->globalVariables = array(); $globalVariables = new Scalr_Scripting_GlobalVariables($DBServer->envId); $vars = $globalVariables->listVariables($DBServer->roleId, $DBServer->farmId, $DBServer->farmRoleId); foreach ($vars as $k => $v) { $msg->globalVariables[] = (object) array('name' => $k, 'value' => $v); } } catch (Exception $e) { } $DBServer->SendMessage($msg, false, true); } } } $this->response->success('Script execution has been queued. Script will be executed on selected instance(s) within couple of minutes.'); }
public function xUpdateAgentAction() { $this->request->defineParams(array('serverId')); if (!$this->db->GetOne("SELECT id FROM scripts WHERE id='2102' AND clientid='0'")) { throw new Exception("Automatical scalarizr update doesn't supported by this scalr version"); } $dbServer = DBServer::LoadByID($this->getParam('serverId')); $this->user->getPermissions()->validate($dbServer); $eventName = Scalr_Scripting_Manager::generateEventName('CustomEvent'); $target = SCRIPTING_TARGET::INSTANCE; $serverId = $dbServer->serverId; $farmRoleId = $dbServer->farmRoleId; $farmId = $dbServer->farmId; $this->db->Execute("INSERT INTO farm_role_scripts SET\n\t\t\tscriptid\t= ?,\n\t\t\tfarmid\t\t= ?,\n\t\t\tfarm_roleid\t= ?,\n\t\t\tparams\t\t= ?,\n\t\t\tevent_name\t= ?,\n\t\t\ttarget\t\t= ?,\n\t\t\tversion\t\t= ?,\n\t\t\ttimeout\t\t= ?,\n\t\t\tissync\t\t= ?,\n\t\t\tismenuitem\t= ?\n\t\t", array(2102, (int) $farmId, (int) $farmRoleId, serialize(array()), $eventName, $target, $this->db->GetOne("SELECT MAX(revision) FROM script_revisions WHERE scriptid='2102'"), 300, 0, 0)); $farmScriptId = $this->db->Insert_ID(); $message = new Scalr_Messaging_Msg_ExecScript($eventName); $message->meta[Scalr_Messaging_MsgMeta::EVENT_ID] = "FRSID-{$farmScriptId}"; $dbServer->SendMessage($message); $this->response->success('Scalarizr update successfully initiated. Please wait a few minutes and then refresh the page'); }
public function xExecuteAction() { $this->request->defineParams(array('farmId' => array('type' => 'int'), 'farmRoleId' => array('type' => 'int'), 'serverId' => array('type' => 'string'), 'scriptId' => array('type' => 'int'), 'scriptIsSync' => array('type' => 'int'), 'scriptTimeout' => array('type' => 'int'), 'scriptVersion' => array('type' => 'int'), 'scriptOptions' => array('type' => 'array'), 'createMenuLink' => array('type' => 'int'))); $eventName = Scalr_Scripting_Manager::generateEventName('CustomEvent'); $target = ''; // @TODO: validation if ($this->getParam('serverId')) { $dbServer = DBServer::LoadByID($this->getParam('serverId')); $this->user->getPermissions()->validate($dbServer); $target = SCRIPTING_TARGET::INSTANCE; $serverId = $dbServer->serverId; $farmRoleId = $dbServer->farmRoleId; $farmId = $dbServer->farmId; } else { if ($this->getParam('farmRoleId')) { $dbFarmRole = DBFarmRole::LoadByID($this->getParam('farmRoleId')); $this->user->getPermissions()->validate($dbFarmRole); $target = SCRIPTING_TARGET::ROLE; $farmRoleId = $dbFarmRole->ID; $farmId = $dbFarmRole->FarmID; } else { $dbFarm = DBFarm::LoadByID($this->getParam('farmId')); $this->user->getPermissions()->validate($dbFarm); $target = SCRIPTING_TARGET::FARM; $farmId = $dbFarm->ID; } } if (!$this->getParam('eventName')) { $this->db->Execute("INSERT INTO farm_role_scripts SET\n\t\t\t\tscriptid\t= ?,\n\t\t\t\tfarmid\t\t= ?,\n\t\t\t\tfarm_roleid\t= ?,\n\t\t\t\tparams\t\t= ?,\n\t\t\t\tevent_name\t= ?,\n\t\t\t\ttarget\t\t= ?,\n\t\t\t\tversion\t\t= ?,\n\t\t\t\ttimeout\t\t= ?,\n\t\t\t\tissync\t\t= ?,\n\t\t\t\tismenuitem\t= ?\n\t\t\t", array($this->getParam('scriptId'), (int) $farmId, (int) $farmRoleId, serialize($this->getParam('scriptOptions')), $eventName, $target, $this->getParam('scriptVersion'), $this->getParam('scriptTimeout'), $this->getParam('scriptIsSync'), $this->getParam('createMenuLink'))); $farmScriptId = $this->db->Insert_ID(); $executeScript = true; } else { $info = $this->db->Execute("SELECT farmid FROM farm_role_scripts WHERE event_name=?", array($this->getParam('eventName'))); if ($info['farmid'] != $dbFarm->ID) { throw new Exception("You cannot change farm for script shortcut"); } $this->db->Execute("UPDATE farm_role_scripts SET\n\t\t\t\tscriptid\t= ?,\n\t\t\t\tfarm_roleid\t= ?,\n\t\t\t\tparams\t\t= ?,\n\t\t\t\ttarget\t\t= ?,\n\t\t\t\tversion\t\t= ?,\n\t\t\t\ttimeout\t\t= ?,\n\t\t\t\tissync\t\t= ?\n\t\t\tWHERE event_name = ? AND farmid = ?\n\t\t\t", array($this->getParam('scriptId'), (int) $farmRoleId, serialize($this->getParam('scriptOptions')), $target, $this->getParam('scriptVersion'), $this->getParam('scriptTimeout'), $this->getParam('scriptIsSync'), $this->getParam('eventName'), $farmId)); if (!$this->getParam('isShortcut')) { $executeScript = true; } } if ($executeScript) { switch ($target) { case SCRIPTING_TARGET::FARM: $servers = $this->db->GetAll("SELECT server_id FROM servers WHERE status IN (?,?) AND farm_id=?", array(SERVER_STATUS::INIT, SERVER_STATUS::RUNNING, $farmId)); break; case SCRIPTING_TARGET::ROLE: $servers = $this->db->GetAll("SELECT server_id FROM servers WHERE status IN (?,?) AND farm_roleid=?", array(SERVER_STATUS::INIT, SERVER_STATUS::RUNNING, $farmRoleId)); break; case SCRIPTING_TARGET::INSTANCE: $servers = $this->db->GetAll("SELECT server_id FROM servers WHERE status IN (?,?) AND server_id=?", array(SERVER_STATUS::INIT, SERVER_STATUS::RUNNING, $serverId)); break; } if (count($servers) > 0) { foreach ($servers as $server) { $DBServer = DBServer::LoadByID($server['server_id']); $message = new Scalr_Messaging_Msg_ExecScript($eventName); $message->meta[Scalr_Messaging_MsgMeta::EVENT_ID] = "FRSID-{$farmScriptId}"; /*****/ $message = Scalr_Scripting_Manager::extendMessage($message, $DBServer); /*****/ $DBServer->SendMessage($message); } } } $this->response->success('Script executed'); }
public function OnStartForking() { // start cron, which runs scripts by it's schedule queue try { $db = Core::GetDBInstance(null, true); // set status to "finished" for active tasks, which ended or executed once $info = $db->Execute("UPDATE scheduler SET `status` = ? WHERE\r\n\t\t\t\t`status` = ? AND (`end_time` < NOW() OR (`last_start_time` < NOW() AND `restart_every` = 0))", array(Scalr_SchedulerTask::STATUS_FINISHED, Scalr_SchedulerTask::STATUS_ACTIVE)); // get active tasks: first run (condition and last_start_time is null), others (condition and last_start_time + interval * 0.9 < now()) $taskList = $db->GetAll("SELECT *\r\n\t\t\t\tFROM scheduler\r\n\t\t\t\tWHERE `status` = ? AND (`end_time` > NOW() OR `end_time` IS NULL) AND (`start_time` <= NOW() OR `start_time` IS NULL) AND (\r\n\t\t\t\t\t`last_start_time` IS NULL OR\r\n\t\t\t\t\t`last_start_time` IS NOT NULL AND (last_start_time + INTERVAL (restart_every * 0.9 * 60) SECOND < NOW())\r\n\t\t\t\t)\r\n\t\t\t\tORDER BY IF (last_start_time, last_start_time, start_time), order_index ASC\r\n\t\t\t", array(Scalr_SchedulerTask::STATUS_ACTIVE)); if (!$taskList) { $this->Logger->info(_("There is no tasks to execute in scheduler table")); exit; } foreach ($taskList as $task) { // check account status (active or inactive) try { if (Scalr_Account::init()->loadById($task['account_id'])->status != Scalr_Account::STATUS_ACTIVE) { continue; } } catch (Exception $e) { $this->Logger->info("Invalid scheduler task #{$task['id']}: {$e->getMessage()}"); } // check time $lastStartTime = $task['last_start_time'] ? strtotime($task['last_start_time']) : NULL; if ($lastStartTime) { if ($task['start_time'] == NULL) { // disallow execute earlier if ($lastStartTime + $task['restart_every'] * 60 > time()) { continue; } } else { // try to auto-align time to start time $startTime = strtotime($task['start_time']); $num = (time() - $startTime) / ($task['restart_every'] * 60); /*file_put_contents("test.txt", print_r($task['name'], true), FILE_APPEND); file_put_contents("test.txt", " - ", FILE_APPEND); file_put_contents("test.txt", print_r(date('r', $lastStartTime), true), FILE_APPEND); file_put_contents("test.txt", " - ", FILE_APPEND); file_put_contents("test.txt", print_r(date('r'), true), FILE_APPEND); file_put_contents("test.txt", " - ", FILE_APPEND); file_put_contents("test.txt", print_r($num, true), FILE_APPEND); file_put_contents("test.txt", " - ", FILE_APPEND); file_put_contents("test.txt", print_r(floor($num), true), FILE_APPEND); file_put_contents("test.txt", " - ", FILE_APPEND); file_put_contents("test.txt", print_r(round($num, 0, PHP_ROUND_HALF_UP), true), FILE_APPEND); file_put_contents("test.txt", "\n", FILE_APPEND);*/ // num sholud be less than 0.5 if (floor($num) != round($num, 0, PHP_ROUND_HALF_UP)) { continue; } } } // Terminate, Launch farm or execute script $farmRoleNotFound = false; switch ($task['type']) { case Scalr_SchedulerTask::LAUNCH_FARM: try { $farmId = $task['target_id']; $DBFarm = DBFarm::LoadByID($farmId); if ($DBFarm->Status == FARM_STATUS::TERMINATED) { // launch farm Scalr::FireEvent($farmId, new FarmLaunchedEvent(true)); $this->Logger->info(sprintf("Farm #{$farmId} successfully launched")); } elseif ($DBFarm->Status == FARM_STATUS::RUNNING) { // farm is running $this->Logger->info(sprintf("Farm #{$farmId} is already running")); } else { // farm can't be launched $this->Logger->info(sprintf("Farm #{$farmId} can't be launched because of it's status: {$DBFarm->Status}")); } } catch (Exception $e) { // farm not found $farmRoleNotFound = true; $this->Logger->info(sprintf("Farm #{$farmId} was not found and can't be launched")); } break; case SCHEDULE_TASK_TYPE::TERMINATE_FARM: try { // get config settings $farmId = $task['target_id']; $config = unserialize($task['config']); $deleteDNSZones = (int) $config['deleteDNSZones']; $deleteCloudObjects = (int) $config['deleteCloudObjects']; $keepCloudObjects = $deleteCloudObjects == 1 ? 0 : 1; $DBFarm = DBFarm::LoadByID($farmId); if ($DBFarm->Status == FARM_STATUS::RUNNING) { // terminate farm $event = new FarmTerminatedEvent($deleteDNSZones, $keepCloudObjects, false, $keepCloudObjects); Scalr::FireEvent($farmId, $event); $this->Logger->info(sprintf("Farm successfully terminated")); } else { $this->Logger->info(sprintf("Farm #{$farmId} can't be terminated because of it's status")); } } catch (Exception $e) { // role not found $farmRoleNotFound = true; $this->Logger->info(sprintf("Farm #{$farmId} was not found and can't be terminated")); } break; case SCHEDULE_TASK_TYPE::SCRIPT_EXEC: // generate event name $eventName = Scalr_Scripting_Manager::generateEventName('CustomEvent'); $instances = array(); try { // get variables for SQL INSERT or UPDATE $config = unserialize($task['config']); if (!$config['scriptId']) { throw new Exception(_("Script %s is not existed"), $config['scriptId']); } // check avaliable script version if (!$db->GetOne("SELECT id FROM script_revisions WHERE scriptid = ? AND revision = ? AND approval_state = ?", array($config['scriptId'], $config['scriptVersion'], APPROVAL_STATE::APPROVED))) { throw new Exception(_("Selected version is not approved or no longer available")); } // get executing object by target_type variable switch ($task['target_type']) { case SCRIPTING_TARGET::FARM: $DBFarm = DBFarm::LoadByID($task['target_id']); $farmId = $DBFarm->ID; $farmRoleId = null; $servers = $db->GetAll("SELECT * FROM servers WHERE `status` IN (?,?) AND farm_id = ?", array(SERVER_STATUS::INIT, SERVER_STATUS::RUNNING, $farmId)); break; case SCRIPTING_TARGET::ROLE: $farmRoleId = $task['target_id']; $DBFarmRole = DBFarmRole::LoadByID($farmRoleId); $farmId = $DBFarmRole->GetFarmObject()->ID; $servers = $db->GetAll("SELECT * FROM servers WHERE `status` IN (?,?) AND farm_roleid = ?", array(SERVER_STATUS::INIT, SERVER_STATUS::RUNNING, $farmRoleId)); break; case SCRIPTING_TARGET::INSTANCE: $instanceArgs = explode(":", $task['target_id']); $farmRoleId = $instanceArgs[0]; $DBFarmRole = DBFarmRole::LoadByID($farmRoleId); // target for instance looks like "farm_roleid:index" // script gets farmid conformed to the roleid and index $servers = $db->GetAll("SELECT * FROM servers WHERE `status` IN (?,?) AND farm_roleid = ? AND `index` = ? ", array(SERVER_STATUS::INIT, SERVER_STATUS::RUNNING, $farmRoleId, $instanceArgs[1])); $farmId = $servers[0]["farm_id"]; break; } if ($servers) { $db->Execute("INSERT INTO farm_role_scripts SET\r\n\t\t\t\t\t\t\t\t\tscriptid\t= ?,\r\n\t\t\t\t\t\t\t\t\tfarmid\t\t= ?,\r\n\t\t\t\t\t\t\t\t\tfarm_roleid\t= ?,\r\n\t\t\t\t\t\t\t\t\tparams\t\t= ?,\r\n\t\t\t\t\t\t\t\t\tevent_name\t= ?,\r\n\t\t\t\t\t\t\t\t\ttarget\t\t= ?,\r\n\t\t\t\t\t\t\t\t\tversion\t\t= ?,\r\n\t\t\t\t\t\t\t\t\ttimeout\t\t= ?,\r\n\t\t\t\t\t\t\t\t\tissync\t\t= ?,\r\n\t\t\t\t\t\t\t\t\torder_index = ?,\r\n\t\t\t\t\t\t\t\t\tismenuitem\t= ?,\r\n\t\t\t\t\t\t\t\t\t`debug`\t\t= ?\r\n\t\t\t\t\t\t\t\t", array($config['scriptId'], $farmId, $farmRoleId, serialize($config['scriptOptions']), $eventName, $task['target_type'], $config['scriptVersion'], $config['scriptTimeout'], $config['scriptIsSync'], $task["order_index"], 0, 'scheduler2')); $farmRoleScriptId = $db->Insert_ID(); // send message to start executing task (starts script) foreach ($servers as $server) { $DBServer = DBServer::LoadByID($server['server_id']); $msg = new Scalr_Messaging_Msg_ExecScript($eventName); $msg->meta[Scalr_Messaging_MsgMeta::EVENT_ID] = "FRSID-{$farmRoleScriptId}"; $msg = Scalr_Scripting_Manager::extendMessage($msg, $DBServer); $DBServer->SendMessage($msg); } } } catch (Exception $e) { // farm or role not found. $farmRoleNotFound = true; $this->Logger->warn(sprintf("Farm, role or instances were not found, script can't be executed")); } break; } if ($farmRoleNotFound) { // delete task if farm or role not found. //$db->Execute("DELETE FROM scheduler WHERE id = ?", array($task['id'])); //$this->Logger->warn(sprintf("Task {$task['id']} was deleted, because of the farm or role was not found")); } else { $db->Execute("UPDATE scheduler SET last_start_time = NOW() WHERE id = ?", array($task['id'])); $this->Logger->info(sprintf("Task {$task['id']} successfully sent")); } } } catch (Exception $e) { $this->Logger->warn(sprintf("Can't execute task {$task['id']}. Error message: %s", $e->getMessage())); } }