public static function farmUpdateRoleSettings(DBFarmRole $DBFarmRole, $oldSettings, $newSettings) { $db = \Scalr::getDb(); if (!$newSettings[DBFarmRole::SETTING_AWS_USE_EBS] && $oldSettings[DBFarmRole::SETTING_AWS_USE_EBS]) { $db->Execute("DELETE FROM ec2_ebs WHERE farm_roleid = ? AND ismanual='0'", array($DBFarmRole->ID)); //TODO: Remove Volume? } $DBFarm = $DBFarmRole->GetFarmObject(); if ($newSettings[DBFarmRole::SETTING_AWS_USE_EBS] && !$oldSettings[DBFarmRole::SETTING_AWS_USE_EBS]) { $servers = $DBFarmRole->GetServersByFilter(array('status' => array(SERVER_STATUS::INIT, SERVER_STATUS::RUNNING))); foreach ($servers as $DBServer) { if (!$db->GetRow("SELECT id FROM ec2_ebs WHERE server_id=? AND ismanual='0' LIMIT 1", array($DBServer->serverId))) { if (in_array($DBFarmRole->GetSetting(DBFarmRole::SETTING_AWS_EBS_TYPE), array('standard', 'io1'))) { $type = $DBFarmRole->GetSetting(DBFarmRole::SETTING_AWS_EBS_TYPE); } else { $type = 'standard'; } $DBEBSVolume = new DBEBSVolume(); $DBEBSVolume->attachmentStatus = EC2_EBS_ATTACH_STATUS::CREATING; $DBEBSVolume->isManual = false; $DBEBSVolume->ec2AvailZone = $DBFarmRole->GetSetting(DBFarmRole::SETTING_AWS_AVAIL_ZONE); $DBEBSVolume->ec2Region = $DBFarmRole->CloudLocation; $DBEBSVolume->farmId = $DBFarmRole->FarmID; $DBEBSVolume->farmRoleId = $DBFarmRole->ID; $DBEBSVolume->serverId = $DBServer->serverId; $DBEBSVolume->serverIndex = $DBServer->index; $DBEBSVolume->type = $type; $DBEBSVolume->iops = $DBFarmRole->GetSetting(DBFarmRole::SETTING_AWS_EBS_IOPS); $DBEBSVolume->size = $DBFarmRole->GetSetting(DBFarmRole::SETTING_AWS_EBS_SIZE); $DBEBSVolume->snapId = $DBFarmRole->GetSetting(DBFarmRole::SETTING_AWS_EBS_SNAPID); $DBEBSVolume->mount = $DBFarmRole->GetSetting(DBFarmRole::SETTING_AWS_EBS_MOUNT); $DBEBSVolume->mountPoint = $DBFarmRole->GetSetting(DBFarmRole::SETTING_AWS_EBS_MOUNTPOINT); $DBEBSVolume->mountStatus = $DBFarmRole->GetSetting(DBFarmRole::SETTING_AWS_EBS_MOUNT) ? EC2_EBS_MOUNT_STATUS::AWAITING_ATTACHMENT : EC2_EBS_MOUNT_STATUS::NOT_MOUNTED; $DBEBSVolume->clientId = $DBFarm->ClientID; $DBEBSVolume->envId = $DBFarm->EnvID; $DBEBSVolume->Save(); } } if ($newSettings[DBFarmRole::SETTING_AWS_EBS_MOUNTPOINT] != $oldSettings[DBFarmRole::SETTING_AWS_EBS_MOUNTPOINT]) { $db->Execute("UPDATE ec2_ebs SET mountpoint=? WHERE farm_roleid=? AND ismanual='0'", array($DBFarmRole->GetSetting(DBFarmRole::SETTING_AWS_EBS_MOUNTPOINT), $DBFarmRole->ID)); } } }
protected function ListEBSMountpoints() { $ResponseDOMDocument = $this->CreateResponse(); $MountpointsDOMNode = $ResponseDOMDocument->createElement("mountpoints"); // // List EBS Volumes // if ($this->DBServer->IsSupported("0.7.36")) { $volumes = $this->DB->GetAll("SELECT id FROM ec2_ebs WHERE farm_roleid=? AND server_index=?", array($this->DBServer->farmRoleId, $this->DBServer->index)); } else { $volumes = $this->DB->GetAll("SELECT id FROM ec2_ebs WHERE server_id=? AND attachment_status = ? AND mount_status IN (?,?)", array($this->DBServer->serverId, EC2_EBS_ATTACH_STATUS::ATTACHED, EC2_EBS_MOUNT_STATUS::MOUNTED, EC2_EBS_MOUNT_STATUS::MOUNTING)); } $DBFarmRole = $this->DBServer->GetFarmRoleObject(); if ($DBFarmRole->GetSetting(DBFarmRole::SETTING_AWS_USE_EBS) == 0) { $volumes = array(); } foreach ($volumes as $volume) { $DBEBSVolume = DBEBSVolume::loadById($volume['id']); $mountpoint = $DBEBSVolume->mountPoint ? $DBEBSVolume->mountPoint : ""; if (!$DBEBSVolume->isManual && $mountpoint) { $createfs = $DBEBSVolume->isFsExists ? 0 : 1; } else { $createfs = 0; } if ($mountpoint || $this->DBServer->IsSupported("0.7.36")) { $mountpoints[] = array('name' => $DBEBSVolume->attachmentStatus == EC2_EBS_ATTACH_STATUS::CREATING ? "vol-creating" : $DBEBSVolume->volumeId, 'dir' => $mountpoint, 'createfs' => $createfs, 'volumes' => array($DBEBSVolume), 'isarray' => 0); } } // // Create response // $MountpointDOMNode = $ResponseDOMDocument->createElement("mountpoint"); if (!empty($mountpoints)) { foreach ($mountpoints as $mountpoint) { $MountpointDOMNode->setAttribute("name", $mountpoint['name']); $MountpointDOMNode->setAttribute("dir", $mountpoint['dir']); $MountpointDOMNode->setAttribute("createfs", $mountpoint['createfs']); $MountpointDOMNode->setAttribute("isarray", $mountpoint['isarray']); $VolumesDOMNode = $ResponseDOMDocument->createElement("volumes"); foreach ($mountpoint['volumes'] as $DBEBSVolume) { $VolumeDOMNode = $ResponseDOMDocument->createElement("volume"); $VolumeDOMNode->setAttribute("device", $DBEBSVolume->deviceName); $VolumeDOMNode->setAttribute("volume-id", $DBEBSVolume->volumeId); $VolumesDOMNode->appendChild($VolumeDOMNode); } $MountpointDOMNode->appendChild($VolumesDOMNode); $MountpointsDOMNode->appendChild($MountpointDOMNode); } } $ResponseDOMDocument->documentElement->appendChild($MountpointsDOMNode); return $ResponseDOMDocument; }
/** * {@inheritdoc} * @see \Scalr\System\Pcntl\ProcessInterface::StartThread() */ public function StartThread($volume) { $DBEBSVolume = DBEBSVolume::loadById($volume['id']); $aws = $DBEBSVolume->getEnvironmentObject()->aws($DBEBSVolume); if ($DBEBSVolume->volumeId) { try { $volumeinfo = $aws->ec2->volume->describe($DBEBSVolume->volumeId)->get(0); } catch (Exception $e) { if (stristr($e->getMessage(), "does not exist")) { $DBEBSVolume->delete(); exit; } else { $this->logger->error("Cannot get EBS volume information: {$e->getMessage()}. Database ID: {$DBEBSVolume->id}"); } } } $attach_volume = null; switch ($DBEBSVolume->attachmentStatus) { case EC2_EBS_ATTACH_STATUS::DELETING: if ($DBEBSVolume->volumeId) { try { $aws->ec2->volume->delete($DBEBSVolume->volumeId); $removeFromDb = true; } catch (Exception $e) { if (stristr($e->getMessage(), "does not exist")) { $removeFromDb = true; } else { $this->logger->error("Cannot remove volume: {$e->getMessage()}. Database ID: {$DBEBSVolume->id}"); } } } else { $removeFromDb = true; } if ($removeFromDb) { $DBEBSVolume->delete(); } break; case EC2_EBS_ATTACH_STATUS::ATTACHING: switch ($volumeinfo->status) { case AMAZON_EBS_STATE::IN_USE: $volumeInstanceId = $volumeinfo->attachmentSet->get(0)->instanceId; $DBServer = DBServer::LoadByID($DBEBSVolume->serverId); if ($volumeInstanceId == $DBServer->GetProperty(EC2_SERVER_PROPERTIES::INSTANCE_ID)) { $DBEBSVolume->attachmentStatus = EC2_EBS_ATTACH_STATUS::ATTACHED; } else { $this->logger->warn(sprintf(_("Volume #%s should be attached to server %s (%s), " . "but it already attached to instance %s. " . "Re-attaching..."), $DBEBSVolume->volumeId, $DBServer->GetProperty(EC2_SERVER_PROPERTIES::INSTANCE_ID), $DBServer->serverId, $volumeInstanceId)); try { $aws->ec2->volume->detach($DBEBSVolume->volumeId, $volumeInstanceId, $DBEBSVolume->deviceName, true); } catch (Exception $e) { } } $DBEBSVolume->save(); break; case AMAZON_EBS_STATE::AVAILABLE: $attach_volume = true; break; case AMAZON_EBS_STATE::ATTACHING: // NOTHING TO DO; break; default: $this->logger->error("Cannot attach volume to server {$DBServer->serverId}. " . "Volume status: {$volumeinfo->status}. " . "Volume Database ID: {$DBEBSVolume->id}. " . "Volume ID: {$DBEBSVolume->volumeId} (" . serialize($volumeinfo) . ")"); break; } break; case EC2_EBS_ATTACH_STATUS::CREATING: if (!$DBEBSVolume->volumeId) { if ($DBEBSVolume->ec2AvailZone == 'x-scalr-diff' || stristr($DBEBSVolume->ec2AvailZone, "x-scalr-custom")) { if ($DBEBSVolume->serverId) { $DBEBSVolume->ec2AvailZone = DBServer::LoadByID($DBEBSVolume->serverId)->GetProperty(EC2_SERVER_PROPERTIES::AVAIL_ZONE); } else { $DBEBSVolume->delete(); } } try { $req = new CreateVolumeRequestData($DBEBSVolume->ec2AvailZone, $DBEBSVolume->size); $req->volumeType = $DBEBSVolume->type; if (!empty($DBEBSVolume->snapId)) { $req->snapshotId = $DBEBSVolume->snapId; } if ($req->volumeType == 'io1') { $req->iops = $DBEBSVolume->iops; } $result = $aws->ec2->volume->create($req); if ($result->volumeId) { $DBEBSVolume->volumeId = $result->volumeId; $DBEBSVolume->save(); $this->logger->info("Created new volume: {$DBEBSVolume->volumeId}. Database ID: {$DBEBSVolume->id}"); } else { $this->logger->error("Cannot create volume. Database ID: {$DBEBSVolume->id}"); exit; } } catch (Exception $e) { if (stristr($e->getMessage(), "must be at least snapshot size")) { $matches = []; @preg_match_all("/(([0-9]+)GiB)/sim", $e->getMessage(), $matches); if (!empty($matches[2][1]) && $matches[2][1] > 1) { $DBEBSVolume->size = $matches[2][1]; $DBEBSVolume->save(); } } if ($DBEBSVolume->farmId) { $this->logger->error(new FarmLogMessage(!empty($DBEBSVolume->farmId) ? $DBEBSVolume->farmId : null, "Cannot create volume: {$e->getMessage()}", !empty($DBEBSVolume->serverId) ? $DBEBSVolume->serverId : null, !empty($DBEBSVolume->envId) ? $DBEBSVolume->envId : null, !empty($DBEBSVolume->farmRoleId) ? $DBEBSVolume->farmRoleId : null)); } else { $this->logger->error("Cannot create volume: {$e->getMessage()}. Database ID: {$DBEBSVolume->id}"); } exit; } } else { if ($volumeinfo && $DBEBSVolume->volumeId) { if ($volumeinfo->status == AMAZON_EBS_STATE::AVAILABLE) { if (!$DBEBSVolume->serverId) { $DBEBSVolume->attachmentStatus = EC2_EBS_ATTACH_STATUS::AVAILABLE; $DBEBSVolume->save(); } else { $attach_volume = true; } } } } break; } switch ($DBEBSVolume->mountStatus) { case EC2_EBS_MOUNT_STATUS::AWAITING_ATTACHMENT: if ($DBEBSVolume->attachmentStatus == EC2_EBS_ATTACH_STATUS::ATTACHED) { $DBEBSVolume->mountStatus = EC2_EBS_MOUNT_STATUS::MOUNTING; $DBEBSVolume->save(); $DBServer = DBServer::LoadByID($DBEBSVolume->serverId); $DBServer->SendMessage(new Scalr_Messaging_Msg_MountPointsReconfigure()); } break; case EC2_EBS_MOUNT_STATUS::MOUNTING: //NOTHING TO DO break; } if ($attach_volume) { try { $DBServer = DBServer::LoadByID($DBEBSVolume->serverId); if ($DBServer->status != SERVER_STATUS::RUNNING && $DBServer->IsSupported("0.7.36")) { $DBEBSVolume->attachmentStatus = EC2_EBS_ATTACH_STATUS::ATTACHING; $DBEBSVolume->save(); return; } } catch (\Scalr\Exception\ServerNotFoundException $e) { if ($DBEBSVolume->volumeId) { $DBEBSVolume->attachmentStatus = EC2_EBS_ATTACH_STATUS::AVAILABLE; $DBEBSVolume->mountStatus = EC2_EBS_MOUNT_STATUS::NOT_MOUNTED; $DBEBSVolume->save(); } } if ($DBServer) { //NOT supported if ($DBServer->GetOsType() == 'windows') { return; } try { $device = $DBServer->GetFreeDeviceName(); $result = $aws->ec2->volume->attach($DBEBSVolume->volumeId, $DBServer->GetProperty(EC2_SERVER_PROPERTIES::INSTANCE_ID), $device); } catch (Exception $e) { if (!stristr($e->getMessage(), "is not in the same availability zone as instance") && !stristr($e->getMessage(), "Cannot get a list of used disk devices")) { $this->logger->fatal("Cannot attach volume: {$e->getMessage()}"); } else { $this->logger->info("Cannot attach volume: {$e->getMessage()}"); } return false; } if ($result && $result->status == AMAZON_EBS_STATE::IN_USE || $result->status == AMAZON_EBS_STATE::ATTACHING) { $DBEBSVolume->attachmentStatus = EC2_EBS_ATTACH_STATUS::ATTACHING; $DBEBSVolume->deviceName = $device; $DBEBSVolume->save(); } else { $this->logger->warn("Cannot attach volume: volume status: {$result->status} ({$volumeinfo->status}). " . "Database ID: {$DBEBSVolume->id}. " . "Volume ID: {$DBEBSVolume->volumeId}"); } } } }
/** * {@inheritdoc} * @see EventObserver::OnHostInit() */ public function OnHostInit(\HostInitEvent $event) { if ($event->DBServer->platform != \SERVER_PLATFORMS::EC2) { return; } $DBFarmRole = $event->DBServer->GetFarmRoleObject(); if ($DBFarmRole->GetSetting(DBFarmRole::SETTING_AWS_USE_EBS)) { if (!$this->DB->GetOne("\n SELECT id FROM ec2_ebs\n WHERE farm_roleid=? AND server_index=? AND ismanual='0'\n LIMIT 1\n ", array($event->DBServer->farmRoleId, $event->DBServer->index))) { if (in_array($DBFarmRole->GetSetting(DBFarmRole::SETTING_AWS_EBS_TYPE), array('standard', 'io1', 'gp2'))) { $type = $DBFarmRole->GetSetting(DBFarmRole::SETTING_AWS_EBS_TYPE); } else { $type = 'standard'; } $DBEBSVolume = new \DBEBSVolume(); $DBEBSVolume->attachmentStatus = \EC2_EBS_ATTACH_STATUS::CREATING; $DBEBSVolume->isManual = 0; $DBEBSVolume->ec2AvailZone = $DBFarmRole->GetSetting(DBFarmRole::SETTING_AWS_AVAIL_ZONE); $DBEBSVolume->ec2Region = $event->DBServer->GetProperty(\EC2_SERVER_PROPERTIES::REGION); $DBEBSVolume->farmId = $DBFarmRole->FarmID; $DBEBSVolume->farmRoleId = $DBFarmRole->ID; $DBEBSVolume->serverId = $event->DBServer->serverId; $DBEBSVolume->serverIndex = $event->DBServer->index; $DBEBSVolume->size = $DBFarmRole->GetSetting(DBFarmRole::SETTING_AWS_EBS_SIZE); $DBEBSVolume->type = $type; $DBEBSVolume->iops = $DBFarmRole->GetSetting(DBFarmRole::SETTING_AWS_EBS_IOPS); $DBEBSVolume->snapId = $DBFarmRole->GetSetting(DBFarmRole::SETTING_AWS_EBS_SNAPID); $DBEBSVolume->isFsExists = $DBFarmRole->GetSetting(DBFarmRole::SETTING_AWS_EBS_SNAPID) ? 1 : 0; $DBEBSVolume->mount = $DBFarmRole->GetSetting(DBFarmRole::SETTING_AWS_EBS_MOUNT); $DBEBSVolume->mountPoint = $DBFarmRole->GetSetting(DBFarmRole::SETTING_AWS_EBS_MOUNTPOINT); $DBEBSVolume->mountStatus = $DBFarmRole->GetSetting(DBFarmRole::SETTING_AWS_EBS_MOUNT) ? \EC2_EBS_MOUNT_STATUS::AWAITING_ATTACHMENT : \EC2_EBS_MOUNT_STATUS::NOT_MOUNTED; $DBEBSVolume->clientId = $event->DBServer->GetFarmObject()->ClientID; $DBEBSVolume->envId = $event->DBServer->envId; $DBEBSVolume->Save(); } } }
public function xDetachAction() { $this->request->restrictAccess(Acl::RESOURCE_AWS_VOLUMES, Acl::PERM_AWS_VOLUMES_MANAGE); $aws = $this->getEnvironment()->aws($this->getParam('cloudLocation')); $this->request->defineParams(array('cloudLocation', 'volumeId', 'forceDetach')); $isForce = $this->getParam('forceDetach') == 1; //Describes if the volume exists and checks user access permissions $decision = $this->getFilteringDecision(); //We should check permissions to this volume $this->describeVolume($this->getParam('cloudLocation'), $this->getParam('volumeId')); /* @var $att AttachmentSetResponseData */ $att = $aws->ec2->volume->detach($this->getParam('volumeId'), null, null, $isForce); if ($att->volumeId && ($att->status == AttachmentSetResponseData::STATUS_DETACHING || $att->status == AttachmentSetResponseData::STATUS_DETACHED)) { $dbEbsVolume = null; try { $dbEbsVolume = DBEBSVolume::loadByVolumeId($this->getParam('volumeId')); } catch (\Exception $e) { } if (!empty($dbEbsVolume)) { if ($dbEbsVolume->isManual) { $dbEbsVolume->delete(); } else { if (!$dbEbsVolume->isManual) { $dbEbsVolume->attachmentStatus = EC2_EBS_ATTACH_STATUS::AVAILABLE; $dbEbsVolume->mountStatus = EC2_EBS_MOUNT_STATUS::NOT_MOUNTED; $dbEbsVolume->serverId = ''; $dbEbsVolume->deviceName = ''; $dbEbsVolume->save(); } } } } $this->response->success('Volume has been successfully detached'); }
public function xListVolumesAction() { $this->request->defineParams(array('sort' => array('type' => 'json', 'default' => array('property' => 'volumeId', 'direction' => 'DESC')), 'volumeId')); $amazonEC2Client = Scalr_Service_Cloud_Aws::newEc2($this->getParam('cloudLocation'), $this->getEnvironment()->getPlatformConfigValue(Modules_Platforms_Ec2::PRIVATE_KEY), $this->getEnvironment()->getPlatformConfigValue(Modules_Platforms_Ec2::CERTIFICATE)); // Rows $aws_response = $amazonEC2Client->DescribeVolumes(); $rowz = $aws_response->volumeSet->item; if ($rowz instanceof stdClass) { $rowz = array($rowz); } $vols = array(); foreach ($rowz as $pk => $pv) { if ($pv->attachmentSet && $pv->attachmentSet->item) { $pv->attachmentSet = $pv->attachmentSet->item; } if ($this->getParam('volumeId') && $this->getParam('volumeId') != $pv->volumeId) { continue; } $item = array('volumeId' => $pv->volumeId, 'size' => $pv->size, 'snapshotId' => $pv->snapshotId, 'availZone' => $pv->availabilityZone, 'status' => $pv->status, 'attachmentStatus' => $pv->attachmentSet->status, 'device' => $pv->attachmentSet->device, 'instanceId' => $pv->attachmentSet->instanceId); $item['autoSnaps'] = $this->db->GetOne("SELECT id FROM autosnap_settings WHERE objectid=? AND object_type=?", array($pv->volumeId, AUTOSNAPSHOT_TYPE::EBSSnap)) ? true : false; $DBEBSVolume = false; try { $DBEBSVolume = DBEBSVolume::loadByVolumeId($pv->volumeId); //$sort_key = "{$DBEBSVolume->farmId}_{$DBEBSVolume->farmRoleId}_{$pv->volumeId}"; $item['farmId'] = $DBEBSVolume->farmId; $item['farmRoleId'] = $DBEBSVolume->farmRoleId; $item['serverIndex'] = $DBEBSVolume->serverIndex; $item['serverId'] = $DBEBSVolume->serverId; $item['mountStatus'] = $DBEBSVolume->mountStatus; $item['farmName'] = DBFarm::LoadByID($DBEBSVolume->farmId)->Name; $item['roleName'] = DBFarmRole::LoadByID($DBEBSVolume->farmRoleId)->GetRoleObject()->name; $item['autoAttach'] = true; } catch (Exception $e) { } if (!$DBEBSVolume && $item['instanceId']) { try { $dbServer = DBServer::LoadByPropertyValue(EC2_SERVER_PROPERTIES::INSTANCE_ID, $item['instanceId']); $item['farmId'] = $dbServer->farmId; $item['farmRoleId'] = $dbServer->farmRoleId; $item['serverIndex'] = $dbServer->index; $item['serverId'] = $dbServer->serverId; $item['farmName'] = $dbServer->GetFarmObject()->Name; $item['mountStatus'] = false; $item['roleName'] = $dbServer->GetFarmRoleObject()->GetRoleObject()->name; } catch (Exception $e) { } } $vols[] = $item; } $response = $this->buildResponseFromData($vols, array('instanceId', 'volumeId', 'snapshotId', 'farmId', 'farmRoleId', 'availZone')); $this->response->data($response); }
public function StartThread($volume) { $db = Core::GetDBInstance(null, true); $DBEBSVolume = DBEBSVolume::loadById($volume['id']); $EC2Client = Scalr_Service_Cloud_Aws::newEc2($DBEBSVolume->ec2Region, $DBEBSVolume->getEnvironmentObject()->getPlatformConfigValue(Modules_Platforms_Ec2::PRIVATE_KEY), $DBEBSVolume->getEnvironmentObject()->getPlatformConfigValue(Modules_Platforms_Ec2::CERTIFICATE)); if ($DBEBSVolume->volumeId) { try { $result = $EC2Client->DescribeVolumes($DBEBSVolume->volumeId); $volumeinfo = $result->volumeSet->item; } catch (Exception $e) { if (stristr($e->getMessage(), "does not exist")) { $DBEBSVolume->delete(); exit; } else { $this->logger->error("Cannot get EBS volume information: {$e->getMessage()}. Database ID: {$DBEBSVolume->id}"); } } } switch ($DBEBSVolume->attachmentStatus) { case EC2_EBS_ATTACH_STATUS::DELETING: if ($DBEBSVolume->volumeId) { try { $EC2Client->DeleteVolume($DBEBSVolume->volumeId); $removeFromDb = true; } catch (Exception $e) { if (stristr($e->getMessage(), "does not exist")) { $removeFromDb = true; } else { $this->logger->error("Cannot remove volume: {$e->getMessage()}. Database ID: {$DBEBSVolume->id}"); } } } else { $removeFromDb = true; } if ($removeFromDb) { $DBEBSVolume->delete(); } break; case EC2_EBS_ATTACH_STATUS::ATTACHING: switch ($volumeinfo->status) { case AMAZON_EBS_STATE::IN_USE: $volumeInstanceId = $volumeinfo->attachmentSet->item->instanceId; $DBServer = DBServer::LoadByID($DBEBSVolume->serverId); if ($volumeInstanceId == $DBServer->GetProperty(EC2_SERVER_PROPERTIES::INSTANCE_ID)) { $DBEBSVolume->attachmentStatus = EC2_EBS_ATTACH_STATUS::ATTACHED; } else { $this->logger->warn(sprintf(_("Volume #%s should be attached to server %s (%s), but it already attached to instance %s. Re-attaching..."), $DBEBSVolume->volumeId, $DBServer->GetProperty(EC2_SERVER_PROPERTIES::INSTANCE_ID), $DBServer->serverId, $volumeInstanceId)); try { $DetachVolumeType = new DetachVolumeType($DBEBSVolume->volumeId, $volumeInstanceId, $DBEBSVolume->deviceName, true); $EC2Client->DetachVolume($DetachVolumeType); } catch (Exception $e) { } } $DBEBSVolume->save(); break; case AMAZON_EBS_STATE::AVAILABLE: $attach_volume = true; break; case AMAZON_EBS_STATE::ATTACHING: // NOTHING TO DO; break; default: $this->logger->error("Cannot attach volume to server {$DBServer->serverId}. Volume status: {$volumeinfo->status}. Volume Database ID: {$DBEBSVolume->id}. Volume ID: {$DBEBSVolume->volumeId} (" . serialize($volumeinfo) . ")"); break; } break; case EC2_EBS_ATTACH_STATUS::CREATING: if (!$DBEBSVolume->volumeId) { if ($DBEBSVolume->ec2AvailZone == 'x-scalr-diff' || stristr($DBEBSVolume->ec2AvailZone, "x-scalr-custom")) { if ($DBEBSVolume->serverId) { $DBEBSVolume->ec2AvailZone = DBServer::LoadByID($DBEBSVolume->serverId)->GetProperty(EC2_SERVER_PROPERTIES::AVAIL_ZONE); } else { $DBEBSVolume->delete(); } } $CreateVolumeType = new CreateVolumeType($DBEBSVolume->size, $DBEBSVolume->snapId ? $DBEBSVolume->snapId : "", $DBEBSVolume->ec2AvailZone); try { $result = $EC2Client->CreateVolume($CreateVolumeType); if ($result->volumeId) { $DBEBSVolume->volumeId = $result->volumeId; $DBEBSVolume->save(); $this->logger->info("Created new volume: {$DBEBSVolume->volumeId}. Database ID: {$DBEBSVolume->id}"); } else { $this->logger->error("Cannot create volume. Database ID: {$DBEBSVolume->id}"); exit; } } catch (Exception $e) { if (stristr($e->getMessage(), "must be at least snapshot size")) { @preg_match_all("/(([0-9]+)GiB)/sim", $e->getMessage(), $matches); if ($matches[2][1] > 1) { $DBEBSVolume->size = $matches[2][1]; $DBEBSVolume->save(); } } $this->logger->error("Cannot create volume: {$e->getMessage()}. Database ID: {$DBEBSVolume->id}"); exit; } } else { if ($volumeinfo && $DBEBSVolume->volumeId) { if ($volumeinfo->status == AMAZON_EBS_STATE::AVAILABLE) { if (!$DBEBSVolume->serverId) { $DBEBSVolume->attachmentStatus = EC2_EBS_ATTACH_STATUS::AVAILABLE; $DBEBSVolume->save(); } else { $attach_volume = true; } } } } break; } switch ($DBEBSVolume->mountStatus) { case EC2_EBS_MOUNT_STATUS::AWAITING_ATTACHMENT: if ($DBEBSVolume->attachmentStatus == EC2_EBS_ATTACH_STATUS::ATTACHED) { $DBEBSVolume->mountStatus = EC2_EBS_MOUNT_STATUS::MOUNTING; $DBEBSVolume->save(); $DBServer = DBServer::LoadByID($DBEBSVolume->serverId); $DBServer->SendMessage(new Scalr_Messaging_Msg_MountPointsReconfigure()); } break; case EC2_EBS_MOUNT_STATUS::MOUNTING: //NOTHING TO DO break; } if ($attach_volume) { try { $DBServer = DBServer::LoadByID($DBEBSVolume->serverId); if ($DBServer->status != SERVER_STATUS::RUNNING && $DBServer->IsSupported("0.7.36")) { $DBEBSVolume->attachmentStatus = EC2_EBS_ATTACH_STATUS::ATTACHING; $DBEBSVolume->save(); $this->logger->fatal("Szr verison > 0.7.36. Status: {$DBServer->status}. VolumeID: {$DBEBSVolume->volumeId}"); return; } } catch (ServerNotFoundException $e) { if ($DBEBSVolume->volumeId) { $DBEBSVolume->attachmentStatus = EC2_EBS_ATTACH_STATUS::AVAILABLE; $DBEBSVolume->mountStatus = EC2_EBS_MOUNT_STATUS::NOT_MOUNTED; $DBEBSVolume->save(); } } if ($DBServer) { //NOT supported if ($DBServer->GetOsFamily() == 'windows') { return; } try { $attachVolumeType = new AttachVolumeType($DBEBSVolume->volumeId, $DBServer->GetProperty(EC2_SERVER_PROPERTIES::INSTANCE_ID), $DBServer->GetFreeDeviceName()); $result = $EC2Client->AttachVolume($attachVolumeType); } catch (Exception $e) { if (!stristr($e->getMessage(), "is not in the same availability zone as instance") && !stristr($e->getMessage(), "Cannot get a list of used disk devices")) { $this->logger->fatal("Cannot attach volume: {$e->getMessage()}"); } else { $this->logger->info("Cannot attach volume: {$e->getMessage()}"); } } if ($result->status == AMAZON_EBS_STATE::IN_USE || $result->status == AMAZON_EBS_STATE::ATTACHING) { $DBEBSVolume->attachmentStatus = EC2_EBS_ATTACH_STATUS::ATTACHING; $DBEBSVolume->deviceName = $attachVolumeType->device; $DBEBSVolume->save(); } else { $this->logger->warn("Cannot attach volume: volume status: {$result->status} ({$volumeinfo->status}). Database ID: {$DBEBSVolume->id}. Volume ID: {$DBEBSVolume->volumeId}"); } } } }
public function xListVolumesAction() { $aws = $this->getEnvironment()->aws($this->getParam('cloudLocation')); $this->request->defineParams(array('sort' => array('type' => 'json', 'default' => array('property' => 'volumeId', 'direction' => 'DESC')), 'volumeId')); if ($this->getParam('volumeId')) { $filter = array(array('name' => VolumeFilterNameType::volumeId(), 'value' => $this->getParam('volumeId'))); } else { $filter = null; } // Rows $volumeList = $aws->ec2->volume->describe(null, $filter); $vols = array(); /* @var $pv VolumeData */ foreach ($volumeList as $pv) { /* @var $att AttachmentSetResponseData */ if (count($pv->attachmentSet)) { $att = $pv->attachmentSet[0]; } else { $att = null; } $item = array('volumeId' => $pv->volumeId, 'size' => (int) $pv->size, 'snapshotId' => $pv->snapshotId, 'availZone' => $pv->availabilityZone, 'type' => $pv->volumeType, 'status' => $pv->status, 'attachmentStatus' => $att !== null ? $att->status : null, 'device' => $att !== null ? $att->device : null, 'instanceId' => $att !== null ? $att->instanceId : null); $item['autoSnaps'] = $this->db->GetOne("SELECT id FROM autosnap_settings WHERE objectid=? AND object_type=? LIMIT 1", array($pv->volumeId, AUTOSNAPSHOT_TYPE::EBSSnap)) ? true : false; $dbEbsVolume = false; try { $dbEbsVolume = DBEBSVolume::loadByVolumeId($pv->volumeId); $item['farmId'] = $dbEbsVolume->farmId; $item['farmRoleId'] = $dbEbsVolume->farmRoleId; $item['serverIndex'] = $dbEbsVolume->serverIndex; $item['serverId'] = $dbEbsVolume->serverId; $item['mountStatus'] = $dbEbsVolume->mountStatus; $item['farmName'] = DBFarm::LoadByID($dbEbsVolume->farmId)->Name; $item['roleName'] = DBFarmRole::LoadByID($dbEbsVolume->farmRoleId)->GetRoleObject()->name; $item['autoAttach'] = true; } catch (\Exception $e) { } if (!$dbEbsVolume && !empty($item['instanceId'])) { try { $dbServer = DBServer::LoadByPropertyValue(EC2_SERVER_PROPERTIES::INSTANCE_ID, $item['instanceId']); $item['farmId'] = $dbServer->farmId; $item['farmRoleId'] = $dbServer->farmRoleId; $item['serverIndex'] = $dbServer->index; $item['serverId'] = $dbServer->serverId; $item['farmName'] = $dbServer->GetFarmObject()->Name; $item['mountStatus'] = false; $item['roleName'] = $dbServer->GetFarmRoleObject()->GetRoleObject()->name; } catch (\Exception $e) { } } $vols[] = $item; } $response = $this->buildResponseFromData($vols, array('instanceId', 'volumeId', 'snapshotId', 'farmId', 'farmRoleId', 'availZone', 'type')); $this->response->data($response); }
public function xDetachAction() { $aws = $this->getEnvironment()->aws($this->getParam('cloudLocation')); $this->request->defineParams(array('cloudLocation', 'volumeId', 'forceDetach')); $isForce = $this->getParam('forceDetach') == 1; /* @var $att AttachmentSetResponseData */ $att = $aws->ec2->volume->detach($this->getParam('volumeId'), null, null, $isForce); if ($att->volumeId && ($att->status == AttachmentSetResponseData::STATUS_DETACHING || $att->status == AttachmentSetResponseData::STATUS_DETACHED)) { $dbEbsVolume = null; try { $dbEbsVolume = DBEBSVolume::loadByVolumeId($this->getParam('volumeId')); } catch (\Exception $e) { } if (!empty($dbEbsVolume)) { if ($dbEbsVolume->isManual) { $dbEbsVolume->delete(); } else { if (!$dbEbsVolume->isManual) { $dbEbsVolume->attachmentStatus = EC2_EBS_ATTACH_STATUS::AVAILABLE; $dbEbsVolume->mountStatus = EC2_EBS_MOUNT_STATUS::NOT_MOUNTED; $dbEbsVolume->serverId = ''; $dbEbsVolume->deviceName = ''; $dbEbsVolume->save(); } } } } $this->response->success('Volume has been successfully detached'); }