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}"); } } } }
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}"); } } } }