Copied over the /backend/tests directory and modified the paths to their new locations. Moved the liquidsoap directory to be under the pypo directory.
487 lines
15 KiB
PHP
Executable file
487 lines
15 KiB
PHP
Executable file
<?php
|
|
define('BACKUP_EXT', 'tar');
|
|
define('ACCESS_TYPE', 'backup');
|
|
|
|
/**
|
|
* @package Campcaster
|
|
* @subpackage StorageServer
|
|
* @copyright 2010 Sourcefabric O.P.S.
|
|
* @license http://www.gnu.org/licenses/gpl.txt
|
|
*/
|
|
class Backup
|
|
{
|
|
/**
|
|
* Name of logfile
|
|
* @var string
|
|
*/
|
|
private $logFile;
|
|
|
|
/**
|
|
* Session id
|
|
* @var string
|
|
*/
|
|
private $sessid;
|
|
|
|
/**
|
|
* struct - see search criteria
|
|
* @var array
|
|
*/
|
|
private $criteria;
|
|
|
|
/**
|
|
* @var string
|
|
*/
|
|
private $token;
|
|
|
|
/**
|
|
* name of statusfile
|
|
* @var string
|
|
*/
|
|
private $statusFile;
|
|
|
|
/**
|
|
* Affected gunids
|
|
* @var array
|
|
*/
|
|
private $ids;
|
|
|
|
/**
|
|
* Array of affected filenames
|
|
* @var array
|
|
*/
|
|
private $filenames = array();
|
|
|
|
/**
|
|
* Base tmp name
|
|
* @var string
|
|
*/
|
|
private $tmpName;
|
|
|
|
/**
|
|
* Name of temporary tarball file
|
|
* @var string
|
|
*/
|
|
private $tmpFile;
|
|
|
|
/**
|
|
* Name of temporary directory
|
|
* @var string
|
|
*/
|
|
private $tmpDir;
|
|
|
|
/**
|
|
* Name of temporary playlist directory
|
|
* @var string
|
|
*/
|
|
private $tmpDirPlaylist;
|
|
|
|
/**
|
|
* Name of temporary audioclip directory
|
|
* @var string
|
|
*/
|
|
private $tmpDirClip;
|
|
|
|
/**
|
|
* Name of temporary metafile directory
|
|
* @var string
|
|
*/
|
|
private $tmpDirMeta;
|
|
|
|
/**
|
|
* @var string
|
|
*/
|
|
private $loglevel = 'warn'; # 'debug';
|
|
|
|
/**
|
|
* @var GreenBox
|
|
*/
|
|
private $gb;
|
|
|
|
/**
|
|
* @param GreeenBox $gb
|
|
*/
|
|
public function __construct(&$gb)
|
|
{
|
|
global $CC_CONFIG;
|
|
$this->gb =& $gb;
|
|
$this->token = null;
|
|
$this->logFile = $CC_CONFIG['bufferDir'].'/'.ACCESS_TYPE.'.log';
|
|
$this->addLogItem("-I- ".date("Ymd-H:i:s")." construct\n");
|
|
}
|
|
|
|
|
|
/**
|
|
* Open a backup
|
|
* Create a backup file (tarball)
|
|
*
|
|
* @param string $sessid
|
|
* @param array $criteria
|
|
* struct - see search criteria
|
|
* @return array
|
|
* hasharray with field:
|
|
* token string: backup token
|
|
*/
|
|
public function openBackup($sessid, $criteria='')
|
|
{
|
|
if ($this->loglevel=='debug') {
|
|
$this->addLogItem("-I- ".date("Ymd-H:i:s")." openBackup - sessid:$sessid\n");
|
|
}
|
|
$this->sessid = $sessid;
|
|
$this->criteria = $criteria;
|
|
|
|
// get ids (and real filenames) which files match with criteria
|
|
$srch = $this->gb->localSearch($this->criteria,$this->sessid);
|
|
if (PEAR::isError($srch)) {
|
|
return $srch;
|
|
}
|
|
$this->setIDs($srch);
|
|
|
|
// get real filenames
|
|
if (is_array($this->ids)) {
|
|
$this->setFilenames();
|
|
|
|
$this->setEnviroment(true);
|
|
|
|
// write a status file
|
|
file_put_contents($this->statusFile, 'working');
|
|
|
|
// save the metafile to tmpdir
|
|
$hostname = trim(`hostname`);
|
|
$ctime = time();
|
|
$ctime_f = date("Ymd-H:i:s");
|
|
file_put_contents("{$this->tmpDirMeta}/storage.xml",
|
|
"<?xml version=\"1.0\" encoding=\"utf-8\" ?>\n".
|
|
"<storage\n".
|
|
" type=\"".ACCESS_TYPE."\"\n".
|
|
" version=\"1.0\"\n".
|
|
" ctime=\"$ctime\"\n".
|
|
" hostname=\"$hostname\"\n".
|
|
"/><!-- $ctime_f -->\n"
|
|
);
|
|
|
|
// copy all file to tmpdir
|
|
$this->copyAllFiles();
|
|
|
|
// do everything
|
|
$this->doIt();
|
|
|
|
return array('token'=>$this->token);
|
|
} else {
|
|
return false;
|
|
}
|
|
}
|
|
|
|
|
|
/**
|
|
* Check the status of backup.
|
|
*
|
|
* @param unknown $token
|
|
* @return array
|
|
* status : string - susccess | working | fault
|
|
* faultString: string - description of fault
|
|
* token : stirng - backup token
|
|
* url : string - access url
|
|
* tmpfile : string - access filename
|
|
*/
|
|
public function checkBackup($token)
|
|
{
|
|
global $CC_CONFIG;
|
|
if ($this->loglevel=='debug') {
|
|
$this->addLogItem("-I- ".date("Ymd-H:i:s")." checkBackup - token:$token\n");
|
|
}
|
|
$this->token = $token;
|
|
$this->setEnviroment();
|
|
$status = file_get_contents($this->statusFile);
|
|
if (strpos($status,'fault')!==false) {
|
|
list($status,$faultString) = explode('|',$status);
|
|
}
|
|
switch ($status) {
|
|
case 'success':
|
|
$r['url'] = BasicStor::GetUrlPart()."access/$token.".BACKUP_EXT;
|
|
$r['tmpfile'] = $CC_CONFIG['accessDir']."/$token.".BACKUP_EXT;
|
|
case 'working':
|
|
case 'fault':
|
|
$r['status'] = $status;
|
|
$r['faultString'] = $faultString;
|
|
$r['token'] = $token;
|
|
break;
|
|
}
|
|
return $r;
|
|
}
|
|
|
|
|
|
/**
|
|
* Close a backup
|
|
*
|
|
* @param unknown $token
|
|
* @return boolean
|
|
*/
|
|
public function closeBackup($token)
|
|
{
|
|
if ($this->loglevel=='debug') {
|
|
$this->addLogItem("-I- ".date("Ymd-H:i:s")." closeBackup - token:$token\n");
|
|
}
|
|
# post procedures
|
|
$this->token = $token;
|
|
$this->setEnviroment();
|
|
BasicStor::bsRelease($token, ACCESS_TYPE);
|
|
Backup::rRmDir($this->tmpDir);
|
|
unlink($this->statusFile);
|
|
unlink($this->tmpFile);
|
|
if (is_file($this->tmpName)) {
|
|
unlink($this->tmpName);
|
|
}
|
|
return !is_file($this->tmpFile);
|
|
}
|
|
|
|
|
|
/**
|
|
* list of unclosed backups
|
|
*
|
|
* @param string $stat
|
|
* if this parameter is not set, then return with all unclosed backups
|
|
* @return array of hasharray with field:
|
|
* status : string - susccess | working | fault
|
|
* token : stirng - backup token
|
|
* url : string - access url
|
|
*/
|
|
public function listBackups($stat='')
|
|
{
|
|
if ($this->loglevel=='debug') {
|
|
$this->addLogItem("-I- ".date("Ymd-H:i:s")." listBackups - stat:$stat\n");
|
|
}
|
|
// open temporary dir
|
|
$tokens = BasicStor::GetTokensByType(ACCESS_TYPE);
|
|
// echo '<XMP>tokens:'; print_r($tokens); echo '</XMP>';
|
|
foreach ($tokens as $token) {
|
|
$st = $this->checkBackup($token);
|
|
if ($stat=='' || $st['status']==$stat) {
|
|
$r[] = $st;
|
|
}
|
|
}
|
|
return $r;
|
|
}
|
|
|
|
|
|
/**
|
|
* Set the ids from searchResult
|
|
*
|
|
* @param array $searchResult : array of gunids
|
|
*/
|
|
private function setIDs($searchResult)
|
|
{
|
|
if ($this->loglevel=='debug') {
|
|
$this->addLogItem("-I- ".date("Ymd-H:i:s")." setIDs\n");
|
|
}
|
|
if (is_array($searchResult['results'])) {
|
|
$this->ids = $searchResult['results'];
|
|
} else {
|
|
$this->addLogItem("-E- ".date("Ymd-H:i:s")." setIDs - the parameter is not array!\n");
|
|
return PEAR::raiseError('The IDs variable isn\'t array.');
|
|
}
|
|
}
|
|
|
|
|
|
/**
|
|
* Set the filenames from ids.
|
|
*
|
|
*/
|
|
private function setFilenames()
|
|
{
|
|
// if ($this->loglevel=='debug') {
|
|
// $this->addLogItem("-I- ".date("Ymd-H:i:s")." setFilenames\n");
|
|
// }
|
|
// if (is_array($this->ids)) {
|
|
// foreach ($this->ids as $i => $item) {
|
|
// $gunid = $item['gunid'];
|
|
// // get a stored file object of this gunid
|
|
// $sf = StoredFile::RecallByGunid($gunid);
|
|
// if (is_null($sf) || PEAR::isError($sf)) {
|
|
// return $sf;
|
|
// }
|
|
// $lid = BasicStor::IdFromGunid($gunid);
|
|
// if (($res = BasicStor::Authorize('read', $lid, $this->sessid)) !== TRUE) {
|
|
// $this->addLogItem("-E- ".date("Ymd-H:i:s")." setFilenames - authorize gunid:$gunid\n");
|
|
// return PEAR::raiseError('Backup::setFilenames : Authorize ... error.');
|
|
// }
|
|
// // if the file is a playlist then it has only a meta file
|
|
// if (strtolower($sf->md->format) != 'playlist') {
|
|
// $this->filenames[] = array(
|
|
// 'filename' => $sf->getRealFileName(),
|
|
// 'format' => $sf->md->format
|
|
// );
|
|
// }
|
|
// $this->filenames[] = array(
|
|
// 'filename' => $sf->getRealMetadataFileName(),
|
|
// 'format' => $sf->md->format
|
|
// );
|
|
// if ($this->loglevel=='debug') {
|
|
// $this->addLogItem("-I- ".date("Ymd-H:i:s")." setFilenames - add file: {$sf->md->format}|".$sf->getRealMetadataFileName()."\n");
|
|
// }
|
|
// }
|
|
// return $this->filenames;
|
|
// } else {
|
|
// $this->addLogItem("-E- ".date("Ymd-H:i:s")." setFilenames - The IDs variable isn't array.\n");
|
|
// return PEAR::raiseError('Backup::setFilenames : The IDs variable isn\'t array.');
|
|
// }
|
|
}
|
|
|
|
|
|
/**
|
|
* Create the tarball - call the shell script
|
|
*
|
|
*/
|
|
private function doIt()
|
|
{
|
|
if ($this->loglevel=='debug') {
|
|
$this->addLogItem("-I- ".date("Ymd-H:i:s")." doIt\n");
|
|
}
|
|
$command = dirname(__FILe__)."/../bin/backup.sh"
|
|
." {$this->tmpDir}"
|
|
." {$this->tmpFile}"
|
|
." {$this->statusFile}"
|
|
." >> {$this->logFile} &";
|
|
$res = system("$command");
|
|
sleep(2);
|
|
if ($this->loglevel=='debug') {
|
|
$this->addLogItem("-I- ".date("Ymd-H:i:s")." doIt - command:$command\n");
|
|
}
|
|
}
|
|
|
|
|
|
/**
|
|
* Copy the real files into the tmp dirs to tar they.
|
|
*
|
|
*/
|
|
private function copyAllFiles()
|
|
{
|
|
if ($this->loglevel=='debug') {
|
|
$this->addLogItem("-I- ".date("Ymd-H:i:s")." copyAllFiles\n");
|
|
}
|
|
//echo '<XMP>this->filenames:'; print_r($this->filenames); echo '</XMP>';
|
|
if (is_array($this->filenames)) {
|
|
foreach ($this->filenames as $v) {
|
|
# get the filename from full path
|
|
$fn = substr($v['filename'],strrpos($v['filename'],'/'));
|
|
switch (strtolower($v['format'])) {
|
|
case 'playlist':
|
|
# if playlist then copy to the playlist dir
|
|
copy($v['filename'],$this->tmpDirPlaylist.$fn);
|
|
break;
|
|
case 'audioclip':
|
|
# if audioclip then copy to the audioclip dir
|
|
copy($v['filename'],$this->tmpDirClip.$fn);
|
|
break;
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
|
|
/**
|
|
* Figure out the enviroment to the backup
|
|
*
|
|
*/
|
|
private function setEnviroment($createDir=false)
|
|
{
|
|
global $CC_CONFIG;
|
|
if ($this->loglevel=='debug') {
|
|
$this->addLogItem("-I- ".date("Ymd-H:i:s")." setEnviroment - createDirs:$createDir\n");
|
|
}
|
|
// create temporary directories
|
|
if (is_null($this->token) && $createDir) {
|
|
$this->tmpName = tempnam($CC_CONFIG['bufferDir'], ACCESS_TYPE.'_');
|
|
$this->tmpFile = $this->tmpName.'.'.BACKUP_EXT;
|
|
$this->tmpDir = $this->tmpName.'.dir';
|
|
$this->tmpDirPlaylist = $this->tmpDir. '/playlist';
|
|
$this->tmpDirClip = $this->tmpDir. '/audioClip';
|
|
$this->tmpDirMeta = $this->tmpDir. '/meta-inf';
|
|
touch($this->tmpFile);
|
|
mkdir($this->tmpDir);
|
|
mkdir($this->tmpDirPlaylist);
|
|
mkdir($this->tmpDirClip);
|
|
mkdir($this->tmpDirMeta);
|
|
$this->genToken();
|
|
} else {
|
|
$symlink = $CC_CONFIG['accessDir'].'/'.$this->token.'.'.BACKUP_EXT;
|
|
if (is_link($symlink) && is_file(readlink($symlink))) {
|
|
$this->tmpName = str_replace('.tar','',readlink($symlink));
|
|
$this->tmpFile = $this->tmpName.'.'.BACKUP_EXT;
|
|
$this->tmpDir = $this->tmpName.'.dir';
|
|
$this->tmpDirPlaylist = $this->tmpDir. '/playlist';
|
|
$this->tmpDirClip = $this->tmpDir. '/audioClip';
|
|
$this->tmpDirMeta = $this->tmpDir. '/meta-inf';
|
|
} else {
|
|
$this->addLogItem("-E- ".date("Ymd-H:i:s")." setEnviroment - Corrupt symbolic link.\n");
|
|
return false;
|
|
}
|
|
}
|
|
$this->statusFile = $CC_CONFIG['accessDir'].'/'.$this->token.'.'.BACKUP_EXT.'.status';
|
|
if ($this->loglevel=='debug') {
|
|
$this->addLogItem("this->tmpName: $this->tmpName\n");
|
|
$this->addLogItem("this->tmpFile: $this->tmpFile\n");
|
|
$this->addLogItem("this->tmpDir: $this->tmpDir\n");
|
|
$this->addLogItem("this->tmpDirPlaylist: $this->tmpDirPlaylist\n");
|
|
$this->addLogItem("this->tmpDirClip: $this->tmpDirClip\n");
|
|
$this->addLogItem("this->tmpDirMeta: $this->tmpDirMeta\n");
|
|
$this->addLogItem("this->token: $this->token\n");
|
|
$this->addLogItem("this->statusFile: $this->statusFile\n");
|
|
}
|
|
}
|
|
|
|
|
|
/**
|
|
* Generate a new token.
|
|
* @return void
|
|
*/
|
|
private function genToken()
|
|
{
|
|
$acc = BasicStor::bsAccess($this->tmpFile, BACKUP_EXT, null, ACCESS_TYPE);
|
|
if (PEAR::isError($acc)) {
|
|
return $acc;
|
|
}
|
|
$this->token = $acc['token'];
|
|
}
|
|
|
|
|
|
/**
|
|
* Add a line to the logfile.
|
|
*
|
|
* @param string $item
|
|
* the new row of log file
|
|
*/
|
|
private function addLogItem($item)
|
|
{
|
|
$f = fopen($this->logFile,'a');
|
|
fwrite($f,$item);
|
|
fclose($f);
|
|
}
|
|
|
|
|
|
/**
|
|
* Delete a directory recursive
|
|
*
|
|
* @param string $dirname
|
|
* path of dir.
|
|
*/
|
|
private static function rRmDir($dirname)
|
|
{
|
|
if (is_dir($dirname)) {
|
|
$dir_handle = opendir($dirname);
|
|
}
|
|
while ($file = readdir($dir_handle)) {
|
|
if ( ($file != ".") && ($file != "..") ) {
|
|
if (!is_dir($dirname."/".$file)) {
|
|
unlink ($dirname."/".$file);
|
|
} else {
|
|
Backup::rRmDir($dirname."/".$file);
|
|
}
|
|
}
|
|
}
|
|
closedir($dir_handle);
|
|
rmdir($dirname);
|
|
return true;
|
|
}
|
|
|
|
} // classs Backup
|
|
?>
|