Keith Robertson has uploaded a new change for review.

Change subject: tools: Better API error handling
......................................................................

tools: Better API error handling

Print the actual exception string when attempting
to create an instance of the API and fix
the 'NoneType' error that sometimes occurs when
API creation fails.

Change-Id: Ib51002532b726cb7becdd4e4289d385119fa1ea3
Signed-off-by: Keith Robertson <krobe...@redhat.com>
---
M src/engine-iso-uploader.py
1 file changed, 77 insertions(+), 68 deletions(-)


  git pull ssh://gerrit.ovirt.org:29418/ovirt-iso-uploader 
refs/changes/54/8954/1

diff --git a/src/engine-iso-uploader.py b/src/engine-iso-uploader.py
index 05a26f5..5ebe0be 100644
--- a/src/engine-iso-uploader.py
+++ b/src/engine-iso-uploader.py
@@ -32,21 +32,21 @@
 NFS_UMOUNT_OPTS = '-t nfs -f '
 NFS_USER = 'vdsm'
 NUMERIC_VDSM_ID = 36
-SUDO='/usr/bin/sudo'
-MOUNT='/bin/mount'
-UMOUNT='/bin/umount'
-SSH='/usr/bin/ssh'
-SCP='/usr/bin/scp'
-CP='/bin/cp'
-RM='/bin/rm -fv'
-MV='/bin/mv -fv'
-CHOWN='/bin/chown'
-CHMOD='/bin/chmod'
-TEST='/usr/bin/test'
-DEFAULT_CONFIGURATION_FILE='/etc/ovirt-engine/isouploader.conf'
-DEFAULT_LOG_FILE='/var/log/ovirt-engine/engine-iso-uploader.log'
-PERMS_MASK='640'
-PYTHON='/usr/bin/python'
+SUDO = '/usr/bin/sudo'
+MOUNT = '/bin/mount'
+UMOUNT = '/bin/umount'
+SSH = '/usr/bin/ssh'
+SCP = '/usr/bin/scp'
+CP = '/bin/cp'
+RM = '/bin/rm -fv'
+MV = '/bin/mv -fv'
+CHOWN = '/bin/chown'
+CHMOD = '/bin/chmod'
+TEST = '/usr/bin/test'
+DEFAULT_CONFIGURATION_FILE = '/etc/ovirt-engine/isouploader.conf'
+DEFAULT_LOG_FILE = '/var/log/ovirt-engine/engine-iso-uploader.log'
+PERMS_MASK = '640'
+PYTHON = '/usr/bin/python'
 
 
 def multilog(logger, msg):
@@ -64,12 +64,12 @@
     """
     A simple psudo-enumeration class to hold the current and future exit codes
     """
-    NOERR=0
-    CRITICAL=1
-    LIST_ISO_ERR=2
-    UPLOAD_ERR=3
-    CLEANUP_ERR=4
-    exit_code=NOERR
+    NOERR = 0
+    CRITICAL = 1
+    LIST_ISO_ERR = 2
+    UPLOAD_ERR = 3
+    CLEANUP_ERR = 4
+    exit_code = NOERR
 
 class Commands():
     """
@@ -77,7 +77,7 @@
     """
     LIST = 'list'
     UPLOAD = 'upload'
-    #DELETE = 'delete'
+    # DELETE = 'delete'
     ARY = [LIST, UPLOAD]
 
 class Caller(object):
@@ -106,7 +106,7 @@
         logging.debug("STDERR(%s)" % stderr)
 
         if returncode == 0:
-            return (stdout,returncode)
+            return (stdout, returncode)
         else:
             raise Exception(stderr)
 
@@ -210,8 +210,8 @@
 
         # we want the items from the ISOUploader section only
         try:
-            opts = ["--%s=%s" % (k,v)
-                       for k,v in cp.items("ISOUploader")]
+            opts = ["--%s=%s" % (k, v)
+                       for k, v in cp.items("ISOUploader")]
             (new_options, args) = self.parser.parse_args(args=opts, 
values=self.options)
             self.from_option_groups(new_options, self.parser)
             self.from_options(new_options, self.parser)
@@ -355,6 +355,9 @@
 
             url = "https://"; + self.configuration.get("engine") + "/api"
             try:
+                logging.debug('user(%s) ca(%s) insecure(%s)' % 
(self.configuration.get("user"),
+                                                                
self.configuration.get("engine_ca"),
+                                                                
self.configuration.get("insecure")))
                 self.api = API(url=url,
                                username=self.configuration.get("user"),
                                password=self.configuration.get("passwd"),
@@ -366,21 +369,22 @@
                     vrm = '%s.%s.%s' % (pi.get_version().get_major(),
                                         pi.get_version().get_minor(),
                                         pi.get_version().get_revision())
-                    logging.debug("API Vendor(%s)\tAPI Version(%s)" %  
(pi.get_vendor(), vrm))
+                    logging.debug("API Vendor(%s)\tAPI Version(%s)" % 
(pi.get_vendor(), vrm))
                 else:
                     logging.error(_("Unable to connect to REST API."))
                     return False
             except RequestError, re:
-                logging.error(_("Unable to connect to REST API.  Reason: %s") 
%  re.reason)
+                logging.error(_("Unable to connect to REST API.  Reason: %s") 
% re.reason)
                 return False
-            except ConnectionError:
-                logging.error(_("Problem connecting to the REST API.  Is the 
service available and does the CA certificate exist?"))
+            except ConnectionError, ce:
+                logging.error(_("Problem connecting to the REST API.  \
+Is the service available and does the CA certificate exist? Error: %s") % 
str(ce))
                 return False
             except NoCertificatesError:
                 logging.error(_("Problem connecting to the REST API.  The CA 
is invalid.  To override use the \'insecure\' option."))
                 return False
             except Exception, e:
-                logging.error(_("Unable to connect to REST API.  Message: %s") 
%  e)
+                logging.error(_("Unable to connect to REST API.  Message: %s") 
% e)
                 return False
         return True
 
@@ -421,10 +425,10 @@
                 print "\n".join(fmt % (name, dcName, status)
                                 for name, dcName, status in isoAry)
              else:
-                ExitCodes.exit_code=ExitCodes.LIST_ISO_ERR
+                ExitCodes.exit_code = ExitCodes.LIST_ISO_ERR
                 logging.error(_("There are no ISO storage domains."))
         else:
-            ExitCodes.exit_code=ExitCodes.LIST_ISO_ERR
+            ExitCodes.exit_code = ExitCodes.LIST_ISO_ERR
             logging.error(_("There are no datacenters with ISO storage 
domains."))
 
     def get_host_and_path_from_ISO_domain(self, isodomain):
@@ -435,7 +439,8 @@
           (host, id, path)
         """
         if not self._initialize_api():
-            return
+            return (None, None, None)
+
         sd = self.api.storagedomains.get(isodomain)
         if sd is not None:
             if sd.get_type() != 'iso':
@@ -498,11 +503,11 @@
         """
 
         cmd = self.format_ssh_command()
-        cmd += ' %s%s "%s -e %s"'  % (user, address, TEST, file)
+        cmd += ' %s%s "%s -e %s"' % (user, address, TEST, file)
         logging.debug(cmd)
         returncode = 1
         try:
-            stdout,returncode = self.caller.call(cmd)
+            stdout, returncode = self.caller.call(cmd)
         except:
             pass
 
@@ -513,7 +518,7 @@
             logging.debug("exists returning false")
             return False
 
-    def space_test_ssh(self, user, address,dir, file):
+    def space_test_ssh(self, user, address, dir, file):
         """
         Function to test if the given file will fit on the given
         remote directory.  This function will return the available
@@ -525,8 +530,8 @@
         cmd += """ %s%s "%s -c 'import os; dir_stat = os.statvfs(\\"%s\\"); 
print (dir_stat.f_bavail * dir_stat.f_frsize)'" """ % (user, address, PYTHON, 
dir)
         logging.debug('Mount point size test command is (%s)' % cmd)
         try:
-            dir_size,returncode = self.caller.call(cmd)
-        except Exception,e:
+            dir_size, returncode = self.caller.call(cmd)
+        except Exception, e:
             pass
 
         if returncode == 0 and dir_size is not None:
@@ -534,9 +539,9 @@
             dir_size = dir_size.strip()
             file_size = os.path.getsize(file)
             logging.debug("Size of %s:\t%s bytes\t%.1f 1K-blocks\t%.1f MB" %
-                          (file, file_size, file_size/1024, 
(file_size/1024)/1024))
-            logging.debug("Available space in %s:\t%s bytes\t%.1f 
1K-blocks\t%.1f MB"  %
-                          (dir, dir_size, float(dir_size)/1024, 
(float(dir_size)/1024)/1024))
+                          (file, file_size, file_size / 1024, (file_size / 
1024) / 1024))
+            logging.debug("Available space in %s:\t%s bytes\t%.1f 
1K-blocks\t%.1f MB" %
+                          (dir, dir_size, float(dir_size) / 1024, 
(float(dir_size) / 1024) / 1024))
             return (dir_size, file_size)
         else:
             raise Exception("unable to test the available space on %s" % dir)
@@ -560,12 +565,12 @@
         dir_size = (dir_stat.f_bavail * dir_stat.f_frsize)
         file_size = os.path.getsize(file)
         logging.debug("Size of %s:\t%s bytes\t%.1f 1K-blocks\t%.1f MB" %
-                      (file, file_size, file_size/1024, (file_size/1024)/1024))
-        logging.debug("Available space in %s:\t%s bytes\t%.1f 1K-blocks\t%.1f 
MB"  %
-                      (dir, dir_size, dir_size/1024, (dir_size/1024)/1024))
+                      (file, file_size, file_size / 1024, (file_size / 1024) / 
1024))
+        logging.debug("Available space in %s:\t%s bytes\t%.1f 1K-blocks\t%.1f 
MB" %
+                      (dir, dir_size, dir_size / 1024, (dir_size / 1024) / 
1024))
         return (dir_size, file_size)
 
-    def copy_file(self, src_file_name,dest_file_name, uid, gid):
+    def copy_file(self, src_file_name, dest_file_name, uid, gid):
         """
         Copy a file from source to dest via file handles.  The destination
         file will be opened and written to as the UID and GID provided.
@@ -575,7 +580,7 @@
         """
         retVal = True
         logging.debug("euid(%s) egid(%s)" % (os.geteuid(), os.getegid()))
-        umask_save = os.umask(0137) # Set to 660
+        umask_save = os.umask(0137)  # Set to 660
         try:
             src = open(src_file_name, 'r')
             os.setegid(gid)
@@ -594,7 +599,7 @@
             dest.close()
         return retVal
 
-    def rename_file_nfs(self, src_file_name,dest_file_name, uid, gid):
+    def rename_file_nfs(self, src_file_name, dest_file_name, uid, gid):
         """
         Rename a file from source to dest as the UID and GID provided.
         This method will set the euid and egid to that which is provided
@@ -621,8 +626,8 @@
         cmd += """ %s%s "%s %s %s" """ % (user, address, MV, src_file_name, 
dest_file_name)
         logging.debug('Rename file command is (%s)' % cmd)
         try:
-            stdout,returncode = self.caller.call(cmd)
-        except Exception,e:
+            stdout, returncode = self.caller.call(cmd)
+        except Exception, e:
             raise Exception("unable to move file from %s to %s" % 
(src_file_name, dest_file_name))
 
     def remove_file_nfs(self, file_name, uid, gid):
@@ -644,7 +649,7 @@
             os.seteuid(0)
             os.setegid(0)
 
-    def remove_file_ssh(self,user, address, file):
+    def remove_file_ssh(self, user, address, file):
         """
         This method will remove a file via SSH.
         """
@@ -653,8 +658,8 @@
         cmd += """ %s%s "%s %s" """ % (user, address, RM, file)
         logging.debug('Remove file command is (%s)' % cmd)
         try:
-            stdout,returncode = self.caller.call(cmd)
-        except Exception,e:
+            stdout, returncode = self.caller.call(cmd)
+        except Exception, e:
             raise Exception("unable to remove %s" % file)
 
     def refresh_iso_domain(self, id):
@@ -669,8 +674,8 @@
             sd = self.api.storagedomains.get(id=id)
             if sd is not None and sd.files is not None:
                 sd.files.list()
-        except Exception,e:
-            logging.warn(_("failed to refresh the list of files available in 
the %s ISO storage domain. Please refresh the list manually using the 'Refresh' 
button in the oVirt Webadmin console."  %
+        except Exception, e:
+            logging.warn(_("failed to refresh the list of files available in 
the %s ISO storage domain. Please refresh the list manually using the 'Refresh' 
button in the oVirt Webadmin console." %
                            self.configuration.get('iso_domain')))
             logging.debug(e)
 
@@ -688,7 +693,11 @@
         elif self.configuration.get('iso_domain'):
             # Discover the hostname and path from the ISO domain.
             (id, address, path) = 
self.get_host_and_path_from_ISO_domain(self.configuration.get('iso_domain'))
-            remote_path = os.path.join(id,DEFAULT_IMAGES_DIR)
+            if id:
+                remote_path = os.path.join(id, DEFAULT_IMAGES_DIR)
+            else:
+                logging.debug('Unable to get host and path information from 
API.')
+                return
         elif self.configuration.get('nfs_server'):
             mnt = self.configuration.get('nfs_server')
             (address, sep, path) = mnt.partition(':')
@@ -746,11 +755,11 @@
                             logging.error(_('There is not enough space in %s 
(%s bytes) for %s (%s bytes)' %
                                             (path, dir_size, file, file_size)))
                     else:
-                        ExitCodes.exit_code=ExitCodes.UPLOAD_ERR
+                        ExitCodes.exit_code = ExitCodes.UPLOAD_ERR
                         logging.error(_('%s exists on %s.  Either remove it or 
supply the --force option to overwrite it.')
-                                      % (file,address))
+                                      % (file, address))
                 except Exception, e:
-                        ExitCodes.exit_code=ExitCodes.UPLOAD_ERR
+                        ExitCodes.exit_code = ExitCodes.UPLOAD_ERR
                         logging.error(_('Unable to copy %s to ISO storage 
domain on %s.'
                                         % (file,
                                            
self.configuration.get('iso_domain'))))
@@ -764,15 +773,15 @@
                 self.caller.call(cmd)
                 passwd = getpwnam(NFS_USER)
                 for file in self.configuration.files:
-                    dest_dir = os.path.join(tmpDir,remote_path)
+                    dest_dir = os.path.join(tmpDir, remote_path)
                     dest_file = os.path.join(dest_dir, os.path.basename(file))
-                    retVal = self.exists_nfs(dest_file,NUMERIC_VDSM_ID, 
NUMERIC_VDSM_ID)
+                    retVal = self.exists_nfs(dest_file, NUMERIC_VDSM_ID, 
NUMERIC_VDSM_ID)
                     if conf.get('force') or not retVal:
                         try:
                             # Remove the file if it exists before checking 
space.
                             if retVal:
                                 self.remove_file_nfs(dest_file, 
NUMERIC_VDSM_ID, NUMERIC_VDSM_ID)
-                            (dir_size, file_size) = 
self.space_test_nfs(dest_dir,file, NUMERIC_VDSM_ID, NUMERIC_VDSM_ID)
+                            (dir_size, file_size) = 
self.space_test_nfs(dest_dir, file, NUMERIC_VDSM_ID, NUMERIC_VDSM_ID)
                             if (dir_size > file_size):
                                 temp_dest_file = os.path.join(dest_dir, '.%s' 
% os.path.basename(file))
                                 if self.copy_file(file,
@@ -791,7 +800,7 @@
                                 logging.error(_('There is not enough space in 
%s (%s bytes) for %s (%s bytes)' %
                                               (path, dir_size, file, 
file_size)))
                         except Exception, e:
-                            ExitCodes.exit_code=ExitCodes.UPLOAD_ERR
+                            ExitCodes.exit_code = ExitCodes.UPLOAD_ERR
                             logging.error(_('Unable to copy %s to ISO storage 
domain on %s.'
                                             % (file,
                                                
self.configuration.get('iso_domain') if
@@ -799,18 +808,18 @@
                                                  
self.configuration.get('nfs_server'))))
                             logging.error(_('Error message is "%s"') % 
str(e).strip())
                     else:
-                        ExitCodes.exit_code=ExitCodes.UPLOAD_ERR
+                        ExitCodes.exit_code = ExitCodes.UPLOAD_ERR
                         logging.error(_('%s exists on %s.  Either remove it or 
supply the --force option to overwrite it.')
-                                      % (file,address))
+                                      % (file, address))
 
             except KeyError, k:
-                ExitCodes.exit_code=ExitCodes.CRITICAL
+                ExitCodes.exit_code = ExitCodes.CRITICAL
                 logging.error(_("A user named %s with a UID and GID of %d must 
be defined on the system to mount the ISO storage domain on %s as Read/Write"
                                 % (NFS_USER,
                                    NUMERIC_VDSM_ID,
                                    self.configuration.get('iso_domain'))))
             except Exception, e:
-                ExitCodes.exit_code=ExitCodes.CRITICAL
+                ExitCodes.exit_code = ExitCodes.CRITICAL
                 logging.error(e)
             finally:
                 try:
@@ -819,7 +828,7 @@
                     self.caller.call(cmd)
                     shutil.rmtree(tmpDir)
                 except Exception, e:
-                    ExitCodes.exit_code=ExitCodes.CLEANUP_ERR
+                    ExitCodes.exit_code = ExitCodes.CLEANUP_ERR
                     logging.debug(e)
 
 if __name__ == '__main__':
@@ -962,7 +971,7 @@
         if conf and (conf.get("verbose")):
             logging.debug(_("Configuration:"))
             logging.debug(_("command: %s") % conf.command)
-            #multilog(logging.debug, pprint.pformat(conf))
+            # multilog(logging.debug, pprint.pformat(conf))
             multilog(logging.debug, traceback.format_exc())
         sys.exit(ExitCodes.CRITICAL)
 


--
To view, visit http://gerrit.ovirt.org/8954
To unsubscribe, visit http://gerrit.ovirt.org/settings

Gerrit-MessageType: newchange
Gerrit-Change-Id: Ib51002532b726cb7becdd4e4289d385119fa1ea3
Gerrit-PatchSet: 1
Gerrit-Project: ovirt-iso-uploader
Gerrit-Branch: master
Gerrit-Owner: Keith Robertson <krobe...@redhat.com>
_______________________________________________
Engine-patches mailing list
Engine-patches@ovirt.org
http://lists.ovirt.org/mailman/listinfo/engine-patches

Reply via email to