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)
Example #2
0
             print 'Operation completed'
             self.download_print_time()
             self.download_send_status('Operation completed')
             logging.info("Operation completed")
             time.sleep(5)
     except:
         print "Error detected when launching download_action"
         logging.exception("Error detected when lauching download_action")
         raise
     else:   
         # Loop download action
         if download_launch:
             try:
                 print "End of download and install "
                 self.download_print_time()
                 inventory = ueinventory.build_inventory()
                 response_inventory = uecommunication.send_inventory(self.urlinv, inventory[0], options)
                 # Break download action if an error occured during a previous install
                 if break_download_action == None:
                     self.download_action(self.urlinv,str(response_inventory),options)
             except:
                 print "Error in loop download action"
                 logging.exception("Error in loop download action")
 
 
 
 def download_send_status(self,message):
     try:
         header = '<Packstatus><Mid>'+self.mid+'</Mid><Pid>'+self.pid+'</Pid><Status>'
         tail = '</Status></Packstatus>'
         full_message = header + message + tail
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_action(self, url, xml, options=None):
        self.urlinv = url
        self.xml = xml
        self.options = options
        try:
            root = etree.fromstring(self.xml)
        except:
            print(self.xml)
            print('Error reading xml response in download_action')
            logging.info('Error reading xml response in download_action')
            raise
        # download_launch is used to know if a download action append
        download_launch = None
        self.max_download_action -= 1
        try:
            # Install packages
            for pack in root.findall('Package'):
                try:
                    command = pack.find('Command').text
                    if command.find('download_no_restart'
                                    ) != -1 and self.max_download_action < 4:
                        continue
                    self.download_print_time()
                    print('Package: ' + pack.find('Name').text)
                    logging.info('Package: ' + pack.find('Name').text)
                    self.mid = pack.find('Id').text
                    self.pid = pack.find('Pid').text
                    no_break_on_error = None
                    if command.find('no_break_on_error') != -1:
                        no_break_on_error = True
                    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)
                            self.download_send_status(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
                    download_launch = True
                    status_msg = True
                except:
                    print('Error in package xml format')
                    logging.exception('Error in package xml format')
                    raise

                self.download_send_status('Ready to download and execute')
                logging.info('Ready to download and execute')

                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)
                        self.download_send_status('Error downloading file ' +
                                                  file_name)
                        logging.exception('Error when downloading: ' +
                                          file_name)
                        raise
                    else:
                        print('Install in progress')
                        logging.info('Install in progress')
                        self.download_send_status('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)
                            self.download_send_status(
                                'Error launching action: ' + err)
                            logging.exception('Error launching action: ' + err)
                            if no_break_on_error is True:
                                status_msg = None
                            else:
                                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))
                            self.download_send_status(
                                'Error launching action: ' + err)
                            logging.exception('Error launching action: ' + err)
                            if no_break_on_error is True:
                                status_msg = None
                            else:
                                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')
                    self.download_send_status('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)
                        self.download_send_status('Error launching action: ' +
                                                  err)
                        logging.exception('Error launching action: ' + err)
                        if no_break_on_error is True:
                            status_msg = None
                        else:
                            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))
                        self.download_send_status('Error launching action: ' +
                                                  err)
                        logging.exception('Error launching action: ' + err)
                        if no_break_on_error is True:
                            status_msg = None
                        else:
                            raise

                if status_msg is True:
                    self.download_print_time()
                    print('Operation completed')
                    self.download_send_status('Operation completed')
                    logging.info('Operation completed')

            if not root.findall('Package'):
                print('Done, no package to install')
                logging.info('Done, no package to install')
        except:
            print('Error detected when launching download_action')
            logging.exception('Error detected when lauching download_action')
            raise
        else:
            # Loop download action
            if download_launch:
                try:
                    self.download_print_time()
                    if self.max_download_action == 0:
                        print('End of download and install')
                    else:
                        print('Perform a new check')
                    time.sleep(5)
                    inventory = ueinventory.build_inventory()
                    response_inventory = uecommunication.send_inventory(
                        self.urlinv, inventory[0], options)
                    extended_inventory = ueinventory.build_extended_inventory(
                        response_inventory)
                    if extended_inventory:
                        response_inventory = uecommunication.send_extended_inventory(
                            self.urlinv, extended_inventory, options)
                    if self.max_download_action > 0:
                        self.download_action(self.urlinv, response_inventory,
                                             options)
                except:
                    print('Error in loop download action')
                    logging.exception('Error in loop download action')
Example #5
0
                print 'Operation completed'
                self.download_print_time()
                self.download_send_status('Operation completed')
                logging.info("Operation completed")
                time.sleep(5)
        except:
            print "Error detected when launching download_action"
            logging.exception("Error detected when lauching download_action")
            raise
        else:
            # Loop download action
            if download_launch:
                try:
                    print "End of download and install "
                    self.download_print_time()
                    inventory = ueinventory.build_inventory()
                    response_inventory = uecommunication.send_inventory(
                        self.urlinv, inventory[0], options)
                    # Break download action if an error occured during a previous install
                    if break_download_action == None:
                        self.download_action(self.urlinv,
                                             str(response_inventory), options)
                except:
                    print "Error in loop download action"
                    logging.exception("Error in loop download action")

    def download_send_status(self, message):
        try:
            header = '<Packstatus><Mid>' + self.mid + '</Mid><Pid>' + self.pid + '</Pid><Status>'
            tail = '</Status></Packstatus>'
            full_message = header + message + tail