/** * @param string $serverId * @param string $name * @param string $description * @param bool $createRole * @param string $replaceRole * @param bool $replaceImage * @param int $rootVolumeSize * @param string $rootVolumeType * @param int $rootVolumeIops * @throws Exception */ public function xServerCreateSnapshotAction($serverId, $name = '', $description = '', $createRole = false, $replaceRole = '', $replaceImage = false, $rootVolumeSize = 0, $rootVolumeType = '', $rootVolumeIops = 0) { $this->request->restrictAccess(Acl::RESOURCE_IMAGES_ENVIRONMENT, Acl::PERM_IMAGES_ENVIRONMENT_MANAGE); if (!$serverId) { throw new Exception('Server not found'); } $dbServer = DBServer::LoadByID($serverId); $this->user->getPermissions()->validate($dbServer); $errorMsg = []; //Check for already running bundle on selected instance $chk = $this->db->GetOne("SELECT id FROM bundle_tasks WHERE server_id=? AND status NOT IN ('success', 'failed') LIMIT 1", array($dbServer->serverId)); if ($chk) { $errorMsg[] = sprintf(_("Server '%s' is already synchonizing."), $dbServer->serverId); } //Check is role already synchronizing... $chk = $this->db->GetOne("SELECT server_id FROM bundle_tasks WHERE prototype_role_id=? AND status NOT IN ('success', 'failed') LIMIT 1", array($dbServer->GetFarmRoleObject()->RoleID)); if ($chk && $chk != $dbServer->serverId) { try { $bDBServer = DBServer::LoadByID($chk); if ($bDBServer->farmId == $dbServer->farmId) { $errorMsg[] = sprintf(_("Role '%s' is already synchronizing."), $dbServer->GetFarmRoleObject()->GetRoleObject()->name); } } catch (Exception $e) { } } if (!empty($errorMsg)) { throw new Exception(implode('\\n', $errorMsg)); } $validator = new \Scalr\UI\Request\Validator(); $validator->addErrorIf(strlen($name) < 3, 'name', _("Role name should be greater than 3 chars")); $validator->addErrorIf(!preg_match("/^[A-Za-z0-9-]+\$/si", $name), 'name', _("Role name is incorrect")); $validator->addErrorIf(!in_array($replaceRole, ['farm', 'all', '']), 'replaceRole', 'Invalid value'); $object = $createRole ? BundleTask::BUNDLETASK_OBJECT_ROLE : BundleTask::BUNDLETASK_OBJECT_IMAGE; $replaceType = SERVER_REPLACEMENT_TYPE::NO_REPLACE; if ($createRole) { $this->request->restrictAccess(Acl::RESOURCE_ROLES_ENVIRONMENT, Acl::PERM_ROLES_ENVIRONMENT_MANAGE); if ($replaceRole == 'farm') { $this->request->restrictFarmAccess($dbServer->GetFarmObject(), Acl::PERM_FARMS_MANAGE); $replaceType = SERVER_REPLACEMENT_TYPE::REPLACE_FARM; } else { if ($replaceRole == 'all') { $this->request->restrictFarmAccess(null, Acl::PERM_FARMS_MANAGE); $replaceType = SERVER_REPLACEMENT_TYPE::REPLACE_ALL; } } } else { $scope = $dbServer->GetFarmRoleObject()->GetRoleObject()->__getNewRoleObject()->getScope(); if ($replaceImage && ($scope == ScopeInterface::SCOPE_ENVIRONMENT && $this->request->isAllowed(Acl::RESOURCE_ROLES_ENVIRONMENT, Acl::PERM_ROLES_ENVIRONMENT_MANAGE) || $scope == ScopeInterface::SCOPE_ACCOUNT && $this->request->isAllowed(Acl::RESOURCE_ROLES_ACCOUNT, Acl::PERM_ROLES_ACCOUNT_MANAGE))) { $replaceType = SERVER_REPLACEMENT_TYPE::REPLACE_ALL; } } if ($createRole) { $roleInfo = $this->db->GetRow("SELECT * FROM roles WHERE name=? AND (client_id IS NULL OR client_id = ? AND env_id IS NULL OR env_id=?) LIMIT 1", array($name, $dbServer->clientId, $dbServer->envId, $dbServer->GetFarmRoleObject()->RoleID)); if ($roleInfo) { if (empty($roleInfo['client_id'])) { $validator->addError('name', _("Selected role name is reserved and cannot be used for custom role")); } else { if ($replaceType != SERVER_REPLACEMENT_TYPE::REPLACE_ALL) { $validator->addError('name', _("Specified role name is already used by another role. You can use this role name only if you will replace old one on ALL your farms.")); } else { if ($replaceType == SERVER_REPLACEMENT_TYPE::REPLACE_ALL && $roleInfo['id'] != $dbServer->GetFarmRoleObject()->RoleID) { $validator->addError('name', _("This Role name is already in use. You cannot replace a Role different from the one you are currently snapshotting.")); } } } } } $roleImage = $dbServer->GetFarmRoleObject()->GetRoleObject()->__getNewRoleObject()->getImage($dbServer->platform, $dbServer->GetCloudLocation()); $rootBlockDevice = []; if ($dbServer->platform == SERVER_PLATFORMS::EC2 && ($dbServer->IsSupported('0.7') && $dbServer->osType == 'linux' || $roleImage->getImage()->isEc2HvmImage())) { if ($rootVolumeSize > 0) { $rootBlockDevice['size'] = $rootVolumeSize; } if (in_array($rootVolumeType, ['standard', 'gp2', 'io1'])) { $rootBlockDevice['volume_type'] = $rootVolumeType; if ($rootVolumeType == 'io1' && $rootVolumeIops > 0) { $rootBlockDevice['iops'] = $rootVolumeIops; } } } if (!$validator->isValid($this->response)) { return; } $ServerSnapshotCreateInfo = new ServerSnapshotCreateInfo($dbServer, $name, $replaceType, $object, $description, $rootBlockDevice); $BundleTask = BundleTask::Create($ServerSnapshotCreateInfo); $BundleTask->createdById = $this->user->id; $BundleTask->createdByEmail = $this->user->getEmail(); if ($dbServer->GetFarmRoleObject()->GetSetting('user-data.scm_branch') == 'feature/image-api') { $BundleTask->generation = 2; } $protoRole = DBRole::loadById($dbServer->GetFarmRoleObject()->RoleID); $BundleTask->osId = $protoRole->osId; if ($protoRole->getOs()->family == 'windows') { $BundleTask->osFamily = $protoRole->getOs()->family; $BundleTask->osVersion = $protoRole->getOs()->generation; $BundleTask->osName = ''; } else { $BundleTask->osFamily = $protoRole->getOs()->family; $BundleTask->osVersion = $protoRole->getOs()->version; $BundleTask->osName = $protoRole->getOs()->name; } if (in_array($protoRole->getOs()->family, array('redhat', 'oel', 'scientific')) && $dbServer->platform == SERVER_PLATFORMS::EC2) { $BundleTask->bundleType = SERVER_SNAPSHOT_CREATION_TYPE::EC2_EBS_HVM; } $BundleTask->save(); $this->response->data(['bundleTaskId' => $BundleTask->id]); $this->response->success("Bundle task successfully created."); }