web/lib/Zend/Cloud/Infrastructure/Adapter/AbstractAdapter.php
changeset 808 6b6c2214f778
child 1230 68c69c656a2c
equal deleted inserted replaced
807:877f952ae2bd 808:6b6c2214f778
       
     1 <?php
       
     2 /**
       
     3  * LICENSE
       
     4  *
       
     5  * This source file is subject to the new BSD license that is bundled
       
     6  * with this package in the file LICENSE.txt.
       
     7  * It is also available through the world-wide-web at this URL:
       
     8  * http://framework.zend.com/license/new-bsd
       
     9  * If you did not receive a copy of the license and are unable to
       
    10  * obtain it through the world-wide-web, please send an email
       
    11  * to license@zend.com so we can send you a copy immediately.
       
    12  *
       
    13  * @category   Zend
       
    14  * @package    Zend_Cloud
       
    15  * @subpackage DocumentService
       
    16  * @copyright  Copyright (c) 2005-2012 Zend Technologies USA Inc. (http://www.zend.com)
       
    17  * @license    http://framework.zend.com/license/new-bsd     New BSD License
       
    18  */
       
    19 
       
    20 require_once 'Zend/Cloud/Infrastructure/Adapter.php';
       
    21 require_once 'Zend/Cloud/Infrastructure/Instance.php';
       
    22 
       
    23 /**
       
    24  * Abstract infrastructure service adapter
       
    25  *
       
    26  * @category   Zend
       
    27  * @package    Zend_Cloud_Infrastructure
       
    28  * @subpackage Adapter
       
    29  * @copyright  Copyright (c) 2005-2012 Zend Technologies USA Inc. (http://www.zend.com)
       
    30  * @license    http://framework.zend.com/license/new-bsd     New BSD License
       
    31  */
       
    32 abstract class Zend_Cloud_Infrastructure_Adapter_AbstractAdapter implements Zend_Cloud_Infrastructure_Adapter
       
    33 {
       
    34     /**
       
    35      * Store the last response from the adpter
       
    36      * 
       
    37      * @var array
       
    38      */
       
    39     protected $adapterResult;
       
    40     
       
    41     /**
       
    42      * Valid metrics for monitor
       
    43      * 
       
    44      * @var array
       
    45      */
       
    46     protected $validMetrics = array(
       
    47         Zend_Cloud_Infrastructure_Instance::MONITOR_CPU,
       
    48         Zend_Cloud_Infrastructure_Instance::MONITOR_RAM,
       
    49         Zend_Cloud_Infrastructure_Instance::MONITOR_DISK,
       
    50         Zend_Cloud_Infrastructure_Instance::MONITOR_DISK_READ,
       
    51         Zend_Cloud_Infrastructure_Instance::MONITOR_DISK_WRITE,
       
    52         Zend_Cloud_Infrastructure_Instance::MONITOR_NETWORK_IN,
       
    53         Zend_Cloud_Infrastructure_Instance::MONITOR_NETWORK_OUT,
       
    54     );
       
    55 
       
    56     /**
       
    57      * Get the last result of the adapter
       
    58      *
       
    59      * @return array
       
    60      */
       
    61     public function getAdapterResult()
       
    62     {
       
    63         return $this->adapterResult;
       
    64     }
       
    65 
       
    66     /**
       
    67      * Wait for status $status with a timeout of $timeout seconds
       
    68      * 
       
    69      * @param  string $id
       
    70      * @param  string $status
       
    71      * @param  integer $timeout 
       
    72      * @return boolean
       
    73      */
       
    74     public function waitStatusInstance($id, $status, $timeout = self::TIMEOUT_STATUS_CHANGE)
       
    75     {
       
    76         if (empty($id) || empty($status)) {
       
    77             return false;
       
    78         }
       
    79 
       
    80         $num = 0;
       
    81         while (($num<$timeout) && ($this->statusInstance($id) != $status)) {
       
    82             sleep(self::TIME_STEP_STATUS_CHANGE);
       
    83             $num += self::TIME_STEP_STATUS_CHANGE;
       
    84         }
       
    85         return ($num < $timeout);
       
    86     }
       
    87 
       
    88     /**
       
    89      * Run arbitrary shell script on an instance
       
    90      *
       
    91      * @param  string $id
       
    92      * @param  array $param
       
    93      * @param  string|array $cmd
       
    94      * @return string|array
       
    95      */ 
       
    96     public function deployInstance($id, $params, $cmd)
       
    97     {
       
    98         if (!function_exists("ssh2_connect")) {
       
    99             require_once 'Zend/Cloud/Infrastructure/Exception.php';
       
   100             throw new Zend_Cloud_Infrastructure_Exception('Deployment requires the PHP "SSH" extension (ext/ssh2)');
       
   101         }
       
   102 
       
   103         if (empty($id)) {
       
   104             require_once 'Zend/Cloud/Infrastructure/Exception.php';
       
   105             throw new Zend_Cloud_Infrastructure_Exception('You must specify the instance where to deploy');
       
   106         }
       
   107 
       
   108         if (empty($cmd)) {
       
   109             require_once 'Zend/Cloud/Infrastructure/Exception.php';
       
   110             throw new Zend_Cloud_Infrastructure_Exception('You must specify the shell commands to run on the instance');
       
   111         }
       
   112 
       
   113         if (empty($params) 
       
   114             || empty($params[Zend_Cloud_Infrastructure_Instance::SSH_USERNAME]) 
       
   115             || (empty($params[Zend_Cloud_Infrastructure_Instance::SSH_PASSWORD]) 
       
   116                 && empty($params[Zend_Cloud_Infrastructure_Instance::SSH_KEY]))
       
   117         ) {
       
   118             require_once 'Zend/Cloud/Infrastructure/Exception.php';
       
   119             throw new Zend_Cloud_Infrastructure_Exception('You must specify the params for the SSH connection');
       
   120         }
       
   121 
       
   122         $host = $this->publicDnsInstance($id);
       
   123         if (empty($host)) {
       
   124             require_once 'Zend/Cloud/Infrastructure/Exception.php';
       
   125             throw new Zend_Cloud_Infrastructure_Exception(sprintf(
       
   126                 'The instance identified by "%s" does not exist', 
       
   127                 $id
       
   128             ));
       
   129         }
       
   130 
       
   131         $conn = ssh2_connect($host);
       
   132         if (!ssh2_auth_password($conn, $params[Zend_Cloud_Infrastructure_Instance::SSH_USERNAME], 
       
   133                 $params[Zend_Cloud_Infrastructure_Instance::SSH_PASSWORD])) {
       
   134             require_once 'Zend/Cloud/Infrastructure/Exception.php';
       
   135             throw new Zend_Cloud_Infrastructure_Exception('SSH authentication failed');
       
   136         }
       
   137 
       
   138         if (is_array($cmd)) {
       
   139             $result = array();
       
   140             foreach ($cmd as $command) {
       
   141                 $stream      = ssh2_exec($conn, $command);
       
   142                 $errorStream = ssh2_fetch_stream($stream, SSH2_STREAM_STDERR);
       
   143 
       
   144                 stream_set_blocking($errorStream, true);
       
   145                 stream_set_blocking($stream, true); 
       
   146 
       
   147                 $output = stream_get_contents($stream);
       
   148                 $error  = stream_get_contents($errorStream);
       
   149                 
       
   150                 if (empty($error)) {
       
   151                     $result[$command] = $output;
       
   152                 } else {
       
   153                     $result[$command] = $error;
       
   154                 }
       
   155             }
       
   156         } else {
       
   157             $stream      = ssh2_exec($conn, $cmd);
       
   158             $result      = stream_set_blocking($stream, true);
       
   159             $errorStream = ssh2_fetch_stream($stream, SSH2_STREAM_STDERR);
       
   160 
       
   161             stream_set_blocking($errorStream, true);
       
   162             stream_set_blocking($stream, true); 
       
   163 
       
   164             $output = stream_get_contents($stream);
       
   165             $error  = stream_get_contents($errorStream);
       
   166             
       
   167             if (empty($error)) {
       
   168                 $result = $output;
       
   169             } else {
       
   170                 $result = $error;
       
   171             }
       
   172         }    
       
   173         return $result;
       
   174     }
       
   175 }