diff options
| author | Ryan Williams <rdw@lindenlab.com> | 2007-07-22 06:29:36 +0000 | 
|---|---|---|
| committer | Ryan Williams <rdw@lindenlab.com> | 2007-07-22 06:29:36 +0000 | 
| commit | 7769191414b663d652fb1fea0ee86fbdba3a9ec1 (patch) | |
| tree | ae77429e16085b21f077a4827614de68be40c6c5 | |
| parent | 45281046c5cf2d71b53c9f6c3d8d9ba74d29b33d (diff) | |
Added much more error-recovery logic to template-verifier -- e.g. it retries a few times to fetch the master from the web.  Also I changed the master to live in the system global tempdir, mostly because the build machines had a network problem and I wanted to reduce the chance of that happening.  Not reviewed, but I'm checking it in over the weekend so I can silently fix it if there's yet another weird configuration difference that breaks it on the build machines.
| -rwxr-xr-x | scripts/template_verifier.py | 80 | 
1 files changed, 45 insertions, 35 deletions
diff --git a/scripts/template_verifier.py b/scripts/template_verifier.py index e70299c429..769e864420 100755 --- a/scripts/template_verifier.py +++ b/scripts/template_verifier.py @@ -56,7 +56,15 @@ DEVELOPMENT_ACCEPTABLE = (  MAX_MASTER_AGE = 60 * 60 * 4   # refresh master cache every 4 hours -def compare(base, current, mode): +def retry(times, function, *args, **kwargs): +    for i in range(times): +        try: +            return function(*args, **kwargs) +        except Exception, e: +            if i == times - 1: +                raise e  # we retried all the times we could + +def compare(base_parsed, current_parsed, mode):      """Compare the current template against the base template using the given      'mode' strictness: @@ -70,20 +78,7 @@ def compare(base, current, mode):      Return True if they are compatible in this mode, False if not.      """ -    # catch this exception so we can print a message explaining which template is scr0d -    try: -        base = llmessage.parseTemplateString(base) -    except tokenstream.ParseError, e: -        print "Error parsing master message template -- this might be a network problem, try again" -        raise e - -    try: -        current = llmessage.parseTemplateString(current) -    except tokenstream.ParseError, e: -        print "Error parsing local message template" -        raise e -     -    compat = current.compatibleWithBase(base) +    compat = current_parsed.compatibleWithBase(base_parsed)      if mode == 'production':          acceptable = PRODUCTION_ACCEPTABLE      else: @@ -113,15 +108,25 @@ def cache_master(master_url):          return master_cache_url  # our cache is fresh      # new master doesn't exist or isn't fresh      print "Refreshing master cache from %s" % master_url -    try: +    def get_and_test_master():          new_master_contents = fetch(master_url) +        llmessage.parseTemplateString(new_master_contents) +        return new_master_contents +    try: +        new_master_contents = retry(3, get_and_test_master)      except IOError, e:          # the refresh failed, so we should just soldier on          print "WARNING: unable to download new master, probably due to network error.  Your message template compatibility may be suspect." +        print "Cause: %s" % e          return master_cache_url -    mc = open(master_cache, 'wb') -    mc.write(new_master_contents) -    mc.close() +    try: +        mc = open(master_cache, 'wb') +        mc.write(new_master_contents) +        mc.close() +    except IOError, e: +        print "WARNING: Unable to write master message template to %s, proceeding without cache." % master_cache +        print "Cause: %s" % e +        return master_url      return master_cache_url  def local_template_filename(): @@ -131,10 +136,11 @@ def local_template_filename():      return os.path.join(d, 'messages', MESSAGE_TEMPLATE)  def local_master_cache_filename(): -    """Returns the location of the master template cache relative to template_verifier.py -    ./messages/master_message_template_cache.msg""" -    d = os.path.dirname(os.path.realpath(__file__)) -    return os.path.join(d, 'messages', 'master_message_template_cache.msg') +    """Returns the location of the master template cache (which is in the system tempdir) +    <temp_dir>/master_message_template_cache.msg""" +    import tempfile +    d = tempfile.gettempdir() +    return os.path.join(d, 'master_message_template_cache.msg')  def run(sysargs): @@ -165,7 +171,7 @@ http://wiki.secondlife.com/wiki/Template_verifier.py      # both current and master supplied in positional params      if len(args) == 2:          master_filename, current_filename = args -        print "base:", master_filename +        print "master:", master_filename          print "current:", current_filename          master_url = 'file://%s' % master_filename          current_url = 'file://%s' % current_filename @@ -173,7 +179,7 @@ http://wiki.secondlife.com/wiki/Template_verifier.py      elif len(args) == 1:          master_url = None          current_filename = args[0] -        print "base: <master template from repository>" +        print "master:", options.master_url           print "current:", current_filename          current_url = 'file://%s' % current_filename      # nothing specified, use defaults for everything @@ -186,32 +192,36 @@ http://wiki.secondlife.com/wiki/Template_verifier.py      if master_url is None:          master_url = options.master_url -    # fetch the template for this build      if current_url is None:          current_filename = local_template_filename() -        print "base: <master template from repository>" +        print "master:", options.master_url          print "current:", current_filename          current_url = 'file://%s' % current_filename +    # retrieve the contents of the local template and check for syntax +    current = fetch(current_url) +    current_parsed = llmessage.parseTemplateString(current) +      if options.cache_master:          # optionally return a url to a locally-cached master so we don't hit the network all the time          master_url = cache_master(master_url) -    current = fetch(current_url) +    def parse_master_url(): +        master = fetch(master_url) +        return llmessage.parseTemplateString(master)      try: -        master  = fetch(master_url) -    except IOError, e: +        master_parsed = retry(3, parse_master_url) +    except (IOError, tokenstream.ParseError), e:          if options.mode == 'production':              raise e          else: -            print "WARNING: problems fetching the master from %s.  Syntax-checking the local template ONLY, no compatibility check is being run." % master_url -            llmessage.parseTemplateString(current) +            print "WARNING: problems retrieving the master from %s."  % master_url +            print "Syntax-checking the local template ONLY, no compatibility check is being run." +            print "Cause: %s\n\n" % e              return 0 -      acceptable, compat = compare( -        master, current, options.mode) -         +        master_parsed, current_parsed, options.mode)      def explain(header, compat):          print header  | 
