|
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 } |