<s> import os , sys , stat <EOL> import json <EOL> import tarfile <EOL> import getopt <EOL> import hashlib <EOL> import StringIO <EOL> import ConfigParser <EOL> debug = <NUM_LIT:0> <EOL> verbose = False <EOL> def ScanTree ( root , filter_func = None ) : <EOL> global debug , verbose <EOL> flat_size = <NUM_LIT:0> <EOL> seen_files = { } <EOL> file_list = { } <EOL> directory_list = { } <EOL> for start , dirs , files in os . walk ( root ) : <EOL> prefix = start [ len ( root ) : ] + "<STR_LIT:/>" <EOL> for d in dirs : <EOL> if filter_func is not None : <EOL> if filter_func ( prefix + d ) == True : <EOL> continue <EOL> if os . path . islink ( os . path . join ( start , d ) ) : <EOL> files . append ( d ) <EOL> else : <EOL> directory_list [ prefix + d ] = "<STR_LIT:y>" <EOL> for f in files : <EOL> if filter_func is not None : <EOL> if filter_func ( prefix + f ) == True : <EOL> continue <EOL> full_path = start + "<STR_LIT:/>" + f <EOL> if verbose or debug > <NUM_LIT:0> : print >> sys . stderr , "<STR_LIT>" % full_path <EOL> st = os . lstat ( full_path ) <EOL> size = None <EOL> if os . path . islink ( full_path ) : <EOL> buf = os . readlink ( full_path ) <EOL> size = len ( buf ) <EOL> if buf . startswith ( "<STR_LIT:/>" ) : buf = buf [ <NUM_LIT:1> : ] <EOL> file_list [ prefix + f ] = hashlib . sha256 ( buf ) . hexdigest ( ) <EOL> elif os . path . isfile ( full_path ) : <EOL> size = st . st_size <EOL> with open ( full_path ) as file : <EOL> file_list [ prefix + f ] = hashlib . sha256 ( file . read ( ) ) . hexdigest ( ) <EOL> if size is not None and ( st . st_dev , st . st_ino ) not in seen_files : <EOL> flat_size += size <EOL> seen_files [ st . st_dev , st . st_ino ] = True <EOL> return { "<STR_LIT>" : file_list , "<STR_LIT>" : directory_list , "<STR_LIT>" : flat_size } <EOL> def usage ( ) : <EOL> print >> sys . stderr , "<STR_LIT>" % sys . argv [ <NUM_LIT:0> ] <EOL> sys . exit ( <NUM_LIT:1> ) <EOL> SCRIPTS = [ <EOL> "<STR_LIT>" , <EOL> "<STR_LIT>" , <EOL> "<STR_LIT>" , <EOL> "<STR_LIT>" , <EOL> "<STR_LIT>" , <EOL> "<STR_LIT>" , <EOL> "<STR_LIT>" , <EOL> "<STR_LIT>" , <EOL> "<STR_LIT>" <EOL> ] <EOL> def TemplateFiles ( path ) : <EOL> """<STR_LIT>""" <EOL> rv = { } <EOL> includes = [ ] <EOL> excludes = [ ] <EOL> if os . path . exists ( path ) == False : <EOL> return None <EOL> if os . path . isdir ( path ) : <EOL> base_dir = path <EOL> cfg_file = path + "<STR_LIT>" <EOL> else : <EOL> base_dir = os . path . dirname ( path ) <EOL> cfg_file = path <EOL> cfp = ConfigParser . ConfigParser ( ) <EOL> try : <EOL> cfp . read ( cfg_file ) <EOL> except : <EOL> return None <EOL> if cfp . has_option ( "<STR_LIT>" , "<STR_LIT>" ) : <EOL> opt = cfp . get ( "<STR_LIT>" , "<STR_LIT>" ) <EOL> for f in opt . split ( ) : <EOL> excludes . append ( f ) <EOL> if cfp . has_option ( "<STR_LIT>" , "<STR_LIT>" ) : <EOL> opt = cfp . get ( "<STR_LIT>" , "<STR_LIT>" ) <EOL> for f in opt . split ( ) : <EOL> includes . append ( f ) <EOL> rv [ "<STR_LIT>" ] = includes <EOL> rv [ "<STR_LIT>" ] = excludes <EOL> return rv <EOL> def LoadTemplate ( path ) : <EOL> """<STR_LIT>""" <EOL> rv = { } <EOL> if os . path . exists ( path ) == False : <EOL> raise Exception ( "<STR_LIT>" % path ) <EOL> if os . path . isdir ( path ) : <EOL> base_dir = path <EOL> cfg_file = path + "<STR_LIT>" <EOL> else : <EOL> base_dir = os . path . dirname ( path ) <EOL> cfg_file = path <EOL> cfp = ConfigParser . ConfigParser ( ) <EOL> try : <EOL> cfp . read ( cfg_file ) <EOL> except : <EOL> return rv <EOL> if cfp . has_section ( "<STR_LIT>" ) : <EOL> for key in [ "<STR_LIT:name>" , "<STR_LIT>" , "<STR_LIT>" , "<STR_LIT>" , <EOL> "<STR_LIT>" , "<STR_LIT>" , "<STR_LIT>" , "<STR_LIT>" , <EOL> "<STR_LIT>" , "<STR_LIT>" ] : <EOL> if cfp . has_option ( "<STR_LIT>" , key ) : <EOL> rv [ key ] = cfp . get ( "<STR_LIT>" , key ) <EOL> for key in [ "<STR_LIT>" ] : <EOL> if cfp . has_option ( "<STR_LIT>" , key ) : <EOL> rv [ key ] = cfp . getboolean ( "<STR_LIT>" , key ) <EOL> if cfp . has_section ( "<STR_LIT>" ) : <EOL> if "<STR_LIT>" not in rv : <EOL> rv [ "<STR_LIT>" ] = { } <EOL> for opt , val in cfp . items ( "<STR_LIT>" ) : <EOL> if val . startswith ( "<STR_LIT>" ) : <EOL> fname = val [ <NUM_LIT:5> : ] <EOL> if fname . startswith ( "<STR_LIT:/>" ) == False : <EOL> fname = base_dir + "<STR_LIT:/>" + fname <EOL> with open ( fname , "<STR_LIT:r>" ) as f : <EOL> rv [ "<STR_LIT>" ] [ opt ] = f . read ( ) <EOL> else : <EOL> rv [ "<STR_LIT>" ] [ opt ] = val <EOL> if cfp . has_section ( "<STR_LIT>" ) : <EOL> service_list = [ ] <EOL> if cfp . has_option ( "<STR_LIT>" , "<STR_LIT>" ) : <EOL> service_str = cfp . get ( "<STR_LIT>" , "<STR_LIT>" ) <EOL> for svc in service_str . split ( "<STR_LIT:U+002C>" ) : <EOL> service_list . append ( svc . strip ( ) ) <EOL> if len ( service_list ) > <NUM_LIT:0> : <EOL> restart_list = { } <EOL> if cfp . has_option ( "<STR_LIT>" , "<STR_LIT>" ) : <EOL> restart_str = cfp . get ( "<STR_LIT>" , "<STR_LIT>" ) <EOL> if restart_str == "<STR_LIT:all>" : <EOL> for svc in service_list : <EOL> restart_list [ svc ] = True <EOL> else : <EOL> for svc in cfp . get ( "<STR_LIT>" , "<STR_LIT>" ) . split ( "<STR_LIT:U+002C>" ) : <EOL> if not svc in service_list : <EOL> print >> sys . stderr , "<STR_LIT>" % svc <EOL> else : <EOL> restart_list [ svc ] = True <EOL> sdict = { "<STR_LIT>" : service_list } <EOL> if len ( restart_list ) > <NUM_LIT:0> : <EOL> sdict [ "<STR_LIT>" ] = restart_list <EOL> rv [ "<STR_LIT>" ] = sdict <EOL> return rv <EOL> def main ( ) : <EOL> global debug , verbose <EOL> manifest = { <EOL> "<STR_LIT>" : "<STR_LIT>" , <EOL> "<STR_LIT>" : "<STR_LIT>" , <EOL> "<STR_LIT>" : "<STR_LIT>" , <EOL> "<STR_LIT>" : "<STR_LIT>" , <EOL> "<STR_LIT>" : "<STR_LIT>" , <EOL> "<STR_LIT>" : "<STR_LIT:/>" , <EOL> "<STR_LIT>" : "<STR_LIT>" , <EOL> "<STR_LIT>" : "<STR_LIT>" , <EOL> "<STR_LIT>" : True , <EOL> } <EOL> root = None <EOL> arg_name = None <EOL> arg_version = None <EOL> arg_template = None <EOL> try : <EOL> opts , args = getopt . getopt ( sys . argv [ <NUM_LIT:1> : ] , "<STR_LIT>" ) <EOL> for o , a in opts : <EOL> if o == "<STR_LIT>" : <EOL> arg_name = a <EOL> elif o == "<STR_LIT>" : <EOL> arg_template = a <EOL> elif o == "<STR_LIT>" : <EOL> arg_version = a <EOL> elif o == "<STR_LIT>" : <EOL> root = a <EOL> elif o == "<STR_LIT>" : <EOL> debug += <NUM_LIT:1> <EOL> elif o == "<STR_LIT>" : <EOL> verbose = True <EOL> else : <EOL> print >> sys . stderr , "<STR_LIT>" % o <EOL> usage ( ) <EOL> except getopt . GetoptError as err : <EOL> print str ( err ) <EOL> usage ( ) <EOL> if len ( args ) > <NUM_LIT:1> : <EOL> print >> sys . stderr , "<STR_LIT>" <EOL> usage ( ) <EOL> elif len ( args ) == <NUM_LIT:0> : <EOL> print >> sys . stderr , "<STR_LIT>" <EOL> usage ( ) <EOL> else : <EOL> output = args [ <NUM_LIT:0> ] <EOL> if root is None : <EOL> print >> sys . stderr , "<STR_LIT>" <EOL> usage ( ) <EOL> include_list = None <EOL> exclude_list = None <EOL> if arg_template is not None : <EOL> tdict = LoadTemplate ( arg_template ) <EOL> if tdict is not None : <EOL> for k in tdict . keys ( ) : <EOL> manifest [ k ] = tdict [ k ] <EOL> print >> sys . stderr , "<STR_LIT>" % manifest <EOL> filters = TemplateFiles ( arg_template ) <EOL> if filters is not None : <EOL> if debug > <NUM_LIT:1> : print >> sys . stderr , "<STR_LIT>" % filters <EOL> if len ( filters [ "<STR_LIT>" ] ) > <NUM_LIT:0> : <EOL> include_list = filters [ "<STR_LIT>" ] <EOL> if len ( filters [ "<STR_LIT>" ] ) > <NUM_LIT:0> : <EOL> exclude_list = filters [ "<STR_LIT>" ] <EOL> def FilterFunc ( path ) : <EOL> """<STR_LIT>""" <EOL> if include_list is None and exclude_list is None : <EOL> retval = False <EOL> elif include_list is not None and exclude_list is None : <EOL> retval = True <EOL> elif include_list is None and exclude_list is not None : <EOL> retval = False <EOL> else : <EOL> retval = False <EOL> def matches ( path , pattern ) : <EOL> import fnmatch <EOL> prefix = "<STR_LIT>" <EOL> if path . startswith ( "<STR_LIT>" ) : <EOL> prefix = "<STR_LIT:.>" <EOL> if pattern . startswith ( "<STR_LIT:/>" ) : <EOL> tmp = prefix + pattern <EOL> else : <EOL> tmp = pattern <EOL> if path == tmp : <EOL> if debug : print >> sys . stderr , "<STR_LIT>" % path <EOL> return True <EOL> if path . startswith ( tmp ) and path [ len ( tmp ) ] == "<STR_LIT:/>" : <EOL> if debug : print >> sys . stderr , "<STR_LIT>" % ( path , tmp ) <EOL> return True <EOL> if fnmatch . fnmatch ( path , elem ) : <EOL> if debug : print >> sys . stderr , "<STR_LIT>" % ( path , tmp ) <EOL> return True <EOL> return False <EOL> if exclude_list is not None : <EOL> for elem in exclude_list : <EOL> if matches ( path , elem ) == True : <EOL> retval = True <EOL> break <EOL> if include_list is not None : <EOL> for elem in include_list : <EOL> if matches ( path , elem ) == True : <EOL> retval = False <EOL> return retval <EOL> if arg_name is not None : <EOL> manifest [ "<STR_LIT:name>" ] = arg_name <EOL> if arg_version is not None : <EOL> manifest [ "<STR_LIT:version>" ] = arg_version <EOL> if "<STR_LIT:name>" not in manifest : <EOL> print >> sys . stderr , "<STR_LIT>" <EOL> print >> sys . stderr , manifest <EOL> usage ( ) <EOL> if "<STR_LIT:version>" not in manifest : <EOL> print >> sys . stderr , "<STR_LIT>" <EOL> usage ( ) <EOL> if debug > <NUM_LIT:2> : print >> sys . stderr , manifest <EOL> t = ScanTree ( root , FilterFunc ) <EOL> manifest [ "<STR_LIT>" ] = t [ "<STR_LIT>" ] <EOL> manifest [ "<STR_LIT>" ] = t [ "<STR_LIT>" ] <EOL> manifest [ "<STR_LIT>" ] = t [ "<STR_LIT>" ] <EOL> manifest_string = json . dumps ( manifest , sort_keys = True , <EOL> indent = <NUM_LIT:4> , separators = ( '<STR_LIT:U+002C>' , '<STR_LIT>' ) ) <EOL> if debug > <NUM_LIT:1> : print manifest_string <EOL> tf = tarfile . open ( output , "<STR_LIT>" , format = tarfile . PAX_FORMAT ) <EOL> mani_file_info = tarfile . TarInfo ( name = "<STR_LIT>" ) <EOL> mani_file_info . size = len ( manifest_string ) <EOL> mani_file_info . mode = <NUM_LIT:0> <NUM_LIT> <EOL> mani_file_info . type = tarfile . REGTYPE <EOL> mani_file = StringIO . StringIO ( manifest_string ) <EOL> tf . addfile ( mani_file_info , mani_file ) <EOL> for file in sorted ( manifest [ "<STR_LIT>" ] ) : <EOL> if verbose or debug > <NUM_LIT:0> : print >> sys . stderr , "<STR_LIT>" % file <EOL> tf . add ( root + file , arcname = file , recursive = False ) <EOL> for dir in sorted ( manifest [ "<STR_LIT>" ] ) : <EOL> if verbose or debug > <NUM_LIT:0> : print >> sys . stderr , "<STR_LIT>" % dir <EOL> tf . add ( root + dir , arcname = dir , recursive = False ) <EOL> return <NUM_LIT:0> <EOL> if __name__ == "<STR_LIT:__main__>" : <EOL> sys . exit ( main ( ) ) </s>
