<?php
class Backend_MkisoController extends Zend_Controller_Action
{
private $_mkernel;
private $_msources;
private $_mbootmedia;
private $_logger;
private function smartCopy($source, $dest, $folderPermission=0755,$filePermission=0644){
$result=false;
if (is_file($source)) { # $source is file
if(is_dir($dest)) { # $dest is folder
if ($dest[strlen($dest)-1]!='/') # add '/' if necessary
$__dest=$dest."/";
$__dest .= basename($source);
}
else { # $dest is (new) filename
$__dest=$dest;
}
$result=copy($source, $__dest);
chmod($__dest,$filePermission);
}
elseif(is_dir($source)) { # $source is dir
if(!is_dir($dest)) { # dest-dir not there yet, create it
@mkdir($dest,$folderPermission);
chmod($dest,$folderPermission);
}
if ($source[strlen($source)-1]!='/') # add '/' if necessary
$source=$source."/";
if ($dest[strlen($dest)-1]!='/') # add '/' if necessary
$dest=$dest."/";
# find all elements in $source
$result = true; # in case this dir is empty it would otherwise return false
$dirHandle=opendir($source);
while($file=readdir($dirHandle)) { # note that $file can also be a folder
if($file!="." && $file!="..") { # filter starting elements and pass the rest to this function again
# echo "$source$file ||| $dest$file<br />\n";
$result=smartCopy($source.$file, $dest.$file, $folderPermission, $filePermission);
}
}
closedir($dirHandle);
}
else {
$result=false;
}
return $result;
}
public function init()
{
$this->_helper->layout->disableLayout();
$this->_helper->viewRenderer->setNoRender();
$this->_mkernels = new Model_Kernels();
$this->_msources = new Model_Sources();
$this->_mbootmedia = new Model_Bootmedia();
$this->_logger = new Zend_Log();
$w = new Zend_Log_Writer_Stream(APPLICATION_PATH . '/../data/debug.log');
$this->_logger->addWriter($w);
}
private function delTree($dir) {
$files = glob( $dir . '*', GLOB_MARK );
foreach( $files as $file ){
if( substr( $file, -1 ) == '/' )
$this->delTree( $file );
else
unlink( $file );
}
if (is_dir($dir)) rmdir( $dir );
}
public function indexAction()
{
}
public function prepareAction() {
$l = $this->_logger;
$kernel = $this->getRequest()->getParam('kernel');
$name = $this->getRequest()->getParam('name');
$description = $this->getRequest()->getParam('description');
$identifier = dechex(mktime());
$tmppath = APPLICATION_PATH . "/../data/tmp";
$cdpath = $tmppath . "/cd";
$isoDir = "$cdpath/iso/isolinux";
$syslinuxpath = APPLICATION_PATH . "/../data/syslinux";
if (!is_dir($isoDir))
mkdir($isoDir, 0777, true);
$files = array('LICENSE', 'README.iso', 'vesamenu.c32', 'isolinux.bin');
foreach ($files as $f) copy ($syslinuxpath . "/$f", $isoDir . "/$f");
$l->info("copy syslinux files to tmp");
if ($kernel != "auto") {
$s = $this->_mkernels->select();
$s->where("kernel = ?", $kernel);
$r = $this->_mkernels->fetchAll($s)->toArray();
}
#TODO: fetch newest kernel or let user select kernel
if ($kernel == "auto" || empty($r)){
#TODO: build in some ordering to get the newest kernel..
#$s = $this->_mkernels->select();
$r = $this->_mkernels->fetchAll()->toArray();
}
$r = $r[0];
$kernel = $r['kernel'];
$kernelpath = APPLICATION_PATH . "/../data/kernels/$kernel";
$files = array('vmlinuz', 'initramfs');
foreach ($files as $f) copy ($kernelpath . "/$f", $isoDir . "/$f");
$l->info("copy kernel/initramfs to tmp");
$isolinuxConfig = "DEFAULT vesamenu.c32\n";
$isolinuxConfig .= "PROMPT 0\n";
$isolinuxConfig .= "TIMEOUT 100\n";
$isolinuxConfig .= file_get_contents($syslinuxpath . "/themes/openslx/theme.conf");
copy($syslinuxpath . "/themes/openslx/openslx.png", $isoDir . "/openslx.png");
$isolinuxConfig .= '
MENU TITLE Welcome to OpenSLX PreBoot ISO/CD (Mini Linux/Kexec)
LABEL SLXSTDBOOT
MENU LABEL OpenSLX PreBoot - Stateless Netboot Linux ...
MENU DEFAULT
KERNEL vmlinuz
APPEND initrd=initramfs vga=0x317 pbsId='.$identifier.'
TEXT HELP
Use this (default) entry if you have configured your client.
You have chance to edit the kernel commandline by hitting
the TAB key (e.g. for adding debug=3 to it for bug hunting).
ENDTEXT
LABEL LOCALBOOT
MENU LABEL Boot locally (skip OpenSLX PreBoot) ...
LOCALBOOT -1
TEXT HELP
Gets you out of here by booting from next device in BIOS
boot order.
ENDTEXT';
file_put_contents($isoDir . "/isolinux.cfg", $isolinuxConfig);
$return = array(
"kernel" => $kernel,
"name" => $name,
"description" => $description,
"identifier" => $identifier,
"progress" => "30",
"progressmsg" => "creating iso",
"error" => false,
"errormsg" => ""
);
echo(json_encode($return));
}
public function createisoAction() {
$l = $this->_logger;
$kernel = $this->getRequest()->getParam('kernel');
$name = $this->getRequest()->getParam('name');
$description = $this->getRequest()->getParam('description');
$identifier = $this->getRequest()->getParam('identifier');
$tmppath = APPLICATION_PATH . "/../data/tmp";
$cdpath = $tmppath . "/cd";
$mkisofsCmd = 'mkisofs \
-o %s \
-b isolinux/isolinux.bin -no-emul-boot -boot-load-size 4 \
-r -J -l -boot-info-table -joliet-long \
-publisher "OpenSLX Project - http://www.openslx.org" \
-p "OpenSLX Project - openslx-devel@openslx.org" \
-V "OpenSLX BootISO" \
-volset "OpenSLX Project - PreBoot ISO/CD for non PXE/TFTP start of a Linux Stateless Client" \
-c isolinux/boot.cat "%s/iso"';
$outDir = APPLICATION_PATH . "/../public/isos/$identifier";
if (!is_dir($outDir))
mkdir($outDir, 0777, true);
$iso = $outDir . "/openslx.iso";
$isolog = $outDir . "/openslx.iso.log";
$mkisofsCmd = sprintf ($mkisofsCmd, $iso, $cdpath);
$output = array();
$returnval = null;
exec($mkisofsCmd, $output, $returnval);
$l->info(print_r($output,true));
$return = array(
"kernel" => $kernel,
"name" => $name,
"description" => $description,
"identifier" => $identifier,
"progress" => "60",
"progressmsg" => "cleaning up",
"error" => false,
"errormsg" => ""
);
echo(json_encode($return));
}
public function cleanupAction() {
$l = $this->_logger;
$kernel = $this->getRequest()->getParam('kernel');
$name = $this->getRequest()->getParam('name');
$description = $this->getRequest()->getParam('description');
$identifier = $this->getRequest()->getParam('identifier');
$tmppath = APPLICATION_PATH . "/../data/tmp";
$cdpath = $tmppath . "/cd";
$this->delTree($cdpath);
$return = array(
"kernel" => $kernel,
"name" => $name,
"description" => $description,
"identifier" => $identifier,
"progress" => "80",
"progressmsg" => "update DB",
"error" => false,
"errormsg" => ""
);
echo(json_encode($return));
}
public function dbAction() {
$kernel = $this->getRequest()->getParam('kernel');
$name = $this->getRequest()->getParam('name');
$description = $this->getRequest()->getParam('description');
$identifier = $this->getRequest()->getParam('identifier');
$db_data = array(
kernel => $kernel,
name => $name,
identifier => $identifier,
description => $description,
theme => "openslx",
created => mktime(),
mediatype => "cd"
);
$this->_mbootmedia->insert($db_data);
$return = array(
"kernel" => $kernel,
"name" => $name,
"description" => $description,
"identifier" => $identifier,
"progress" => "80",
"progressmsg" => "update DB",
"error" => false,
"errormsg" => ""
);
echo(json_encode(array("progress" => "100", "progressmsg" => "FINISHED!")));
}
}