summaryrefslogblamecommitdiffstats
path: root/application/modules/backend/controllers/MkisoController.php
blob: b0b4fd5b2790708112cf7a89ecfc36c21c5f0447 (plain) (tree)


























































































































































































































































































                                                                                                                   
<?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!")));
    }



}