web/lib/Zend/Cloud/Infrastructure/Adapter/AbstractAdapter.php
changeset 808 6b6c2214f778
child 1230 68c69c656a2c
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/web/lib/Zend/Cloud/Infrastructure/Adapter/AbstractAdapter.php	Thu Mar 21 19:52:38 2013 +0100
@@ -0,0 +1,175 @@
+<?php
+/**
+ * LICENSE
+ *
+ * This source file is subject to the new BSD license that is bundled
+ * with this package in the file LICENSE.txt.
+ * It is also available through the world-wide-web at this URL:
+ * http://framework.zend.com/license/new-bsd
+ * If you did not receive a copy of the license and are unable to
+ * obtain it through the world-wide-web, please send an email
+ * to license@zend.com so we can send you a copy immediately.
+ *
+ * @category   Zend
+ * @package    Zend_Cloud
+ * @subpackage DocumentService
+ * @copyright  Copyright (c) 2005-2012 Zend Technologies USA Inc. (http://www.zend.com)
+ * @license    http://framework.zend.com/license/new-bsd     New BSD License
+ */
+
+require_once 'Zend/Cloud/Infrastructure/Adapter.php';
+require_once 'Zend/Cloud/Infrastructure/Instance.php';
+
+/**
+ * Abstract infrastructure service adapter
+ *
+ * @category   Zend
+ * @package    Zend_Cloud_Infrastructure
+ * @subpackage Adapter
+ * @copyright  Copyright (c) 2005-2012 Zend Technologies USA Inc. (http://www.zend.com)
+ * @license    http://framework.zend.com/license/new-bsd     New BSD License
+ */
+abstract class Zend_Cloud_Infrastructure_Adapter_AbstractAdapter implements Zend_Cloud_Infrastructure_Adapter
+{
+    /**
+     * Store the last response from the adpter
+     * 
+     * @var array
+     */
+    protected $adapterResult;
+    
+    /**
+     * Valid metrics for monitor
+     * 
+     * @var array
+     */
+    protected $validMetrics = array(
+        Zend_Cloud_Infrastructure_Instance::MONITOR_CPU,
+        Zend_Cloud_Infrastructure_Instance::MONITOR_RAM,
+        Zend_Cloud_Infrastructure_Instance::MONITOR_DISK,
+        Zend_Cloud_Infrastructure_Instance::MONITOR_DISK_READ,
+        Zend_Cloud_Infrastructure_Instance::MONITOR_DISK_WRITE,
+        Zend_Cloud_Infrastructure_Instance::MONITOR_NETWORK_IN,
+        Zend_Cloud_Infrastructure_Instance::MONITOR_NETWORK_OUT,
+    );
+
+    /**
+     * Get the last result of the adapter
+     *
+     * @return array
+     */
+    public function getAdapterResult()
+    {
+        return $this->adapterResult;
+    }
+
+    /**
+     * Wait for status $status with a timeout of $timeout seconds
+     * 
+     * @param  string $id
+     * @param  string $status
+     * @param  integer $timeout 
+     * @return boolean
+     */
+    public function waitStatusInstance($id, $status, $timeout = self::TIMEOUT_STATUS_CHANGE)
+    {
+        if (empty($id) || empty($status)) {
+            return false;
+        }
+
+        $num = 0;
+        while (($num<$timeout) && ($this->statusInstance($id) != $status)) {
+            sleep(self::TIME_STEP_STATUS_CHANGE);
+            $num += self::TIME_STEP_STATUS_CHANGE;
+        }
+        return ($num < $timeout);
+    }
+
+    /**
+     * Run arbitrary shell script on an instance
+     *
+     * @param  string $id
+     * @param  array $param
+     * @param  string|array $cmd
+     * @return string|array
+     */ 
+    public function deployInstance($id, $params, $cmd)
+    {
+        if (!function_exists("ssh2_connect")) {
+            require_once 'Zend/Cloud/Infrastructure/Exception.php';
+            throw new Zend_Cloud_Infrastructure_Exception('Deployment requires the PHP "SSH" extension (ext/ssh2)');
+        }
+
+        if (empty($id)) {
+            require_once 'Zend/Cloud/Infrastructure/Exception.php';
+            throw new Zend_Cloud_Infrastructure_Exception('You must specify the instance where to deploy');
+        }
+
+        if (empty($cmd)) {
+            require_once 'Zend/Cloud/Infrastructure/Exception.php';
+            throw new Zend_Cloud_Infrastructure_Exception('You must specify the shell commands to run on the instance');
+        }
+
+        if (empty($params) 
+            || empty($params[Zend_Cloud_Infrastructure_Instance::SSH_USERNAME]) 
+            || (empty($params[Zend_Cloud_Infrastructure_Instance::SSH_PASSWORD]) 
+                && empty($params[Zend_Cloud_Infrastructure_Instance::SSH_KEY]))
+        ) {
+            require_once 'Zend/Cloud/Infrastructure/Exception.php';
+            throw new Zend_Cloud_Infrastructure_Exception('You must specify the params for the SSH connection');
+        }
+
+        $host = $this->publicDnsInstance($id);
+        if (empty($host)) {
+            require_once 'Zend/Cloud/Infrastructure/Exception.php';
+            throw new Zend_Cloud_Infrastructure_Exception(sprintf(
+                'The instance identified by "%s" does not exist', 
+                $id
+            ));
+        }
+
+        $conn = ssh2_connect($host);
+        if (!ssh2_auth_password($conn, $params[Zend_Cloud_Infrastructure_Instance::SSH_USERNAME], 
+                $params[Zend_Cloud_Infrastructure_Instance::SSH_PASSWORD])) {
+            require_once 'Zend/Cloud/Infrastructure/Exception.php';
+            throw new Zend_Cloud_Infrastructure_Exception('SSH authentication failed');
+        }
+
+        if (is_array($cmd)) {
+            $result = array();
+            foreach ($cmd as $command) {
+                $stream      = ssh2_exec($conn, $command);
+                $errorStream = ssh2_fetch_stream($stream, SSH2_STREAM_STDERR);
+
+                stream_set_blocking($errorStream, true);
+                stream_set_blocking($stream, true); 
+
+                $output = stream_get_contents($stream);
+                $error  = stream_get_contents($errorStream);
+                
+                if (empty($error)) {
+                    $result[$command] = $output;
+                } else {
+                    $result[$command] = $error;
+                }
+            }
+        } else {
+            $stream      = ssh2_exec($conn, $cmd);
+            $result      = stream_set_blocking($stream, true);
+            $errorStream = ssh2_fetch_stream($stream, SSH2_STREAM_STDERR);
+
+            stream_set_blocking($errorStream, true);
+            stream_set_blocking($stream, true); 
+
+            $output = stream_get_contents($stream);
+            $error  = stream_get_contents($errorStream);
+            
+            if (empty($error)) {
+                $result = $output;
+            } else {
+                $result = $error;
+            }
+        }    
+        return $result;
+    }
+}