#!/usr/bin/env python #------------------------------------------------------------------------------- # Output - Handle messages # - IMPROVE: Pass a parameter to specify destination(s) stdout, errout, file, or # multiple locations. For now only prints to stdout. # # Parameters # message # - Message string to output # msg_type # - err, warn, or info; defaults to info # ack_flag # - Wait for user acknowledgement? True or False, defaults to True # exit_value # - None if an exit is NOT desied, an integer otherwise, defaults to None # # # Returns - Nothing def Output(message, msg_type='info', ack_flag = True, exit_value = None): #--------------------------------------------------------------------------- # Local constants/variables #--------------------------------------------------------------------------- func_name = 'Output' full_name = "%s.%s" % (__name__, func_name) paramErr = False #--------------------------------------------------------------------------- # Module imports #--------------------------------------------------------------------------- import sys # Access to some variables used/maintained by the interpreter # and to functions that interact strongly with the interpreter. import time # Various time related functions # Get current time now = time.localtime() #--------------------------------------------------------------------------- # Confirm passed parameters are valid. #--------------------------------------------------------------------------- # msg_type if not ( msg_type == 'err' or msg_type == 'warn' or msg_type == 'info' ): raise ValueError("%s - Parameter msg_type is invalid." % full_name) # ack_flag if not ( ack_flag == True or ack_flag == False ): raise ValueError("%s - Parameter ack_flag is invalid." % full_name) # exit_value if not ( exit_value == None or type(exit_value) == type(int()) ): raise ValueError("%s - Parameter exit_value is invalid." % full_name) # Define and print a header line if msg_type == 'warn': msgHeader = '!! WARNING !!' elif msg_type == 'err': msgHeader = '!!! ERROR !!!' else: msgHeader = '! INFORMATION !' print "%-16s - %4d%02d%02d - %02d:%02d:%02d - %s" % (msgHeader, now.tm_year, now.tm_mon, now.tm_mday, now.tm_hour, now.tm_min, now.tm_sec, sys.argv[0]) # Print the message print '%s\n' % message # Wait for user acknowledgement? if ack_flag == True: while True: reply = raw_input("Acknowledge (ok): ") if reply == 'ok': break # Exit? if not exit_value == None: sys.exit(exit_value) return None #------------------------------------------------------------------------------- #------------------------------------------------------------------------------- # Derived from Python cookbook (2nd Ed., pgs80-81) # # TarSubTree - Provides a utility to archive all the files and folders in a # subtree into a tar archive, optionally compressing the data with gzip or # bzip2. # # Input Parameters # folder_to_backup - the base directory to archive; e.g., '/opt/agilent/...' # dest_folder - where the archive should be stored # compression - 'bz2', 'gz', or none ('') # # Returns the tar file destination path. def TarSubTree(folder_to_backup, dest_folder, compression='bz2'): #--------------------------------------------------------------------------- # Module imports #--------------------------------------------------------------------------- import os, tarfile # Locals funcName = TarSubTree # Improve - validate passed parameters # Set destination extension and compression flag if compression: dest_ext = '.' + compression dest_cmp = ':' + compression else: dest_ext = '' dest_cmp = '' # Define archive name and destination path arcname = os.path.basename(folder_to_backup) dest_name = "%s.tar%s" % (arcname, dest_ext) dest_path = os.path.join(dest_folder, dest_name) # Create the tar file object out = tarfile.open(dest_path, 'w'+dest_cmp) # Add the directory to the tar file out.add(folder_to_backup, arcname) # Close the tar file object out.close() # Return the destination path return dest_path #------------------------------------------------------------------------------- #------------------------------------------------------------------------------- # UntarSubTree - Provides a utility to unarchive all the files and folders in a # subtree tar archive into the specified location. Can handle tar files with # gzip or bzip2 compression, presumes compression is indicated by the extenions # 'gz' or 'bz2'; and no compression by just a '.tar' extension. # # Input Parameters # tarfile_path - location of the tar file to unarchive # base_path - the base directory where the archive should be restored # del_flag - should the archive be deleted after being restored? # # Returns nothing def UntarSubTree(tarfile_path, base_path, del_flag=False): #--------------------------------------------------------------------------- # Module imports #--------------------------------------------------------------------------- import os, tarfile # Locals funcName = UntarSubTree # Improve - validate passed parameters # Set compression flag archive_ext = os.path.splitext(tarfile_path)[1] if archive_ext == '.bz2': archive_cmp = ':bz2' elif archive_ext == '.gz': archive_cmp = ':gz' elif archive_ext == '.tar': archive_cmp = '' else: message = "%s - Unsupported archive file extension \"%s\" is not\n" % func_name message += "\".bz2\", \".gz\", or \".tar\".\n" Output(message, 'err', False, 2) # Open the tar file object out = tarfile.open(tarfile_path, 'r'+archive_cmp) # Extract all the files in the archive to the base directory. out.extractall(base_path) # Close the tar file object out.close() # Delete the archive if necessary. if del_flag: os.remove(tarfile_path) #------------------------------------------------------------------------------- #------------------------------------------------------------------------------- # CopySubTree - Provides a utility to copy all the files and folders in a # subtree from one location to another using a tar archive to preserve all # permissions, owners, group, etc. settings. # # Input Parameters # folder_to_copy - the base directory to copy; e.g., '/opt/agilent/...' # base_path - the base directory where the copy should be placed # del_flag - should the original subtree be deleted after being copied? # # Returns nothing def CopySubTree(folder_to_copy, base_path, del_flag=False): #--------------------------------------------------------------------------- # Module imports #--------------------------------------------------------------------------- import os, shutil # Locals funcName = CopySubTree # Improve - validate passed parameters pathList = '' for filePath in (folder_to_copy, base_path): if not os.path.exists(filePath): pathList += "%s\n" % fileName if not pathList == '': message = "%s - The following paths do NOT exist:\n" % func_name message += pathList Output(message, 'err', False, 2) # Tar the source tarfile_path = TarSubTree(folder_to_copy, base_path) # Create the new copy UntarSubTree(tarfile_path, base_path) # Delete the orignal if necessary. if del_flag: shutil.rmtree(folder_to_copy) #------------------------------------------------------------------------------- # Was attempting the following in our script #CopySubTree('/opt/agilent/ipcore/default/config', '/opt/fallback') # When the resulting file from the 1st half is untarred using # tar --bzip2 -xvf config.tar.bz2 # The files and directories are correct. # Example tar file should be included with this message. # Using Python the directories including the parent 'config' directory have the # wrong permissions, owner, and group. Except for the 'state' directory. # Executing the following should mimic the 2nd half of the process tarfile_path = '/opt/fallback/config.tar.bz2' # Set this as desired/needed base_path = '/opt/fallback' # Set this as desired/needed UntarSubTree(tarfile_path, base_path)