Exemplo n.º 1
0
Arquivo: Ebs.php Projeto: recipe/scalr
 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;
 }
Exemplo n.º 3
0
 /**
  * {@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}");
             }
         }
     }
 }
Exemplo n.º 4
0
 /**
  * {@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();
         }
     }
 }
Exemplo n.º 5
0
 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');
 }
Exemplo n.º 6
0
 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}");
             }
         }
     }
 }
Exemplo n.º 8
0
 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);
 }
Exemplo n.º 9
0
 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');
 }