197 lines
		
	
	
		
			5.6 KiB
		
	
	
	
		
			PHP
		
	
	
	
			
		
		
	
	
			197 lines
		
	
	
		
			5.6 KiB
		
	
	
	
		
			PHP
		
	
	
	
| <?php
 | |
| 
 | |
| /* 
 | |
|  ----------------------------------------------------------------------
 | |
|  AlternC - Web Hosting System
 | |
|  Copyright (C) 2000-2013 by the AlternC Development Team.
 | |
|  https://alternc.org/
 | |
|  ----------------------------------------------------------------------
 | |
|  LICENSE
 | |
| 
 | |
|  This program is free software; you can redistribute it and/or
 | |
|  modify it under the terms of the GNU General Public License (GPL)
 | |
|  as published by the Free Software Foundation; either version 2
 | |
|  of the License, or (at your option) any later version.
 | |
| 
 | |
|  This program is distributed in the hope that it will be useful,
 | |
|  but WITHOUT ANY WARRANTY; without even the implied warranty of
 | |
|  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 | |
|  GNU General Public License for more details.
 | |
| 
 | |
|  To read the license please visit http://www.gnu.org/copyleft/gpl.html
 | |
|  ----------------------------------------------------------------------
 | |
|  Purpose of file: Manage LXC-based virtual machine through an inetd-based protocol
 | |
|  ----------------------------------------------------------------------
 | |
| */
 | |
| 
 | |
| include_once(dirname(__FILE__) . '/vm.class.php');
 | |
| 
 | |
| 
 | |
| /**
 | |
|  * Manage AlternC's virtual machine start/stop using our own inetd-based protocol.
 | |
|  */
 | |
| class m_lxc implements vm {
 | |
| 
 | |
| 
 | |
|   public $IP;
 | |
|   public $PORT;
 | |
|   public $TIMEOUT = 5;
 | |
|   public $error = array();
 | |
| 
 | |
| 
 | |
|   /** 
 | |
|    * Constructor, initialize the class informations from AlternC's variables
 | |
|    */
 | |
|   function m_lxc() {
 | |
|     $this->IP   = variable_get('lxc_ip', '', "IP address of the Alternc's LXC server. If empty, no LXC server.", array(array('desc'=>'IP address','type'=>'ip')));
 | |
|     $this->PORT = variable_get('lxc_port', '6504', "Port of the Alternc's LXC server", array(array('desc'=>'Port','type'=>'integer')));
 | |
|     $this->KEY  = variable_get('lxc_key', '', "Shared key with the Alternc's LXC server", array(array('desc'=>'Shared key','type'=>'string')));
 | |
|     $this->maxtime = variable_get('lxc_maxtime', '4', "How many hours do we allow to have a server before shutting it down", array(array('desc'=>'Max time','type'=>'integer')));
 | |
|   }
 | |
| 
 | |
| 
 | |
|   /**
 | |
|    * HOOK: add the "Console Access" to AlternC's main menu
 | |
|    */
 | |
|   function hook_menu() {
 | |
|     if ( empty($this->IP)) return ; // No menu if no server
 | |
| 
 | |
|     $obj = array(
 | |
|       'title'       => _("Console access"),
 | |
|       'ico'         => 'images/ssh.png',
 | |
|       'link'        => 'vm.php',
 | |
|       'pos'         => 95,
 | |
|      ) ;
 | |
| 
 | |
|      return $obj;
 | |
|   }
 | |
| 
 | |
| 
 | |
|   /**
 | |
|    * HOOK: remove VM history for AlternC account
 | |
|    */
 | |
|   function hook_admin_del_member() {
 | |
|     global $db,$err,$cuid;
 | |
|     $err->log("lxc","alternc_del_member");
 | |
|     $db->query("DELETE FROM vm_history WHERE uid='$cuid'");
 | |
|     return true;
 | |
|   }
 | |
| 
 | |
| 
 | |
|   /** 
 | |
|    * Send a message to a remote VM manager instance
 | |
|    * $params are the parameters to send as serialized data
 | |
|    * to the listening server. 
 | |
|    * Return the unserialized response data, if the message has been sent successfully
 | |
|    * or FALSE if an error occurred. In that case $error[] is set.
 | |
|    */
 | |
|   private function sendMessage($params) {
 | |
|     global $L_FQDN,$hooks;
 | |
|     $fp = @fsockopen($this->IP, $this->PORT, $errno, $errstr, $this->TIMEOUT);
 | |
|     if (!$fp) {
 | |
|       $this->error[] = 'Unable to connect';
 | |
|       return FALSE;
 | |
|     }
 | |
|     // Authenticate:
 | |
|     $params['server']=$L_FQDN;
 | |
|     $params['key']=$this->KEY;
 | |
|     // MySQL Host for this user ? 
 | |
|     $moreparams=$hooks->invoke("lxc_params",array($params));
 | |
|     foreach($moreparams as $p) {
 | |
|       foreach($p as $k=>$v) 
 | |
| 	$params[$k]=$v;
 | |
|     }
 | |
| 
 | |
|     $msg = serialize($params);
 | |
|     if (fwrite ($fp, $msg."\n") < 0) {
 | |
|       $this->error[] = 'Unable to send data';
 | |
|       return FALSE;
 | |
|     }
 | |
|     $resp = '';
 | |
|     $resp = fgets($fp, 8192);
 | |
|     fclose ($fp);
 | |
| 
 | |
|     $data = @unserialize($resp);
 | |
|   
 | |
|     if (isset($data['error']) && $data['error']>0) {
 | |
|       $this->error[] = $data['msg'];
 | |
|       return FALSE;
 | |
|     } else {
 | |
|       return $resp;
 | |
|     }
 | |
|   }
 | |
| 
 | |
| 
 | |
|   /** 
 | |
|    * START a Virtual Machine on the remote VM manager
 | |
|    * for user $login having hashed password $pass and uid $uid
 | |
|    */
 | |
|   public function start($login = FALSE, $pass = FALSE, $uid = FALSE) {
 | |
|     global $mem, $db, $err, $mysql;
 | |
| 
 | |
|     if ($this->getvm() !== FALSE) {
 | |
|       $err->raise('lxc', _('VM already started'));
 | |
|       return FALSE;
 | |
|     }
 | |
|     unset($this->error);
 | |
| 
 | |
|     $login = $login ? $login : $mem->user['login'];
 | |
|     $pass  = $pass  ? $pass  : $mem->user['pass'];
 | |
|     $uid   = $uid   ? $uid   : $mem->user['uid'];
 | |
| 
 | |
|     $msgg = array('action'=>'start', 'login'=>$login, 'pass' => $pass, 'uid'=> $uid);  
 | |
|     $msgg['mysql_host'] = $mysql->dbus->Host;
 | |
| 
 | |
|     $res = $this->sendMessage($msgg);
 | |
|     if ($res === FALSE) {
 | |
|       return $this->error;
 | |
|     } else {
 | |
|       $data = unserialize($res);
 | |
|       $error = $data['error'];
 | |
|       $hostname = $data['hostname'];
 | |
|       $msg = $data['msg'];
 | |
|       $date_start = 'NOW()';
 | |
|       $uid = $mem->user['uid'];
 | |
| 
 | |
|       if ((int)$data['error'] != 0) {
 | |
|         $err->raise('lxc', _($data['msg']));
 | |
|         return FALSE;
 | |
|       }
 | |
|       $db->query("INSERT INTO vm_history (ip,date_start,uid,serialized_object) VALUES ('$hostname', $date_start, '$uid', '$res')");
 | |
|       return $res;
 | |
|     }
 | |
|   }
 | |
| 
 | |
| 
 | |
|   /**
 | |
|    * 
 | |
|    */
 | |
|   public function getvm($login = FALSE) {
 | |
|     global $db, $mem, $cuid;
 | |
| 
 | |
|     $login = $login ? $login : $mem->user['login'];
 | |
|     $msgg = array('action'=>'get', 'login'=>$login);  
 | |
|     $res = $this->sendMessage($msgg);
 | |
|     if (!$res) return FALSE;
 | |
|     return unserialize($res);
 | |
|   }
 | |
| 
 | |
| 
 | |
|   /** 
 | |
|    * Stop the currently running VM
 | |
|    */
 | |
|   public function stop() {
 | |
|     global $db, $mem;
 | |
|     $vm = $this->getvm();
 | |
|     if ($vm === FALSE)
 | |
|       return FALSE;
 | |
| 
 | |
|     if ($this->sendMessage(array('action' => 'stop', 'vm' => $vm['vm'])) === FALSE)
 | |
|       return FALSE;
 | |
|     return TRUE;
 | |
|   }
 | |
| 
 | |
| 
 | |
| 
 | |
| } // class m_lxc
 |