/** * Loads BlockDeviceMappingList from simple xml object * * @param \SimpleXMLElement $sxml * @return BlockDeviceMappingList Returns BlockDeviceMappingList */ protected function _loadBlockDeviceMappingList(\SimpleXMLElement $sxml) { $list = new BlockDeviceMappingList(); $list->setEc2($this->ec2); if (!empty($sxml->item)) { foreach ($sxml->item as $v) { $item = new BlockDeviceMappingData(); $item->setEc2($this->ec2); $item->deviceName = $this->exist($v->deviceName) ? (string) $v->deviceName : null; $item->virtualName = $this->exist($v->virtualName) ? (string) $v->virtualName : null; $item->noDevice = $this->exist($v->noDevice) ? (string) $v->noDevice : null; $item->setEbs($this->_loadEbsBlockDeviceData($v->ebs)); $list->append($item); unset($item); } } return $list; }
/** * {@inheritdoc} * @see \Scalr\Modules\PlatformModuleInterface::CreateServerSnapshot() */ public function CreateServerSnapshot(BundleTask $BundleTask) { $DBServer = DBServer::LoadByID($BundleTask->serverId); $aws = $DBServer->GetEnvironmentObject()->aws($DBServer); if (!$BundleTask->prototypeRoleId) { //FIXME $proto_image_id is never used $proto_image_id = $DBServer->GetProperty(EC2_SERVER_PROPERTIES::AMIID); } else { $protoRole = DBRole::loadById($BundleTask->prototypeRoleId); $image = $protoRole->__getNewRoleObject()->getImage(SERVER_PLATFORMS::EC2, $DBServer->GetProperty(EC2_SERVER_PROPERTIES::REGION)); $proto_image_id = $image->imageId; //Bundle EC2 in AWS way $BundleTask->designateType(\SERVER_PLATFORMS::EC2, $image->getImage()->getOs()->family, $image->getImage()->getOs()->generation); } $callEc2CreateImage = false; $reservationSet = $aws->ec2->instance->describe($DBServer->GetCloudServerID())->get(0); $ec2Server = $reservationSet->instancesSet->get(0); if ($ec2Server->platform == 'windows') { if ($ec2Server->rootDeviceType != 'ebs') { $BundleTask->SnapshotCreationFailed("Only EBS root filesystem supported for Windows servers."); return; } if ($BundleTask->status == SERVER_SNAPSHOT_CREATION_STATUS::PENDING) { $BundleTask->bundleType = SERVER_SNAPSHOT_CREATION_TYPE::EC2_EBS_HVM; $BundleTask->Log(sprintf(_("Selected platform snapshotting type: %s"), $BundleTask->bundleType)); $BundleTask->status = SERVER_SNAPSHOT_CREATION_STATUS::PREPARING; $msg = $DBServer->SendMessage(new \Scalr_Messaging_Msg_Win_PrepareBundle($BundleTask->id)); $BundleTask->Log(sprintf(_("PrepareBundle message sent. MessageID: %s. Bundle task status changed to: %s"), $msg->messageId, $BundleTask->status)); $BundleTask->Save(); } elseif ($BundleTask->status == SERVER_SNAPSHOT_CREATION_STATUS::PREPARING) { $callEc2CreateImage = true; } } else { if ($image) { $BundleTask->Log(sprintf(_("Image OS: %s %s"), $image->getImage()->getOs()->family, $image->getImage()->getOs()->generation)); } $BundleTask->status = SERVER_SNAPSHOT_CREATION_STATUS::IN_PROGRESS; if (!$BundleTask->bundleType) { if ($ec2Server->rootDeviceType == 'ebs') { if ($ec2Server->virtualizationType == 'hvm') { $BundleTask->bundleType = SERVER_SNAPSHOT_CREATION_TYPE::EC2_EBS_HVM; } else { $BundleTask->bundleType = SERVER_SNAPSHOT_CREATION_TYPE::EC2_EBS; } } else { $BundleTask->bundleType = SERVER_SNAPSHOT_CREATION_TYPE::EC2_S3I; } $BundleTask->Log(sprintf(_("Selected platform snapshotting type: %s"), $BundleTask->bundleType)); } $BundleTask->Save(); if ($BundleTask->bundleType == SERVER_SNAPSHOT_CREATION_TYPE::EC2_EBS_HVM) { $callEc2CreateImage = true; } else { $msg = new \Scalr_Messaging_Msg_Rebundle($BundleTask->id, $BundleTask->roleName, array()); $metaData = $BundleTask->getSnapshotDetails(); if ($DBServer->IsSupported('2.11.4')) { $msg->rootVolumeTemplate = $metaData['rootBlockDeviceProperties']; } else { if ($metaData['rootBlockDeviceProperties']) { $msg->volumeSize = $metaData['rootBlockDeviceProperties']['size']; } } $DBServer->SendMessage($msg); $BundleTask->Log(sprintf(_("Snapshot creation started (MessageID: %s). Bundle task status changed to: %s"), $msg->messageId, $BundleTask->status)); } } if ($callEc2CreateImage) { try { $metaData = $BundleTask->getSnapshotDetails(); $ebs = new EbsBlockDeviceData(); $bSetEbs = false; if ($metaData['rootBlockDeviceProperties']) { if ($metaData['rootBlockDeviceProperties']['size']) { $ebs->volumeSize = $metaData['rootBlockDeviceProperties']['size']; $bSetEbs = true; } if ($metaData['rootBlockDeviceProperties']['volume_type']) { $ebs->volumeType = $metaData['rootBlockDeviceProperties']['volume_type']; $bSetEbs = true; } if ($metaData['rootBlockDeviceProperties']['iops']) { $ebs->iops = $metaData['rootBlockDeviceProperties']['iops']; $bSetEbs = true; } } $blockDeviceMapping = new BlockDeviceMappingList(); if ($bSetEbs) { $blockDeviceMapping->append(new BlockDeviceMappingData($ec2Server->rootDeviceName, null, null, $ebs)); } //TODO: Remove all attached devices other than root device from blockDeviceMapping $currentMapping = $ec2Server->blockDeviceMapping; $BundleTask->Log(sprintf(_("Server block device mapping: %s"), json_encode($currentMapping->toArray()))); foreach ($currentMapping as $blockDeviceMappingData) { /* @var $blockDeviceMappingData \Scalr\Service\Aws\Ec2\DataType\InstanceBlockDeviceMappingResponseData */ if ($blockDeviceMappingData->deviceName != $ec2Server->rootDeviceName) { $blockDeviceMapping->append(['deviceName' => $blockDeviceMappingData->deviceName, 'noDevice' => '']); } else { if (!$bSetEbs) { $ebsInfo = $aws->ec2->volume->describe($blockDeviceMappingData->ebs->volumeId)->get(0); $ebs->volumeSize = $ebsInfo->size; $ebs->deleteOnTermination = true; $ebs->volumeType = $ebsInfo->volumeType; $ebs->encrypted = $ebsInfo->encrypted; if ($ebsInfo->volumeType == 'io1') { $ebs->iops = $ebsInfo->iops; } $blockDeviceMapping->append(new BlockDeviceMappingData($ec2Server->rootDeviceName, null, null, $ebs)); } } } if ($blockDeviceMapping->count() == 0) { $blockDeviceMapping = null; } else { /* $BundleTask->Log(sprintf( _("New block device mapping: %s"), json_encode($blockDeviceMapping->toArray()) )); */ } $request = new CreateImageRequestData($DBServer->GetProperty(EC2_SERVER_PROPERTIES::INSTANCE_ID), $BundleTask->roleName . "-" . date("YmdHi"), $blockDeviceMapping); $request->description = $BundleTask->roleName; $request->noReboot = false; $imageId = $aws->ec2->image->create($request); $BundleTask->status = SERVER_SNAPSHOT_CREATION_STATUS::IN_PROGRESS; $BundleTask->snapshotId = $imageId; $BundleTask->Log(sprintf(_("Snapshot creating initialized (AMIID: %s). Bundle task status changed to: %s"), $BundleTask->snapshotId, $BundleTask->status)); $BundleTask->Save(); } catch (Exception $e) { $BundleTask->SnapshotCreationFailed($e->getMessage() . "(" . json_encode($request) . ")"); return; } } $BundleTask->setDate('started'); $BundleTask->Save(); }