public function testDescribeMultipleSnapshots() { $rawHttpResponse = "HTTP/1.1 200 OK\r\n" . "Date: Fri, 24 Oct 2008 17:24:52 GMT\r\n" . "Server: hi\r\n" . "Last-modified: Fri, 24 Oct 2008 17:24:52 GMT\r\n" . "Status: 200 OK\r\n" . "Content-type: application/xml; charset=utf-8\r\n" . "Expires: Tue, 31 Mar 1981 05:00:00 GMT\r\n" . "Connection: close\r\n" . "\r\n" . "<DescribeSnapshotsResponse xmlns=\"http://ec2.amazonaws.com/doc/2008-12-01/\">\r\n" . " <snapshotSet>\r\n" . " <item>\r\n" . " <snapshotId>snap-78a54011</snapshotId>\r\n" . " <volumeId>vol-4d826724</volumeId>\r\n" . " <status>pending</status>\r\n" . " <startTime>2008-05-07T12:51:50.000Z</startTime>\r\n" . " <progress>80%</progress>\r\n" . " </item>\r\n" . " <item>\r\n" . " <snapshotId>snap-78a54012</snapshotId>\r\n" . " <volumeId>vol-4d826725</volumeId>\r\n" . " <status>pending</status>\r\n" . " <startTime>2008-08-07T12:51:50.000Z</startTime>\r\n" . " <progress>65%</progress>\r\n" . " </item>\r\n" . " </snapshotSet>\r\n" . "</DescribeSnapshotsResponse>"; $this->adapter->setResponse($rawHttpResponse); $return = $this->Zend_Service_Amazon_Ec2_Ebs->describeSnapshot(array('snap-78a54011', 'snap-78a54012')); $arrSnapshots = array(array('snapshotId' => 'snap-78a54011', 'volumeId' => 'vol-4d826724', 'status' => 'pending', 'startTime' => '2008-05-07T12:51:50.000Z', 'progress' => '80%'), array('snapshotId' => 'snap-78a54012', 'volumeId' => 'vol-4d826725', 'status' => 'pending', 'startTime' => '2008-08-07T12:51:50.000Z', 'progress' => '65%')); $this->assertSame($arrSnapshots, $return); }
/** * Prunes Snapshots for the Given Volume * * @param string $volumeId * @param boolean $dryRun (Optional) Indicates if we should perform a dry run * @throws InvalidArgumentException if the volume id is not valid or $weeks is not numeric * @return App_Service_Amazon_Ec2_EbsSnapshotPruneResult */ public function prune($volumeId, $dryRun = false) { if (!$this->_volumeExists($volumeId)) { throw new InvalidArgumentException('The provided "' . $volumeId . '" volume does not exist'); } // Storage mechanism for to-be saved snapshots $save = array('month-first-day' => array(), 'sundays' => array(), 'past-week' => array(), 'only' => array()); $delete = array(); $savedAtLeastOne = false; foreach ($this->_ebs->describeSnapshot() as $s) { if (strcasecmp($s['volumeId'], $volumeId) !== 0) { continue; } $obj = new App_Service_Amazon_Ec2_EbsSnapshot($s); if ($obj->monthsElapsed() >= 1 && $obj->isFirstDayOfTheMonth() && !isset($save['month-first-day'][$obj->monthsElapsed()])) { $save['month-first-day'][$obj->monthsElapsed()] = $obj; $savedAtLeastOne = true; } else { if ($obj->weeksElapsed() > 0 && $obj->weeksElapsed() < 4 && $obj->isSunday() && !isset($save['sundays'][$obj->weeksElapsed()])) { $save['sundays'][$obj->weeksElapsed()] = $obj; $savedAtLeastOne = true; } else { if ($obj->weeksElapsed() == 0) { $save['past-week'][] = $obj; $savedAtLeastOne = true; } else { $delete[] = $obj; } } } } // Make sure we leave at least one backup // @todo: make this a config option if (!$savedAtLeastOne && !empty($delete)) { $newest['time'] = 0; $newest['obj'] = null; $newest['index'] = null; foreach ($delete as $k => $d) { /* @var $d App_Service_Amazon_Ec2_EbsSnapshot */ $data = $d->getData(); if (strtotime($data['startTime']) > $newest['time']) { $newest['obj'] = $d; $newest['index'] = $k; $newest['time'] = strtotime($data['startTime']); } } if (empty($newest['obj'])) { throw new RuntimeException('Sanity check failed. There should be at ' . 'least one backup to be saved'); } unset($delete[$newest['index']]); // rekey delete $delete = array_values($delete); } $result = new App_Service_Amazon_Ec2_EbsSnapshotPruneResult(); $result->setDeleted($delete); $result->setKept($save); if ($dryRun) { $result->setDryRun(true); return $result; } foreach ($delete as $d) { /* @var $d App_Service_Amazon_Ec2_EbsSnapshot */ $data = $d->getData(); if (!array_key_exists('snapshotId', $data)) { continue; } try { $this->_ebs->deleteSnapshot($data['snapshotId']); } catch (Zend_Service_Amazon_Ec2_Exception $e) { if (!strstr($e->getMessage(), 'is currently in use by ami')) { throw $e; } $result->addWarning($e->getMessage()); } } return $result; }