def remove_all_cleanup_files(signal, rc=0, *args): # This function deletes all files in the cleanup_file_list. This function is # always the first thing pushed onto the cleanup stack, so that it will occur # if the program exits erroneously. It is also called by gen_exit_function. # # The programmer can populate this list with # gexit.add_cleanup_file(file_name) # or # gexit.cleanup_file_list.append(file_name) if not g.quiet: gprint.print_func_name() global cleanup_file_list # The main cleanup loop. while cleanup_file_list != []: cleanup_file = cleanup_file_list.pop() try: # Try deleting the file. os.remove(filename) except OSError: # File deletion failed for some reason. if not quiet_del: g.print_error("Cannot delete file " + filename + ".") rc = 1 return rc
def process_error_message(): # This may be added in later. This is the last gen_bash_print_funcs to # convert. g.print_error("process_error_message is not implemented.") pass
def gen_func_cleanup(signo, rc=0): # This function is designed to execute when a SIGINT or SIGTERM occurs. It # will go through a global function stack, executing and popping each one in # turn, before finally exiting the program with a given return code. # # Each cleanup function needs to be capable of accepting signo and rc as # defined parameters, as well as one last *args parameter that may contain # something or nothing. global global_cleanup_stack global saved_signal_list # Save the current signal set. if saved_signal_list == []: saved_signal_list = gsig.save_signals() else: g.print_error( "Possible programmer error. Attempting to save signals to saved_signal_list in gen_func_cleanup, but signals have already been saved." ) # We're going to start by capturing and ignoring SIGINT and SIGTERM, so they # don't ruin our cleanup functions. signal.signal(signal.SIGINT, gsig.ignore_signals) signal.signal(signal.SIGTERM, gsig.ignore_signals) # Pop off all the functions in the global_cleanup_stack. while global_cleanup_stack != []: pop_cleanup_func(signo, rc) # Restore the previously saved signal set. gsig.restore_signals(saved_signal_list) # Now exit, which we wanted to do in the first place. sys.exit(rc)
def remove_all_cleanup_files(signal,rc=0,*args): # This function deletes all files in the cleanup_file_list. This function is # always the first thing pushed onto the cleanup stack, so that it will occur # if the program exits erroneously. It is also called by gen_exit_function. # # The programmer can populate this list with # gexit.add_cleanup_file(file_name) # or # gexit.cleanup_file_list.append(file_name) if not g.quiet: gprint.print_func_name() global cleanup_file_list # The main cleanup loop. while cleanup_file_list != []: cleanup_file = cleanup_file_list.pop() try: # Try deleting the file. os.remove(filename) except OSError: # File deletion failed for some reason. if not quiet_del: g.print_error("Cannot delete file " + filename + ".") rc = 1 return rc
def gen_timeout_function(timeout, func, *args, **kwargs): # This function is used as a way to add timeout to a function when the # timeout value will not be known until runtime. It will return None if the # timeout occurred, or the function's return value otherwise. # Error check. try: timeout = int(timeout) except ValueError: g.print_error(str(timeout) + ", provided as timeout for " + func.__name__ + " is not a valid timeout value.") return None original_handler = signal.signal(signal.SIGALRM,gen_timeout_handler) signal.alarm(timeout) try: rv = func(*args, **kwargs) except GeneralTimeout: g.print_error("Function " + func.__name__ + " timed out after " + str(timeout) + " seconds.") rv = None signal.alarm(0) signal.signal(signal.SIGALRM,original_handler) return rv
def gen_func_cleanup(signo, rc=0): # This function is designed to execute when a SIGINT or SIGTERM occurs. It # will go through a global function stack, executing and popping each one in # turn, before finally exiting the program with a given return code. # # Each cleanup function needs to be capable of accepting signo and rc as # defined parameters, as well as one last *args parameter that may contain # something or nothing. global global_cleanup_stack global saved_signal_list # Save the current signal set. if saved_signal_list == []: saved_signal_list = gsig.save_signals() else: g.print_error("Possible programmer error. Attempting to save signals to saved_signal_list in gen_func_cleanup, but signals have already been saved.") # We're going to start by capturing and ignoring SIGINT and SIGTERM, so they # don't ruin our cleanup functions. signal.signal(signal.SIGINT, gsig.ignore_signals) signal.signal(signal.SIGTERM, gsig.ignore_signals) # Pop off all the functions in the global_cleanup_stack. while global_cleanup_stack != []: pop_cleanup_func(signo, rc) # Restore the previously saved signal set. gsig.restore_signals(saved_signal_list) # Now exit, which we wanted to do in the first place. sys.exit(rc)
def release_signals(reraise=True): # This function restores all the old signal handlers of signals that were # trapped by trap_signal. If reraise is True, then all of the signals are # re-raised in turn; otherwise, the signals are discarded. global global_trapped_signals global global_received_signals # Restore signal handlers. for signo, handler in global_trapped_signals: try: signal.signal(signo, handler) except RuntimeError: g.print_error( "Cannot release signal " + str(signo) + ". Python does not allow this signal handler to be changed.") global_trapped_signals = [] # We need to copy the list of received signals into another list, or else # it's never actually going to be cleared, since we're firing off signals # and all that. local_received_signals = list(global_received_signals) global_received_signals = [] # Re-raise received signals. if reraise: for sig in local_received_signals: os.kill(g.system_parms["pid"], sig) return 0
def time_wrapped_func(timeout_arg, *args, **kwargs): # Test our timeout_arg in a scope where we know the function name. try: timeout_int = int(timeout_arg) except ValueError: g.print_error( "Programmer error: function " + func.__name__ + " decorated with invalid timeout value in gen_timeout_decorator." ) return None original_handler = signal.signal(signal.SIGALRM, gen_timeout_handler) signal.alarm(timeout_int) try: rv = func(*args, **kwargs) except GeneralTimeout: g.print_error("Function " + func.__name__ + " timed out after " + str(timeout_int) + " seconds.") rv = None signal.alarm(0) signal.signal(signal.SIGALRM, original_handler) return rv
def gen_timeout_function(timeout, func, *args, **kwargs): # This function is used as a way to add timeout to a function when the # timeout value will not be known until runtime. It will return None if the # timeout occurred, or the function's return value otherwise. # Error check. try: timeout = int(timeout) except ValueError: g.print_error( str(timeout) + ", provided as timeout for " + func.__name__ + " is not a valid timeout value.") return None original_handler = signal.signal(signal.SIGALRM, gen_timeout_handler) signal.alarm(timeout) try: rv = func(*args, **kwargs) except GeneralTimeout: g.print_error("Function " + func.__name__ + " timed out after " + str(timeout) + " seconds.") rv = None signal.alarm(0) signal.signal(signal.SIGALRM, original_handler) return rv
def release_signals(reraise=True): # This function restores all the old signal handlers of signals that were # trapped by trap_signal. If reraise is True, then all of the signals are # re-raised in turn; otherwise, the signals are discarded. global global_trapped_signals global global_received_signals # Restore signal handlers. for signo, handler in global_trapped_signals: try: signal.signal(signo, handler) except RuntimeError: g.print_error("Cannot release signal " + str(signo) + ". Python does not allow this signal handler to be changed.") global_trapped_signals = [] # We need to copy the list of received signals into another list, or else # it's never actually going to be cleared, since we're firing off signals # and all that. local_received_signals = list(global_received_signals) global_received_signals = [] # Re-raise received signals. if reraise: for sig in local_received_signals: os.kill(g.system_parms["pid"], sig) return 0
def add_bool_flag(flagname, default_val=False, alt_var=None): # Create an argument-free option flag. # Creates a boolean variable associated with the flag. # Using this flag on the command line sets the value of var to the opposite of # default_val. global boolopts # Convert the default value to 0 or 1. default_val = bool_convert(default_val) # Create a new variable in global_vars and assign its value. var = flagname if alt_var != None: var = str(alt_var) g.global_vars[var] = default_val # Add it to our options list. retval, flagstr = add_opt_flag(flagname, False) if retval == 1: g.print_error("Option " + flagname + " already exists in program, cannot be added again.") return 1 boolopts += [[flagstr, var, default_val, False]] return 0
def valid_write_dir(dir_path): # This function returns True if dir_path is an existing directory and can be # written to. if not os.path.isdir(dir_path): g.print_error("Directory \"" + dir_path + "\" does not exist.") return False elif not os.access(dir_path, os.W_OK | os.X_OK): g.print_error("Directory \"" + dir_path + "\" is not writeable for your userid.") return False return True
def get_status_file_start_end_time(file_path, use_end_time_entry=True): # This function looks through a provided status file, obtaining the earliest # and latest time stamps from it. If use_end_time_entry is False, the # modification time of the file is used instead. date_re = re.compile(valid_status_date_regex) start_time = None end_time = None # Open up the file for reading. try: fd = open(file_path,"r") # Look through every line for a date timestamp, and place that into # start_time. for line in fd: date_match = date_re.match(line) if date_match != None: start_time = date_match.string[date_match.start():date_match.end()] break # If we didn't find any timestamps at all, then we need to use the # modification time for both the start and end. if start_time == None: use_end_time_entry = False # Now get the ending time stamp. The first way is to look through the file # some more, recording every instance, so the last one is saved. if use_end_time_entry: for line in fd: date_match = date_re.match(line) if date_match != None: end_time = date_match.string[date_match.start():date_match.end()] # In case we're using the modification time instead. else: modtime = os.path.getmtime(file_path) end_time = seconds_to_date(modtime) except: g.print_error("Error reading data from \"" + file_path + "\".") return (None, None) # With the file read, we make our final decisions about what to do. By this # point, one of these two variables has to be set. if start_time == None: start_time = end_time elif end_time == None: end_time = start_time return (start_time, end_time)
def time_wrapped_func(*args, **kwargs): original_handler = signal.signal(signal.SIGALRM,gen_timeout_handler) signal.alarm(timeout_int) try: rv = func(*args, **kwargs) except GeneralTimeout: g.print_error("Function " + func.__name__ + " timed out after " + str(timeout_int) + " seconds.") rv = None signal.alarm(0) signal.signal(signal.SIGALRM,original_handler) return rv
def change_signal(signo, newhandler, siglist): # This function will change the handler of signo to newhandler, storing the # old handler in siglist. The main advantage of using this function over # signal.signal is that if you're changing the handler of many different # signals, you can use restore_signals to change them all back at once. try: original_handler = signal.signal(signo, newhandler) siglist.append((signo, original_handler)) except RuntimeError: g.print_error("Cannot trap signal " + str(signo) + ". Python does not allow this signal handler to be changed.") return siglist
def print_opt(optname, desc, exvals="", default=True, loc_col1_indent=2, loc_col1_width=33): # This function automatically prints out help information for a given option. # exvals allows the programmer to specify example values for the option; if # the option was specified as boolean by using add_bool_option, <y/n> will # be printed automatically unless another value is passed in. Setting default # to False will suppress the printout of the default value. # First we search for the parameter name in our list. If it's not there, throw # an error. option = opt_search(optname) if option == None: g.print_error("Programmer error: attempting to print help for option " + optname + " but this option does not exist.") return 1 # Determine what kind of option this is, by its length. is_bool = len(option) == 4 is_var = len(option) == 3 is_func = len(option) == 2 # Get the appropriate data out of the thing. flag = option[0] if is_func: default_val = "" default = False else: default_val = option[2] # Add example values, if necessary. if exvals != "": flag += "=<" + exvals + ">" elif is_bool: flag += "=<y/n>" descfooter = "" # Print out the default value, if necessary. if default: if is_bool: if default_val == 0: descfooter += " The default value is \"n\"." else: descfooter += " The default value is \"y\"." else: descfooter += " The default value is \"" + str(default_val) + "\"." format_string = "%" + str(loc_col1_indent) + "s%-" + str(loc_col1_width) + "s%s" print format_string % ("", flag, desc + descfooter) return 0
def add_func_flag(flagname, func): # Creates an argument-free option flag. # Associates a function with this flag, to be executed if the flag is present. global funcopts # Add it to our options list. There's no variable to assign since there's no # single value to store. retval, flagstr = add_opt_flag(flagname, False) if retval == 1: g.print_error("Option " + flagname + " already exists in program, cannot be added again.") return 1 funcopts += [[flagstr, func]] return 0
def change_signal(signo, newhandler, siglist): # This function will change the handler of signo to newhandler, storing the # old handler in siglist. The main advantage of using this function over # signal.signal is that if you're changing the handler of many different # signals, you can use restore_signals to change them all back at once. try: original_handler = signal.signal(signo, newhandler) siglist.append((signo, original_handler)) except RuntimeError: g.print_error( "Cannot trap signal " + str(signo) + ". Python does not allow this signal handler to be changed.") return siglist
def read_obj(self, file_path=None, validate=True): # This function will look through a file and prepare for reading the file # into this object. The actual reading in of data needs to be handled by # each subclass of GenPythonObject, but they can call this superclass # function to handle some of the validation. That's less typing for us. if file_path == None: file_path = "/tmp/" + g.system_parms["username"] + "/" + self.obj_name if validate: if not os.path.isfile(file_path): g.print_error(file_path + " is not a valid file.") return None return file_path
def read_obj(self, file_path=None, validate=True): # This function will look through a file and prepare for reading the file # into this object. The actual reading in of data needs to be handled by # each subclass of GenPythonObject, but they can call this superclass # function to handle some of the validation. That's less typing for us. if file_path == None: file_path = "/tmp/" + g.system_parms[ "username"] + "/" + self.obj_name if validate: if not os.path.isfile(file_path): g.print_error(file_path + " is not a valid file.") return None return file_path
def time_wrapped_func(*args, **kwargs): original_handler = signal.signal(signal.SIGALRM, gen_timeout_handler) signal.alarm(timeout_int) try: rv = func(*args, **kwargs) except GeneralTimeout: g.print_error("Function " + func.__name__ + " timed out after " + str(timeout_int) + " seconds.") rv = None signal.alarm(0) signal.signal(signal.SIGALRM, original_handler) return rv
def time_wrapped_func(timeout_arg, *args, **kwargs): # Test our timeout_arg in a scope where we know the function name. try: timeout_int = int(timeout_arg) except ValueError: g.print_error("Programmer error: function " + func.__name__ + " decorated with invalid timeout value in gen_timeout_decorator.") return None original_handler = signal.signal(signal.SIGALRM,gen_timeout_handler) signal.alarm(timeout_int) try: rv = func(*args, **kwargs) except GeneralTimeout: g.print_error("Function " + func.__name__ + " timed out after " + str(timeout_int) + " seconds.") rv = None signal.alarm(0) signal.signal(signal.SIGALRM,original_handler) return rv
def add_var_option(flagname, default_val=None, alt_var=None): # Creates an argument-accepting option flag. # Creates a general variable associated with the flag. global varopts # Create a new variable in global_vars and assign its value. var = flagname if alt_var != None: var = str(alt_var) g.global_vars[var] = default_val # Add it to our options list. retval, flagstr = add_opt_flag(flagname, True) if retval == 1: g.print_error("Option " + flagname + " already exists in program, cannot be added again.") return 1 varopts += [[flagstr, var, default_val]] return 0
def trap_signal(signo): # This function will change the signal handler of the provided signal, so that # it will be sent to trap_signal_handler and added to whatever list we're # storing signals in. We store the signal number along with its original # handler, so it can be restored later. # # Only use this function if you want to block all signals and then reuse or # discard them later. If you just want to easily change a signal handler, # use change_signal. global global_trapped_signals try: original_handler = signal.signal(signo, trap_signal_handler) global_trapped_signals.append((signo, original_handler)) except RuntimeError: g.print_error("Cannot trap signal " + str(signo) + ". Python does not allow this signal handler to be changed.") return 1 return 0
def print_parm(paramname, desc, exvals="", default=True, loc_col1_indent=2, loc_col1_width=33): # This function automatically prints out help information for a given # parameter. exvals allows the programmer to specify example values for the # parameter. Setting default to False will suppress the printout of the # default value. The program automatically determines the number of arguments # it takes, and whether or not it's optional. # First we search for the parameter name in our list. If it's not there, throw # an error. parm, opt = parm_search(paramname) if parm == None: g.print_error("Programmer error: attempting to print help for parameter " + paramname + " but this parameter does not exist.") return 1 # Add example values, if necessary. if exvals != "": paramname += " (ex: " + exvals + ")" descheader = "" # Is the parameter optional? # if opt: # descheader += "Optional. " # Does this parameter take multiple arguments? if parm[1] == 0: descheader += "Takes all remaining arguments in the command line. " elif parm[1] != 1: descheader += "Takes " + str(parm[1]) + " arguments. " descfooter = "" # Print out the default value, if necessary. if default: descfooter += " The default value is \"" + str(parm[2]) + "\"." format_string = "%" + str(loc_col1_indent) + "s%-" + str(loc_col1_width) + "s%s" print format_string % ("", paramname, descheader + desc + descfooter) return 0
def remove_cleanup_file(filename, quiet_del=False): # This function will search through the cleanup_file_list for the given # filename. If it exists, the file is deleted from the system and then # removed from the list. If the file is not in the cleanup list for some # reason, it is not deleted from the system as a failsafe. global cleanup_file_list # First, we should check to see if the file is in our list. If not, no big # deal. Just move on. try: cleanup_file_list.remove(filename) except ValueError: # The file wasn't in our list. if not quiet_del: print_time("File " + filename + " not found in cleanup list.") # Next, we should check to see if the file exists at all. If not, then that # counts as success, because it's possible an earlier attempt at this # function deleted it. if not os.path.isfile(filename): if not quiet_del: print_time("Attempted to delete file " + filename + " but the file does not exist. Proceeding with script.") return 0 # If the file does exist, try to delete it. If we fail to, return a # failure. try: os.remove(filename) except OSError: # The file was in our list, but we failed to delete it for some reason. if not quiet_del: g.print_error("Cannot delete file " + filename + ".") return 1 return 0
def trap_signal(signo): # This function will change the signal handler of the provided signal, so that # it will be sent to trap_signal_handler and added to whatever list we're # storing signals in. We store the signal number along with its original # handler, so it can be restored later. # # Only use this function if you want to block all signals and then reuse or # discard them later. If you just want to easily change a signal handler, # use change_signal. global global_trapped_signals try: original_handler = signal.signal(signo, trap_signal_handler) global_trapped_signals.append((signo, original_handler)) except RuntimeError: g.print_error( "Cannot trap signal " + str(signo) + ". Python does not allow this signal handler to be changed.") return 1 return 0
def print_file_attributes(file_var_prefix, file_path, loc_file_var_suffixes=None): g.print_error("print_file_attributes is not implemented.") pass
def comment_help_text(loc_indent, headers): # This function prints out some help text about comments. g.print_error("comment_help_text is not implemented.") pass
def get_file_attributes(file_var_prefix, file_path): g.print_error("get_file_attributes is not implemented.") pass
def extract_date_from_status_line(line): g.print_error("extract_date_from_status_line is not implemented.") # return loc_date pass
def my_read(save_IFS, IFS): g.print_error("my_read is not implemented.") # return read_buffer pass
def directional_egrep(file_path, line_num, search_direction): g.print_error("directional_egrep is not implemented.") # return egrep_result pass
def convert_secs_to_dhms(seconds, unit="days", include_units=False): # This function takes a given number of seconds and converts it to another # unit (days, hours, minutes, or just seconds again). If include_units is # true, the unit will be provided at the end of the printed string. The # function returns a string as well as a full unit breakdown in numbers. # 60*60*24 secs_per_day = 86400 # 60*60 secs_per_hour = 3600 total_days = int(seconds) / secs_per_day days_remainder = int(seconds) % secs_per_day total_hours = days_remainder / secs_per_hour hours_remainder = days_remainder % secs_per_hour total_minutes = hours_remainder / 60 total_seconds = hours_remainder % 60 # Instead of a switch statement, which doesn't actually exist in Python, # we will use a dictionary of functions to decide what our output will be. # Case "days". def days_func(): total_time = "%s %s:%s:%s" % (str(total_days).zfill(2), str(total_hours).zfill(2), str(total_minutes).zfill(2), str(total_seconds).zfill(2)) if include_units: if total_days == 1: total_time += " day" else: total_time += " days" return (total_time, total_days, total_hours, total_minutes, total_seconds) # Case "hours". def hours_func(): total_hours += total_days * 24 total_time = "%s:%s:%s" % (str(total_hours).zfill(2), str(total_minutes).zfill(2), str(total_seconds).zfill(2)) if include_units: if total_days == 1: total_time += " hour" else: total_time += " hours" return (total_time, total_hours, total_minutes, total_seconds) # Case "minutes". def minutes_func(): total_hours += total_days * 24 total_minutes += total_hours * 60 total_time = "%s:%s" % (str(total_minutes).zfill(2), str(total_seconds).zfill(2)) if include_units: if total_days == 1: total_time += " minute" else: total_time += " minutes" return (total_time, total_minutes, total_seconds) # Case "seconds". def seconds_func(): total_hours += total_days * 24 total_minutes += total_hours * 60 total_seconds += total_minutes * 60 total_time = "%s" % str(total_seconds).zfill(2) if include_units: if total_days == 1: total_time += " second" else: total_time += " seconds" return (total_time, total_seconds) func_dict = {"days" : days_func, "hours" : hours_func, "minutes" : minutes_func, "seconds" : seconds_func} # Now look up and execute the correct function, then return the value given. try: retvalue = func_dict[unit]() except KeyError: g.print_error("Programmer error. Incorrect unit provided to convert_secs_to_dhms().") return None return retvalue
def exec_cmd( cmd_buf, stat=False, out=False, err=False, time_out=0, max_attempts=1, sleep_time=1, debug=False, bash=False ): # This is an advanced function for executing a string as a command. It has # the capacity to save the output and return it, time the command out, retry # the function and sleep between attempts. The rmt_cmd option has been # removed, as the "rcmd" function now has a "-rrc" flag that will set the # return code automatically. This is less typing for the programmer, so just # do that. # stat: if this is set, an "issuing" message will be printed prior to # execution. # out: if this is set, the output from the command will be printed to the # screen. # err: if this is set, a failure message will be printed if the command fails. # time_out: if this is non-zero, the function will be timed out after the # specified number of seconds. # max_attempts: the total number of times to attempt the command. # sleep_time: the number of seconds to wait between each attempt. # debug: if this is set, debug information will be printed. # bash: if this is set, the function will execute a Bash command instead of # a Python command. # This function doesn't use parms in the exact same way as the bash version, # but just writing "param=value" works equally well in the function call, # i.e. exec_cmd(cmd_buf, param1=value1, param2=value2) stat = gopt.bool_convert(stat) out = gopt.bool_convert(out) err = gopt.bool_convert(err) debug = gopt.bool_convert(debug) current_attempt = 0 # Print debug information, if necessary. if debug: gprint.print_time("Printing debug information for exec_cmd.") g.print_var("cmd_buf", cmd_buf) g.print_var("stat", stat) g.print_var("out", out) g.print_var("err", err) g.print_var("time_out", time_out) g.print_var("max_attempts", max_attempts) g.print_var("sleep_time", sleep_time) g.print_var("debug", debug) # If we're using a time-out variable, then we need to set up a time-out # signal handler. No need to fork processes. if time_out != 0: original_handler = signal.signal(signal.SIGALRM, gsig.gen_timeout_handler) # Print out an issuing message if needed. if stat and bash: gprint.issuing(cmd_buf) if max_attempts == 0: gprint.print_time("max_attempts is zero so the preceding command will not actually be executed.") # Now let's begin the execution. status = 0 output = "" while current_attempt < max_attempts: status = 0 if time_out == 0: # If we're not timing it out, just run the command. status, output = commands.getstatusoutput(cmd_buf) if out: print output else: # Otherwise, we need to set an alarm and catch a time-out. # We'll actually catch all exceptions, since it's possible we can # be executing a Python command. signal.alarm(time_out) try: # In the Bash case. if bash: status, output = commands.getstatusoutput(cmd_buf) if out: print output # In the Python case. else: if out: exec (cmd_buf) else: sys.stdout = os.devnull exec (cmd_buf) sys.stdout = sys.__stdout__ except: # Restore stdout just in case. sys.stdout = sys.__stdout__ status = 1 signal.alarm(0) # We need to check the status of the command to see if it failed. # Note that status is set to 1 upon time-out. if status == 0: break else: current_attempt += 1 if sleep_time != 0 and current_attempt < max_attempts: time.sleep(sleep_time) # Check to see if we ultimately failed the command. if status != 0: if err: g.print_error("The following command failed to execute: " + cmd_buf) if output != "": print "Command output:" print output # Reset the alarm handler. if time_out != 0: signal.signal(signal.SIGALRM, original_handler) return status
def get_nearest_time_stamp(file_path, line_num, search_direction): g.print_error("get_nearest_time_stamp is not implemented.") # return time_var pass
def exec_cmd(cmd_buf, stat=False, out=False, err=False, time_out=0, max_attempts=1, sleep_time=1, debug=False, bash=False): # This is an advanced function for executing a string as a command. It has # the capacity to save the output and return it, time the command out, retry # the function and sleep between attempts. The rmt_cmd option has been # removed, as the "rcmd" function now has a "-rrc" flag that will set the # return code automatically. This is less typing for the programmer, so just # do that. # stat: if this is set, an "issuing" message will be printed prior to # execution. # out: if this is set, the output from the command will be printed to the # screen. # err: if this is set, a failure message will be printed if the command fails. # time_out: if this is non-zero, the function will be timed out after the # specified number of seconds. # max_attempts: the total number of times to attempt the command. # sleep_time: the number of seconds to wait between each attempt. # debug: if this is set, debug information will be printed. # bash: if this is set, the function will execute a Bash command instead of # a Python command. # This function doesn't use parms in the exact same way as the bash version, # but just writing "param=value" works equally well in the function call, # i.e. exec_cmd(cmd_buf, param1=value1, param2=value2) stat = gopt.bool_convert(stat) out = gopt.bool_convert(out) err = gopt.bool_convert(err) debug = gopt.bool_convert(debug) current_attempt = 0 # Print debug information, if necessary. if debug: gprint.print_time("Printing debug information for exec_cmd.") g.print_var("cmd_buf", cmd_buf) g.print_var("stat", stat) g.print_var("out", out) g.print_var("err", err) g.print_var("time_out", time_out) g.print_var("max_attempts", max_attempts) g.print_var("sleep_time", sleep_time) g.print_var("debug", debug) # If we're using a time-out variable, then we need to set up a time-out # signal handler. No need to fork processes. if time_out != 0: original_handler = signal.signal(signal.SIGALRM, gsig.gen_timeout_handler) # Print out an issuing message if needed. if stat and bash: gprint.issuing(cmd_buf) if max_attempts == 0: gprint.print_time( "max_attempts is zero so the preceding command will not actually be executed." ) # Now let's begin the execution. status = 0 output = "" while current_attempt < max_attempts: status = 0 if time_out == 0: # If we're not timing it out, just run the command. status, output = commands.getstatusoutput(cmd_buf) if out: print output else: # Otherwise, we need to set an alarm and catch a time-out. # We'll actually catch all exceptions, since it's possible we can # be executing a Python command. signal.alarm(time_out) try: # In the Bash case. if bash: status, output = commands.getstatusoutput(cmd_buf) if out: print output # In the Python case. else: if out: exec(cmd_buf) else: sys.stdout = os.devnull exec(cmd_buf) sys.stdout = sys.__stdout__ except: # Restore stdout just in case. sys.stdout = sys.__stdout__ status = 1 signal.alarm(0) # We need to check the status of the command to see if it failed. # Note that status is set to 1 upon time-out. if status == 0: break else: current_attempt += 1 if sleep_time != 0 and current_attempt < max_attempts: time.sleep(sleep_time) # Check to see if we ultimately failed the command. if status != 0: if err: g.print_error("The following command failed to execute: " + cmd_buf) if output != "": print "Command output:" print output # Reset the alarm handler. if time_out != 0: signal.signal(signal.SIGALRM, original_handler) return status
def sort_by_last_time_stamp(parm_list): g.print_error("sort_by_last_time_stamp is not implemented.") # return parm_list pass
def cleanup_temp_file(file_list, remove_from_global_list=False): g.print_error("cleanup_temp_file is not implemented.") # return rc pass
def get_options(args): # The main function to parse options. Many of these are generated # automatically from a few values provided. global shortopts global longopts global boolopts global varopts global funcopts global posparms global optparms try: opts, parms = getopt.gnu_getopt(args, shortopts, longopts) except getopt.GetoptError: g.print_error("Invalid option flag(s) specified.") return 1 # Process command line options. We have some short-circuiting present. for opt, arg in opts: found = False if opt == "--help": return 2 if boolopts != []: # Process all boolean options here. for flagname, var, default_val, needarg in boolopts: if opt == flagname: if needarg: g.global_vars[var] = bool_convert(arg) else: g.global_vars[var] = not default_val found = True break if not found and varopts != []: # Process all variable-setting options here. for flagname, var, default_val in varopts: if opt == flagname: g.global_vars[var] = arg found = True break if not found and funcopts != []: # Process all function-executing options here. for flagname, func in funcopts: if opt == flagname: func() break # Process command line parameters. We used to pop arguments from these lists, # but keeping track of positions with integers is way faster. argn = 0; amax = len(parms); parmn = 0; pmax = len(posparms) while argn < amax and parmn < pmax: # Go through the designated parms in order and assign values. varname, varlen, default_val = posparms[parmn] if varlen == 1: g.global_vars[varname] = parms[argn] elif varlen == 0: g.global_vars[varname] = parms[argn:amax] else: g.global_vars[varname] = parms[argn:argn+varlen] if varlen == 0: argn = amax # Checking for a programmer error. if parmn+1 < pmax or optparms != []: print "Programmer error: cannot allow additional parameters after a parm list takes all remaining arguments." return 1 else: argn += varlen parmn += 1 # If there are any mandatory parameters that have gone unassigned, # raise an error. if parmn < pmax: g.print_error("Mandatory parameter not specified.") return 1 # Process optional command line parameters. parmn = 0; pmax = len(optparms) while argn < amax and parmn < pmax: # Go through the designated parms in order and assign values. varname, varlen, default_val = optparms[parmn] if varlen == 1: g.global_vars[varname] = parms[argn] elif varlen == 0: g.global_vars[varname] = parms[argn:amax] else: g.global_vars[varname] = parms[argn:argn+varlen] if varlen == 0: argn = amax # Checking for a programmer error. if parmn+1 < pmax: g.print_error("Programmer error: cannot allow additional parameters after a parm list takes all remaining arguments.") return 1 else: argn += varlen parmn += 1 # If there are any command line parameters left, not a problem, just don't # use them. return 0
def check_pts_group_membership(group_name, group_cell, userid, print_err): g.print_error("check_pts_group_membership is not implemented.") # return rc pass
def get_real_caller_func(): g.print_error("get_real_caller_func is not implemented.") # return funcname pass
def build_cmd_buf(our_parms, additional_parms, cmd_buf): g.print_error("build_cmd_buf is not implemented.") # return cmd_buf pass