Alternc  3.2
Alternc logiel libre pour l'h├ębergement
 All Data Structures Namespaces Files Functions Variables Pages
m_lxc.php
Go to the documentation of this file.
1 <?php
2 
3 /*
4  ----------------------------------------------------------------------
5  AlternC - Web Hosting System
6  Copyright (C) 2000-2013 by the AlternC Development Team.
7  https://alternc.org/
8  ----------------------------------------------------------------------
9  LICENSE
10 
11  This program is free software; you can redistribute it and/or
12  modify it under the terms of the GNU General Public License (GPL)
13  as published by the Free Software Foundation; either version 2
14  of the License, or (at your option) any later version.
15 
16  This program is distributed in the hope that it will be useful,
17  but WITHOUT ANY WARRANTY; without even the implied warranty of
18  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
19  GNU General Public License for more details.
20 
21  To read the license please visit http://www.gnu.org/copyleft/gpl.html
22  ----------------------------------------------------------------------
23  Purpose of file: Manage LXC-based virtual machine through an inetd-based protocol
24  ----------------------------------------------------------------------
25 */
26 
27 include_once(dirname(__FILE__) . '/vm.class.php');
28 
29 
30 /**
31  * Manage AlternC's virtual machine start/stop using our own inetd-based protocol.
32  */
33 class m_lxc implements vm {
34 
35 
36  public $IP;
37  public $PORT;
38  public $TIMEOUT = 5;
39  public $error = array();
40 
41 
42  /**
43  * Constructor, initialize the class informations from AlternC's variables
44  */
45  function m_lxc() {
46  $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')));
47  $this->PORT = variable_get('lxc_port', '6504', "Port of the Alternc's LXC server", array(array('desc'=>'Port','type'=>'integer')));
48  $this->KEY = variable_get('lxc_key', '', "Shared key with the Alternc's LXC server", array(array('desc'=>'Shared key','type'=>'string')));
49  $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')));
50  }
51 
52 
53  /**
54  * HOOK: add the "Console Access" to AlternC's main menu
55  */
56  function hook_menu() {
57  if ( empty($this->IP)) return ; // No menu if no server
58 
59  $obj = array(
60  'title' => _("Console access"),
61  'ico' => 'images/ssh.png',
62  'link' => 'vm.php',
63  'pos' => 95,
64  ) ;
65 
66  return $obj;
67  }
68 
69 
70  /**
71  * HOOK: remove VM history for AlternC account
72  */
73  function hook_admin_del_member() {
74  global $db,$err,$cuid;
75  $err->log("lxc","alternc_del_member");
76  $db->query("DELETE FROM vm_history WHERE uid='$cuid'");
77  return true;
78  }
79 
80 
81  /**
82  * Send a message to a remote VM manager instance
83  * $params are the parameters to send as serialized data
84  * to the listening server.
85  * Return the unserialized response data, if the message has been sent successfully
86  * or FALSE if an error occurred. In that case $error[] is set.
87  */
88  private function sendMessage($params) {
89  global $L_FQDN,$hooks;
90  $fp = @fsockopen($this->IP, $this->PORT, $errno, $errstr, $this->TIMEOUT);
91  if (!$fp) {
92  $this->error[] = 'Unable to connect';
93  return FALSE;
94  }
95  // Authenticate:
96  $params['server']=$L_FQDN;
97  $params['key']=$this->KEY;
98  // MySQL Host for this user ?
99  $moreparams=$hooks->invoke("lxc_params",array($params));
100  foreach($moreparams as $p) {
101  foreach($p as $k=>$v)
102  $params[$k]=$v;
103  }
104 
105  $msg = serialize($params);
106  if (fwrite ($fp, $msg."\n") < 0) {
107  $this->error[] = 'Unable to send data';
108  return FALSE;
109  }
110  $resp = '';
111  $resp = fgets($fp, 8192);
112  fclose ($fp);
113 
114  $data = @unserialize($resp);
115 
116  if (isset($data['error']) && $data['error']>0) {
117  $this->error[] = $data['msg'];
118  return FALSE;
119  } else {
120  return $resp;
121  }
122  }
123 
124 
125  /**
126  * START a Virtual Machine on the remote VM manager
127  * for user $login having hashed password $pass and uid $uid
128  */
129  public function start($login = FALSE, $pass = FALSE, $uid = FALSE) {
130  global $mem, $db, $err, $mysql;
131 
132  if ($this->getvm() !== FALSE) {
133  $err->raise('lxc', _('VM already started'));
134  return FALSE;
135  }
136  unset($this->error);
137 
138  $login = $login ? $login : $mem->user['login'];
139  $pass = $pass ? $pass : $mem->user['pass'];
140  $uid = $uid ? $uid : $mem->user['uid'];
141 
142  $msgg = array('action'=>'start', 'login'=>$login, 'pass' => $pass, 'uid'=> $uid);
143  $msgg['mysql_host'] = $mysql->dbus->Host;
144 
145  $res = $this->sendMessage($msgg);
146  if ($res === FALSE) {
147  return $this->error;
148  } else {
149  $data = unserialize($res);
150  $error = $data['error'];
151  $hostname = $data['hostname'];
152  $msg = $data['msg'];
153  $date_start = 'NOW()';
154  $uid = $mem->user['uid'];
155 
156  if ((int)$data['error'] != 0) {
157  $err->raise('lxc', _($data['msg']));
158  return FALSE;
159  }
160  $db->query("INSERT INTO vm_history (ip,date_start,uid,serialized_object) VALUES ('$hostname', $date_start, '$uid', '$res')");
161  return $res;
162  }
163  }
164 
165 
166  /**
167  *
168  */
169  public function getvm($login = FALSE) {
170  global $db, $mem, $cuid;
171 
172  $login = $login ? $login : $mem->user['login'];
173  $msgg = array('action'=>'get', 'login'=>$login);
174  $res = $this->sendMessage($msgg);
175  if (!$res) return FALSE;
176  return unserialize($res);
177  }
178 
179 
180  /**
181  * Stop the currently running VM
182  */
183  public function stop() {
184  global $db, $mem;
185  $vm = $this->getvm();
186  if ($vm === FALSE)
187  return FALSE;
188 
189  if ($this->sendMessage(array('action' => 'stop', 'vm' => $vm['vm'])) === FALSE)
190  return FALSE;
191  return TRUE;
192  }
193 
194 
195 
196 } // class m_lxc