Skip to content

Instantly share code, notes, and snippets.

@kynx
Created July 7, 2012 23:58
Show Gist options
  • Save kynx/3068629 to your computer and use it in GitHub Desktop.
Save kynx/3068629 to your computer and use it in GitHub Desktop.
Rackspace Cloud Files command line pipe program
#!/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