Created
July 7, 2012 23:58
-
-
Save kynx/3068629 to your computer and use it in GitHub Desktop.
Rackspace Cloud Files command line pipe program
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
#!/usr/bin/php | |
<?php | |
/** | |
* Tool for piping files to and from Rackspace Cloud Files | |
* | |
* This is useful for doing things like backup / restore mysql dumps | |
* | |
* INSTALLATION: | |
* | |
* Make sure that the Zend Framework 1.12+ library and Kynx library are in your | |
* PHP include path. If you haven't got them already: | |
* <code> | |
* cd /usr/share/php/library | |
* svn checkout http://framework.zend.com/svn/framework/standard/trunk/library/Zend | |
* git clone https://github.com/kynx/Kynx.git | |
* </code> | |
* | |
* Edit your php.ini and set your path to something sensible: | |
* <code> | |
* include_path = '.:/usr/share/php/library:/your/other/includes' | |
* </code> | |
* | |
* Then copy this file to somewhere in your path and make it executable. | |
* | |
* USAGE: | |
* | |
* Copy cloud file to STDOUT: | |
* $ cfpipe.php container/path/to/file | |
* | |
* Copy local file to cloud: | |
* $ cfpipe.php container/backup.tgz < backup.tgz | |
* | |
* Pipe program output to cloud file: | |
* $ mysqldump -a | cfpipe.php container/backup.sql | |
* | |
* Pipe file from cloud to program: | |
* $ cfpipe.php container/backup.sql | mysql | |
* | |
* Copy cloud file from one account to another: | |
* $ cfpipe.php -a key1 -u user1 container/backup.tgz | \ | |
* cfpipe.php -a key2 -u user2 container/backup.tgz | |
* | |
* ENVIRONMENT VARIABLES: | |
* | |
* Set the following environment variables and you won't have to enter them all | |
* the time: | |
* | |
* OS_USERNAME User | |
* OS_PASSWORD API Key | |
* OS_AUTH_URL Authentication URL | |
* | |
* HELP: | |
* | |
* Type cfpipe.php --help for more help and examples. | |
* | |
* @category Kynx | |
* @package Rackspace | |
* @subpackage Tools | |
* @copyright Copyright (c) 2012 Matt Kynaston (http://www.kynx.org) | |
* @license https://github.com/kynx/Kynx/blob/master/LICENSE New BSD | |
*/ | |
require_once 'Zend/Loader/Autoloader.php'; | |
$autoloader = Zend_Loader_Autoloader::getInstance(); | |
$autoloader->registerNamespace('Kynx_'); | |
$options = array( | |
'apikey|a-s' => "Cloud Files API key", | |
'debug' => "Print full stacktrace of exceptions", | |
'help|h' => "Print help", | |
'remote|r' => "Remote: don't use ServiceNet", | |
'user|u-s' => "Cloud Files user", | |
'url-s' => "Auth URL ('us', 'uk' or full URL, defaults to 'us')" | |
); | |
$getopt = new Zend_Console_Getopt($options); | |
try { | |
$getopt->parse(); | |
} | |
catch (Zend_Console_Getopt_Exception $e) { | |
fwrite(STDERR, $e->getUsageMessage()); | |
exit(1); | |
} | |
if ($getopt->help) { | |
$basename = basename(__FILE__); | |
echo $getopt->getUsageMessage(); | |
echo "\n"; | |
echo "Examples:\n\n"; | |
echo " Copy cloud file to STDOUT:\n"; | |
echo " \$ $basename container/path/to/file\n\n"; | |
echo " Copy local file to cloud:\n"; | |
echo " \$ $basename container/backup.tgz < backup.tgz\n\n"; | |
echo " Pipe program output to cloud file:\n"; | |
echo " \$ mysqldump -a | $basename container/backup.sql\n\n"; | |
echo " Pipe file from cloud to program:\n"; | |
echo " \$ $basename container/backup.sql | mysql\n\n"; | |
echo " Copy cloud file from one account to another:\n"; | |
echo " \$ $basename -a key1 -u user1 container/backup.tgz | \\\n"; | |
echo " $basename -a key2 -u user2 container/backup.tgz\n\n"; | |
echo "Environment variables:\n\n"; | |
echo " OS_USERNAME User\n"; | |
echo " OS_PASSWORD API Key\n"; | |
echo " OS_AUTH_URL Authentication URL\n"; | |
echo "\n\n"; | |
exit; | |
} | |
// check for environment variables to default to | |
// these are the same vars used by nova client | |
$user = empty($getopt->user) ? getenv('OS_USERNAME') : $getopt->user; | |
if (empty($user)) { | |
fwrite(STDERR, "Please specify a user\n"); | |
fwrite(STDERR, $getopt->getUsageMessage()); | |
exit(1); | |
} | |
$apiKey = empty($getopt->apikey) ? getenv('OS_PASSWORD') : $getopt->apikey; | |
if (empty($apiKey)) { | |
fwrite(STDERR, "Please specify an apikey\n"); | |
fwrite(STDERR, $getopt->getUsageMessage()); | |
exit(1); | |
} | |
$url = empty($getopt->url) ? getenv('OS_AUTH_URL') : $getopt->url; | |
switch ($url) { | |
case 'uk' : | |
$url = Zend_Service_Rackspace_Abstract::UK_AUTH_URL; | |
break; | |
case '' : | |
case 'us' : | |
$url = Zend_Service_Rackspace_Abstract::US_AUTH_URL; | |
break; | |
default : | |
// just use what's given | |
} | |
$args = $getopt->getRemainingArgs(); | |
$path = array_shift($args); | |
if (empty($path)) { | |
fwrite(STDERR, "Please specify cloud file.\n"); | |
fwrite(STDERR, $getopt->getUsageMessage()); | |
exit(1); | |
} | |
$cf = new Kynx_Service_Rackspace_Files($user, $apiKey); | |
$cf->setServiceNet(!$getopt->remote); | |
$md5 = exec('which openssl'); | |
if ($md5) { | |
$md5 = 'openssl md5 -r'; | |
} | |
if (!$md5) $md5 = exec('which md5sum'); | |
if ($md5) { | |
$cf->setChecksummer(new Kynx_Service_Rackspace_Files_Checksum_Proc(array('exe' => $md5))); | |
} | |
$cf->registerStreamWrapper(); | |
$path = Kynx_Service_Rackspace_Files::WRAPPER_NAME . '://' . preg_replace('|^/|', '', $path); | |
if (posix_isatty(STDIN)) { | |
$source = $cfh = fopen($path, 'r'); | |
$dest = STDOUT; | |
} | |
else { | |
$source = STDIN; | |
$dest = $cfh = fopen($path, 'w'); | |
} | |
if (!($source && $dest)) { | |
fwrite(STDERR, "Failed to open cloud file '$path'"); | |
exit(1); | |
} | |
try { | |
if (!stream_copy_to_stream($source, $dest)) { | |
fwrite(STDERR, "No bytes transfered!\n"); | |
exit(1); | |
} | |
if (!fclose($cfh)) { | |
fwrite(STDERR, "Error closing pipe. " . Zend_Http_Response::responseCodeAsText($cf->getErrorCode())); | |
exit(1); | |
} | |
} | |
catch (Exception $e) { | |
fwrite(STDERR, $e->getMessage()); | |
if ($getopt->debug) { | |
fwrite(STDERR, $e->getTraceAsString()); | |
} | |
exit(1); | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment