mirror of
				https://github.com/apache/cloudstack.git
				synced 2025-10-26 08:42:29 +01:00 
			
		
		
		
	Added fix for bug 5056.
The fix contains fixes related to ssh library majorly. Complete description should be available under bug description. Signed-off-by: Santhosh Edukulla <Santhosh.Edukulla@citrix.com> Signed-off-by: SrikanteswaraRao Talluri <talluri@apache.org>
This commit is contained in:
		
							parent
							
								
									ea2eafcd85
								
							
						
					
					
						commit
						089f43a1eb
					
				| @ -40,3 +40,5 @@ EMPTY_LIST = "EMPTY_LIST" | |||||||
| FAIL = 0 | FAIL = 0 | ||||||
| PASS = 1 | PASS = 1 | ||||||
| MATCH_NOT_FOUND = "ELEMENT NOT FOUND IN THE INPUT" | MATCH_NOT_FOUND = "ELEMENT NOT FOUND IN THE INPUT" | ||||||
|  | SUCCESS = "SUCCESS" | ||||||
|  | EXCEPTION_OCCURRED = "Exception Occurred" | ||||||
|  | |||||||
| @ -113,8 +113,16 @@ def cleanup_resources(api_client, resources): | |||||||
|         obj.delete(api_client) |         obj.delete(api_client) | ||||||
| 
 | 
 | ||||||
| 
 | 
 | ||||||
| def is_server_ssh_ready(ipaddress, port, username, password, retries=10, timeout=30, keyPairFileLocation=None): | def is_server_ssh_ready(ipaddress, port, username, password, retries=10, retryinterv=30, timeout=3.0, keyPairFileLocation=None): | ||||||
|     """Return ssh handle else wait till sshd is running""" |     ''' | ||||||
|  |     @Name: is_server_ssh_ready | ||||||
|  |     @Input: timeout: tcp connection timeout flag, | ||||||
|  |             others information need to be added | ||||||
|  |     @Output:object for remoteSSHClient | ||||||
|  |     Name of the function is little misnomer and is not | ||||||
|  |               verifying anything as such mentioned | ||||||
|  |     ''' | ||||||
|  | 
 | ||||||
|     try: |     try: | ||||||
|         ssh = remoteSSHClient( |         ssh = remoteSSHClient( | ||||||
|             host=ipaddress, |             host=ipaddress, | ||||||
| @ -123,9 +131,10 @@ def is_server_ssh_ready(ipaddress, port, username, password, retries=10, timeout | |||||||
|             passwd=password, |             passwd=password, | ||||||
|             keyPairFileLocation=keyPairFileLocation, |             keyPairFileLocation=keyPairFileLocation, | ||||||
|             retries=retries, |             retries=retries, | ||||||
|             delay=timeout) |             delay=retryinterv, | ||||||
|  |             timeout=timeout) | ||||||
|     except Exception, e: |     except Exception, e: | ||||||
|         raise Exception("Failed to bring up ssh service in time. Waited %ss. Error is %s" % (retries * timeout, e)) |         raise Exception("SSH connection has Failed. Waited %ss. Error is %s" % (retries * retryinterv, e)) | ||||||
|     else: |     else: | ||||||
|         return ssh |         return ssh | ||||||
| 
 | 
 | ||||||
|  | |||||||
| @ -20,57 +20,48 @@ import time | |||||||
| import cloudstackException | import cloudstackException | ||||||
| import contextlib | import contextlib | ||||||
| import logging | import logging | ||||||
|  | from marvin.codes import ( | ||||||
|  |     SUCCESS, FAIL, INVALID_INPUT, EXCEPTION_OCCURRED | ||||||
|  |     ) | ||||||
| from contextlib import closing | from contextlib import closing | ||||||
| 
 | 
 | ||||||
| 
 | 
 | ||||||
| class remoteSSHClient(object): | class remoteSSHClient(object): | ||||||
|  |     ''' | ||||||
|  |     Added timeout flag for ssh connect calls.Default to 3.0 seconds | ||||||
|  |     ''' | ||||||
|     def __init__(self, host, port, user, passwd, retries=10, delay=30, |     def __init__(self, host, port, user, passwd, retries=10, delay=30, | ||||||
|                  log_lvl=logging.INFO, keyPairFileLocation=None): |                  log_lvl=logging.INFO, keyPairFiles=None, timeout=3.0): | ||||||
|         self.host = host |         self.host = None | ||||||
|         self.port = port |         self.port = 22 | ||||||
|         self.user = user |         self.user = user | ||||||
|         self.passwd = passwd |         self.passwd = passwd | ||||||
|         self.keyPairFile = keyPairFileLocation |         self.keyPairFiles = keyPairFiles | ||||||
|         self.ssh = paramiko.SSHClient() |         self.ssh = paramiko.SSHClient() | ||||||
|         self.ssh.set_missing_host_key_policy(paramiko.AutoAddPolicy()) |         self.ssh.set_missing_host_key_policy(paramiko.AutoAddPolicy()) | ||||||
|         self.logger = logging.getLogger('sshClient') |         self.logger = logging.getLogger('sshClient') | ||||||
|  |         self.retryCnt = 0 | ||||||
|  |         self.delay = 0 | ||||||
|  |         self.timeout = 3.0 | ||||||
|         ch = logging.StreamHandler() |         ch = logging.StreamHandler() | ||||||
|         ch.setLevel(log_lvl) |         ch.setLevel(log_lvl) | ||||||
|         self.logger.addHandler(ch) |         self.logger.addHandler(ch) | ||||||
| 
 | 
 | ||||||
|         retry_count = retries |         #Check invalid host value and raise exception | ||||||
|         while retry_count >= 0: |         #Atleast host is required for connection | ||||||
|             try: |         if host is not None and host != '': | ||||||
|                 if keyPairFileLocation is None: |             self.host = host | ||||||
|                     self.ssh.connect(str(host), int(port), user, passwd) |         if retries is not None and retries > 0: | ||||||
|                     self.logger.debug("SSH connect: %s@%s with passwd %s" % |             self.retryCnt = retries | ||||||
|                                       (user, str(host), passwd)) |         if delay is not None and delay > 0: | ||||||
|                 else: |             self.delay = delay | ||||||
|                     self.ssh.connect(hostname=str(host), |         if timeout is not None and timeout > 0: | ||||||
|                                      port=int(port), |             self.timeout = timeout | ||||||
|                                      username=str(user), |         if port is not None or port >= 0: | ||||||
|                                      key_filename=str(keyPairFileLocation), |             self.port = port | ||||||
|                                      look_for_keys=False |         if self.createConnection() == FAIL: | ||||||
|                                      ) |             raise cloudstackException.\ | ||||||
|                     self.logger.debug( |                 internalError("Connection Failed") | ||||||
|                         "connecting to server %s with user %s key %s" % |  | ||||||
|                         (str(host), user, keyPairFileLocation)) |  | ||||||
|                     self.logger.debug("SSH connect: %s@%s with passwd %s" % |  | ||||||
|                                       (user, str(host), passwd)) |  | ||||||
|             #except paramiko.AuthenticationException, authEx: |  | ||||||
|             #    raise cloudstackException. \ |  | ||||||
|             #        InvalidParameterException("Invalid credentials to " |  | ||||||
|             #                                  + "login to %s on port %s" % |  | ||||||
|             #                                  (str(host), port)) |  | ||||||
|             except Exception as se: |  | ||||||
|                 if retry_count == 0: |  | ||||||
|                     raise cloudstackException. \ |  | ||||||
|                         InvalidParameterException(repr(se)) |  | ||||||
|             else: |  | ||||||
|                 return |  | ||||||
| 
 |  | ||||||
|             retry_count = retry_count - 1 |  | ||||||
|             time.sleep(delay) |  | ||||||
| 
 | 
 | ||||||
|     def execute(self, command): |     def execute(self, command): | ||||||
|         stdin, stdout, stderr = self.ssh.exec_command(command) |         stdin, stdout, stderr = self.ssh.exec_command(command) | ||||||
| @ -89,6 +80,88 @@ class remoteSSHClient(object): | |||||||
|                           (command, str(self.host), results)) |                           (command, str(self.host), results)) | ||||||
|         return results |         return results | ||||||
| 
 | 
 | ||||||
|  |     def createConnection(self): | ||||||
|  |         ''' | ||||||
|  |         @Name: createConnection | ||||||
|  |         @Desc: Creates an ssh connection for | ||||||
|  |                retries mentioned,along with sleep mentioned | ||||||
|  |         @Output: SUCCESS on successful connection | ||||||
|  |                  FAIL If connection through ssh failed | ||||||
|  |         ''' | ||||||
|  |         ret = FAIL | ||||||
|  |         while self.retryCnt >= 0: | ||||||
|  |             try: | ||||||
|  |                 self.logger.debug("SSH Connection: Host:%s User:%s\ | ||||||
|  |                                    Port:%s KeyPairFile: %s" % | ||||||
|  |                                   (self.host, self.user, str(self.port), | ||||||
|  |                                    str(self.keyPairFiles))) | ||||||
|  |                 if self.keyPairFiles is None: | ||||||
|  |                     self.ssh.connect(hostname=self.host, | ||||||
|  |                                      port=self.port, | ||||||
|  |                                      username=self.user, | ||||||
|  |                                      password=self.passwd, | ||||||
|  |                                      timeout=self.timeout) | ||||||
|  |                 else: | ||||||
|  |                     self.ssh.connect(hostname=self.host, | ||||||
|  |                                      port=self.port, | ||||||
|  |                                      username=self.user, | ||||||
|  |                                      password=self.passwd, | ||||||
|  |                                      key_filename=self.keyPairFiles, | ||||||
|  |                                      timeout=self.timeout, | ||||||
|  |                                      look_for_keys=False | ||||||
|  |                                      ) | ||||||
|  |                 ret = SUCCESS | ||||||
|  |                 break | ||||||
|  |             except Exception as se: | ||||||
|  |                 self.retryCnt = self.retryCnt - 1 | ||||||
|  |                 if self.retryCnt == 0: | ||||||
|  |                     break | ||||||
|  |                 time.sleep(self.delay) | ||||||
|  |         return ret | ||||||
|  | 
 | ||||||
|  |     def runCommand(self, command): | ||||||
|  |         ''' | ||||||
|  |         @Name: runCommand | ||||||
|  |         @Desc: Runs a command over ssh and | ||||||
|  |                returns the result along with status code | ||||||
|  |         @Input: command to execute | ||||||
|  |         @Output: 1: status of command executed. | ||||||
|  |                  Default to None | ||||||
|  |                  SUCCESS : If command execution is successful | ||||||
|  |                  FAIL    : If command execution has failed | ||||||
|  |                  EXCEPTION_OCCURRED: Exception occurred while executing | ||||||
|  |                                      command | ||||||
|  |                  INVALID_INPUT : If invalid value for command is passed | ||||||
|  |                  2: stdin,stdout,stderr values of command output | ||||||
|  |         ''' | ||||||
|  |         excep_msg = '' | ||||||
|  |         ret = {"status": None, "stdin": None, "stdout": None, "stderr": None} | ||||||
|  |         if command is None or command == '': | ||||||
|  |             ret["status"] = INVALID_INPUT | ||||||
|  |             return ret | ||||||
|  |         try: | ||||||
|  |             status_check = 1 | ||||||
|  |             stdin, stdout, stderr = self.ssh.exec_command(command) | ||||||
|  |             output = stdout.readlines() | ||||||
|  |             errors = stderr.readlines() | ||||||
|  |             inp = stdin.readlines() | ||||||
|  |             ret["stdin"] = inp | ||||||
|  |             ret["stdout"] = output | ||||||
|  |             ret["stderr"] = errors | ||||||
|  |             if stdout is not None: | ||||||
|  |                 status_check = stdout.channel.recv_exit_status() | ||||||
|  |             if status_check == 0: | ||||||
|  |                 ret["status"] = SUCCESS | ||||||
|  |             else: | ||||||
|  |                 ret["status"] = FAIL | ||||||
|  |         except Exception as e: | ||||||
|  |             excep_msg = str(e) | ||||||
|  |             ret["status"] = EXCEPTION_OCCURRED | ||||||
|  |         finally: | ||||||
|  |             self.logger.debug(" Host: %s Cmd: %s Output:%s Exception: %s" % | ||||||
|  |                               (self.host, command, str(ret), excep_msg)) | ||||||
|  |             return ret | ||||||
|  | 
 | ||||||
|     def scp(self, srcFile, destPath): |     def scp(self, srcFile, destPath): | ||||||
|         transport = paramiko.Transport((self.host, int(self.port))) |         transport = paramiko.Transport((self.host, int(self.port))) | ||||||
|         transport.connect(username=self.user, password=self.passwd) |         transport.connect(username=self.user, password=self.passwd) | ||||||
| @ -99,7 +172,8 @@ class remoteSSHClient(object): | |||||||
|             raise e |             raise e | ||||||
| 
 | 
 | ||||||
|     def close(self): |     def close(self): | ||||||
|         self.ssh.close() |             if self.ssh is not None: | ||||||
|  |                 self.ssh.close() | ||||||
| 
 | 
 | ||||||
| 
 | 
 | ||||||
| if __name__ == "__main__": | if __name__ == "__main__": | ||||||
|  | |||||||
		Loading…
	
	
			
			x
			
			
		
	
		Reference in New Issue
	
	Block a user