def main(): # Check if running as administrator if not isAdmin(): sys.exit('error: Administrator permission required') # Define options parser = ArgParser( description='UpdatEngine client allow computer and server to be ' 'inventoried automatically on an UpdatEngine server and to deploy applications' ) parser.add_argument('-s', '--server', dest='server', type=str, help='UpdatEngine server URL') group = parser.add_mutually_exclusive_group() group.add_argument('-i', '--inventory', dest='inventory', action='store_true', help='to inventory the host') parser.add_argument('-n', '--noproxy', dest='noproxy', action='store_true', help='do not use any proxy') parser.add_argument('-m', '--minutes', dest='minute', type=int, help='minute between each inventory') parser.add_argument('-c', '--cert', dest='cert', type=str, help='absolute path to cacert.pem file') group.add_argument('-l', '--list', dest='list', action='store_true', help='to get public soft list') group.add_argument('-g', '--get', type=int, dest='get', help='package number to install manually') parser.add_argument('-o', '--out', type=str, dest='out', help='full path to logfile') parser.add_argument('-v', '--verbose', dest='verbose', action='store_true', help='verbose mode') parser.add_argument('--version', action='version', version=ueconst.UE_CLIENT_VERSION, help='display version number') options = parser.parse_args() if len(sys.argv) == 1: parser.error('at least one argument is required') if (options.get is not None or options.list is True or options.inventory is True) and options.server is None: parser.error('a server URL is required') # Check options try: if options.out is not None: try: logging.basicConfig(level=logging.DEBUG, filename=options.out) except: logging.basicConfig(level=logging.DEBUG, filename='updatengine-client.log') logging.exception('can\'t write on ' + options.out + ' file use default file instead') else: logging.basicConfig(level=logging.DEBUG, filename='updatengine-client.log') last = False if options.list is True and options.server is not None: logging.info('*********************************\n') localtime = time.localtime() logging.info('Start: ' + time.strftime('%Y-%m-%d-%H:%M:%S', localtime)) print('Public packages software available on server') url = options.server + '/post/' softxml = uecommunication.get_public_software_list(url, options) uecommunication.printable_public_software(softxml) logging.info('List public packages available on server') localtime = time.localtime() logging.info('End: ' + time.strftime('%Y-%m-%d-%H:%M:%S', localtime)) if options.get is not None and options.server is not None: logging.info('*********************************\n') localtime = time.localtime() logging.info('Start: ' + time.strftime('%Y-%m-%d-%H:%M:%S', localtime)) url = options.server + '/post/' print('Trying to install package %d' % options.get) logging.info('Trying to install package %d' % options.get) ue = uedownload() ue.download_pack(url, options.get, options) localtime = time.localtime() logging.info('End: ' + time.strftime('%Y-%m-%d-%H:%M:%S', localtime)) if options.inventory is False and options.list is False and options.get is None: print('Just to test, inventory will not be send') last = True if options.minute is None: last = True download = uedownload() while True: ExitError = False if options.get is not None or options.list is True: break logging.info('*********************************\n') localtime = time.localtime() logging.info('Start: ' + time.strftime('%Y-%m-%d-%H:%M:%S', localtime)) try: inventory = ueinventory.build_inventory() except Exception: print('Error when building inventory') logging.exception('Error when building inventory') ExitError = True else: if inventory is not None: localtime = time.localtime() print(time.strftime('%Y-%m-%d-%H:%M:%S', localtime)) print('Inventory built') logging.info('Inventory built') if options.verbose is True: try: inventory_pretty = inventory[0].replace('&', '&') inventory_pretty = parseXML( inventory_pretty).toprettyxml(indent=' ') logging.info(inventory_pretty + inventory[1]) if len(sys.argv) == 2: print(inventory_pretty) except: logging.info(inventory) if options.inventory is True and options.server is not None: url = options.server + '/post/' try: response_inventory = uecommunication.send_inventory( url, inventory[0], options) except Exception: print('Error on send_inventory process') logging.exception('Error on send_inventory process') ExitError = True else: print('Inventory sent to ' + url) logging.info('Inventory sent to ' + url) if options.verbose is True: print( parseXML(response_inventory).toprettyxml( indent=' ')) uecommunication.print_warninfo(response_inventory) try: extended_inventory = ueinventory.build_extended_inventory( response_inventory) if extended_inventory: if options.verbose is True: extended_pretty = extended_inventory.replace( '&', '&') logging.info( parseXML(extended_pretty).toprettyxml( indent=' ')) response_inventory = uecommunication.send_extended_inventory( url, extended_inventory, options) except Exception: print('Error on extended inventory function') logging.exception( 'Error on extended inventory function') ExitError = True else: if extended_inventory: print('Extended inventory sent to ' + url) logging.info('Extended inventory sent to ' + url) if options.verbose is True: print( parseXML(response_inventory). toprettyxml(indent=' ')) try: download.max_download_action = 5 download.download_action( url, response_inventory, options) except Exception: print('Error on download_action function') logging.exception( 'Error on download_action function') try: # Send a last inventory time.sleep(5) inventory = ueinventory.build_inventory() response_inventory = uecommunication.send_inventory( url, inventory[0], options) except: pass ExitError = True localtime = time.localtime() logging.info('End: ' + time.strftime('%Y-%m-%d-%H:%M:%S', localtime)) if last: if ExitError: sys.exit(1) break else: logging.info('Waiting ' + str(options.minute) + ' minute(s) until next inventory') try: wait(options.minute, inventory[1]) except: logging.exception('Error in wait() function') raise except: logging.exception('Error in main() function') sys.exit(1)
def download_pack(self, url, pack, options ): packxml = uecommunication.get_public_software_list(url, options, pack) try: root = etree.fromstring(packxml) except: print self.xml print "Error reading xml response in download_action" logging.exception("Error reading xml response in download_action") raise try: for pack in root.findall('Package'): try: self.download_print_time() print 'Package: '+pack.find('Name').text logging.info('Package: '+pack.find('Name').text) self.pid = pack.find('Pid').text command = pack.find('Command').text if command.find('download_no_restart') != -1: command = command.replace('\n',' && ') command = command.replace('&& download_no_restart','') command = command.replace('&& section_end','') url = pack.find('Url').text packagesum = pack.find('Packagesum').text except: print "Error in package xml format" logging.exception("Error in package xml format") raise if packagesum != 'nofile': try: tmpdir = tempfile.gettempdir()+'/updatengine/' if not os.path.exists(tmpdir): os.makedirs(tmpdir) file_name = tmpdir+url.split('/')[-1] self.download_tmp(url,file_name,packagesum) except: self.download_print_time() print 'Error when downloading' + file_name logging.exception("Error when downloading "+file_name) raise else: print 'Install in progress' logging.info('Install in progress') try: os.chdir(tmpdir) subprocess.check_call(command, shell = True) except Exception, inst: print "Error launching action: "+command logging.info("Error launching action: "+command) print type(inst) print inst raise finally: # come back to gettemdir to remove updatengine directory try: os.chdir(tempfile.gettempdir()) shutil.rmtree(tmpdir) except: print 'Can\'t delete temp file' logging.info('Can\'t delete temp file') else: print 'Install in progress' logging.info('Install in progress') try: subprocess.check_call(command, shell = True) except Exception, inst: print "Error launching action: "+command logging.info("Error launching action: "+command) print type(inst) print inst raise self.download_print_time() print "Operation completed" logging.info("Operation completed") time.sleep(5)
def main(): # Define options parser = optparse.OptionParser("usage: %prog [options] arg1 arg2") parser.add_option("-s", "--server", dest="server", \ type="string", help="Your UpdatEngine server IP or DNS name") parser.add_option("-i", "--inventory", dest="inventory", \ action="store_false", help="Port of your UpdatEngine server") parser.add_option("-v", "--verbose", dest="verbose", \ action="store_false", help="Verbose mode") parser.add_option("-n", "--noproxy", dest="noproxy", \ action="store_false", help="do not use any proxy") parser.add_option("-m", "--minutes", dest="minute", \ type="int", help="Minute between each inventory") parser.add_option("-c", "--cert", dest="cert", \ type="string", help="Absolute path to cacert.pem file") parser.add_option("-l", "--list", dest="list", \ action="store_false", help="To get public soft list") parser.add_option("-g", "--get", type = "int", dest="get", \ help="Package number to install manualy") parser.add_option("-o", "--out", type = "string", dest="out", \ help="Full path to logfile") (options, args) = parser.parse_args() if options.out is not None: try: logging.basicConfig(level=logging.DEBUG, filename=options.out) except: logging.basicConfig(level=logging.DEBUG, filename='updatengine-client.log') logging.exception("can't write on "+options.out+" file use default file instead") else: logging.basicConfig(level=logging.DEBUG, filename='updatengine-client.log') last = False if options.list is not None and options.server is not None: logging.info("*********************************\n") localtime = time.localtime() logging.info("Start: "+ time.strftime("%Y-%m-%d-%H:%M:%S", localtime)) print "Public packages software available on server\n" url = options.server+'/post/' softxml = uecommunication.get_public_software_list(url, options) uecommunication.printable_public_software(softxml) logging.info("List public packages available on server") localtime = time.localtime() logging.info("End: "+ time.strftime("%Y-%m-%d-%H:%M:%S", localtime)) raw_input("Press Enter to Exit") if options.get is not None and options.server is not None: logging.info("*********************************\n") localtime = time.localtime() logging.info("Start: "+ time.strftime("%Y-%m-%d-%H:%M:%S", localtime)) url = options.server+'/post/' print "Will install package Number: %d \n" % options.get logging.info("Launch manual install of "+ str(options.get) +" package") ue = uedownload() ue.download_pack(url, options.get, options) raw_input("Operation finished, press Enter to Exit") localtime = time.localtime() logging.info("End: "+ time.strftime("%Y-%m-%d-%H:%M:%S", localtime)) if options.inventory is None and options.list is None and options.get is None: print "Just to test, inventory will not be send" last = True if options.minute is None: last = True download = uedownload() while True: if options.get is not None or options.list is not None: break logging.info("*********************************\n") localtime = time.localtime() logging.info("Start: "+ time.strftime("%Y-%m-%d-%H:%M:%S", localtime)) try: inventory = ueinventory.build_inventory() except Exception: print "Error when building inventory" logging.exception("Error when building inventory") else: if inventory is not None: localtime = time.localtime() print time.strftime("%Y-%m-%d-%H:%M:%S", localtime) print "Inventory built" logging.info("Inventory built") if options.verbose is not None: logging.info(inventory) if options.inventory is not None and options.server is not None: url = options.server+'/post/' try: response_inventory = uecommunication.send_inventory(url, inventory[0], options) except Exception: print "Error on send_inventory process" logging.exception("Error on send_inventory process") else: print "Inventory sent to "+url logging.info("Inventory sent to "+url) if options.verbose is not None: print response_inventory try: download.download_action(url, str(response_inventory), options) except Exception: print "Error on download_action function" logging.exception("Error on download_action function") localtime = time.localtime() logging.info("End: "+ time.strftime("%Y-%m-%d-%H:%M:%S", localtime)) if last: break else: logging.info("Waiting "+str(options.minute)+" minute(s) until next inventory\n") wait(options.minute, inventory[1])
def download_pack(self, url, pack, options): packxml = uecommunication.get_public_software_list(url, options, pack) try: root = etree.fromstring(packxml) except: print(self.xml) print('Error reading xml response in download_action') logging.exception('Error reading xml response in download_action') raise try: if not root.findall('Package'): print('Package ' + str(pack) + ' not found') logging.info('Package ' + str(pack) + ' not found') for pack in root.findall('Package'): try: self.download_print_time() print('Package: ' + pack.find('Name').text) logging.info('Package: ' + pack.find('Name').text) self.pid = pack.find('Pid').text command = pack.find('Command').text option_timeout = 'install_timeout_' self.timeout = self.default_timeout if command.find(option_timeout) != -1: match = re.search(option_timeout + '(.+?)(\r?\n|$)', command) try: option_timeout += match.group(1) command_value = int(match.group(1)) if command_value > 0: self.timeout = command_value except: logmsg = 'Ignoring invalid option \'' + option_timeout + '\'' print(logmsg) logging.warning(logmsg) command = re.sub( "\n\s*\n*", " && ", command) # Remove blank lines and convert \n to && command = command.replace(' && download_no_restart', '') command = command.replace(' && no_break_on_error', '') command = command.replace(' && section_end', '') # for retro compatibility command = command.replace(' && ' + option_timeout, '') url = pack.find('Url').text packagesum = pack.find('Packagesum').text except: print('Error in package xml format') logging.exception('Error in package xml format') raise logging.info('Ready to download and execute (manually)') if packagesum != 'nofile': try: self.tmpdir = tempfile.gettempdir( ) + '/updatengine/' + next( tempfile._get_candidate_names()) + "/" if not os.path.exists(self.tmpdir): os.makedirs(self.tmpdir) file_name = self.tmpdir + url.split('/')[-1] self.download_tmp(url, file_name, packagesum) except: self.download_print_time() print('Error when downloading: ' + file_name) logging.exception('Error when downloading: ' + file_name) raise else: print('Install in progress') logging.info('Install in progress') try: os.chdir(self.tmpdir) p = subprocess.Popen(command, stderr=subprocess.PIPE, shell=True) retcode = p.wait(timeout=self.timeout) if retcode != 0: raise Exception(retcode) except subprocess.TimeoutExpired: p.kill() err = "Timeout expired" print('Error launching action: ' + err) logging.exception('Error launching action: ' + err) raise except Exception as e: import locale console_encoding = locale.getpreferredencoding() if console_encoding == 'cp1252': console_encoding = 'cp850' err = [ s.strip().decode(console_encoding) for s in p.stderr.readlines() ] err = ' '.join(err) if len(err): err = err[:450] + ( '...' if len(err) > 450 else '') + " | Exit code " + str(e) else: err = "Exit code " + str(e) print('Error launching action: ' + str(err)) logging.exception('Error launching action: ' + err) raise finally: try: os.chdir(tempfile.gettempdir()) shutil.rmtree(tempfile.gettempdir() + '/updatengine/') except: print('Can\'t delete temp file') logging.info('Can\'t delete temp file') else: print('Install in progress') logging.info('Install in progress') try: p = subprocess.Popen(command, stderr=subprocess.PIPE, shell=True) retcode = p.wait(timeout=self.timeout) if retcode != 0: raise Exception(retcode) except subprocess.TimeoutExpired: p.kill() err = "Timeout expired" print('Error launching action: ' + err) logging.exception('Error launching action: ' + err) raise except Exception as e: import locale console_encoding = locale.getpreferredencoding() if console_encoding == 'cp1252': console_encoding = 'cp850' err = [ s.strip().decode(console_encoding) for s in p.stderr.readlines() ] err = ' '.join(err) if len(err): err = err[:450] + ('...' if len(err) > 450 else '') + " | Exit code " + str(e) else: err = "Exit code " + str(e) print('Error launching action: ' + str(err)) logging.exception('Error launching action: ' + err) raise self.download_print_time() print('Operation completed') logging.info('Operation completed') except: print('Error detected when launching download_action') logging.info('Error detected when launching download_action') raise
def download_pack(self, url, pack, options): packxml = uecommunication.get_public_software_list(url, options, pack) try: root = etree.fromstring(packxml) except: print self.xml print "Error reading xml response in download_action" logging.exception("Error reading xml response in download_action") raise try: for pack in root.findall('Package'): try: self.download_print_time() print 'Package: ' + pack.find('Name').text logging.info('Package: ' + pack.find('Name').text) self.pid = pack.find('Pid').text command = pack.find('Command').text if command.find('download_no_restart') != -1: command = command.replace('\n', ' && ') command = command.replace('&& download_no_restart', '') command = command.replace('&& section_end', '') url = pack.find('Url').text packagesum = pack.find('Packagesum').text except: print "Error in package xml format" logging.exception("Error in package xml format") raise if packagesum != 'nofile': try: tmpdir = tempfile.gettempdir() + '/updatengine/' if not os.path.exists(tmpdir): os.makedirs(tmpdir) file_name = tmpdir + url.split('/')[-1] self.download_tmp(url, file_name, packagesum) except: self.download_print_time() print 'Error when downloading' + file_name logging.exception("Error when downloading " + file_name) raise else: print 'Install in progress' logging.info('Install in progress') try: os.chdir(tmpdir) subprocess.check_call(command, shell=True) except Exception, inst: print "Error launching action: " + command logging.info("Error launching action: " + command) print type(inst) print inst raise finally: # come back to gettemdir to remove updatengine directory try: os.chdir(tempfile.gettempdir()) shutil.rmtree(tmpdir) except: print 'Can\'t delete temp file' logging.info('Can\'t delete temp file') else: print 'Install in progress' logging.info('Install in progress') try: subprocess.check_call(command, shell=True) except Exception, inst: print "Error launching action: " + command logging.info("Error launching action: " + command) print type(inst) print inst raise self.download_print_time() print "Operation completed" logging.info("Operation completed") time.sleep(5)