diff options
| author | Glenn Glazer <coyot@lindenlab.com> | 2016-07-27 15:44:56 -0700 | 
|---|---|---|
| committer | Glenn Glazer <coyot@lindenlab.com> | 2016-07-27 15:44:56 -0700 | 
| commit | f44829f2aefe8c5fae9fba6bb838500719e1067e (patch) | |
| tree | 589fe018bcede49ec004bd8862d55dff49a75ba5 /indra | |
| parent | 1224697a40a469bebd794c5816d6cc9c34e1000a (diff) | |
SL-321: basic launcher/updater integration test fixes
Diffstat (limited to 'indra')
| -rwxr-xr-x | indra/newview/viewer_manifest.py | 20 | ||||
| -rwxr-xr-x | indra/viewer_components/manager/SL_Launcher | 59 | ||||
| -rwxr-xr-x | indra/viewer_components/manager/update_manager.py | 101 | 
3 files changed, 112 insertions, 68 deletions
| diff --git a/indra/newview/viewer_manifest.py b/indra/newview/viewer_manifest.py index aaad79387f..3572b7dba8 100755 --- a/indra/newview/viewer_manifest.py +++ b/indra/newview/viewer_manifest.py @@ -27,6 +27,7 @@ Linden Research, Inc., 945 Battery Street, San Francisco, CA  94111  USA  $/LicenseInfo$  """  import sys +import os  import os.path  import shutil  import errno @@ -702,6 +703,7 @@ class Darwin_i386_Manifest(ViewerManifest):          pkgdir = os.path.join(self.args['build'], os.pardir, 'packages')          relpkgdir = os.path.join(pkgdir, "lib", "release")          debpkgdir = os.path.join(pkgdir, "lib", "debug") +        llbasedir = os.path.join(pkgdir, os.pardir)          if self.prefix(src="", dst="Contents"):  # everything goes in Contents              self.path("Info.plist", dst="Info.plist") @@ -715,8 +717,14 @@ class Darwin_i386_Manifest(ViewerManifest):                  #this copies over the python wrapper script, associated utilities and required libraries, see SL-321, SL-322 and SL-323                  self.path2basename("../viewer_components/manager","SL_Launcher")                  self.path2basename("../viewer_components/manager","*.py") -                self.path2basename("../../../../../packages/llbase","*") -                self.end_prefix() +                llbase_path = os.path.join(self.get_dst_prefix(),'llbase') +                if not os.path.exists(llbase_path): +                    os.makedirs(llbase_path) +                if self.prefix(dst="llbase"): +                    self.path2basename("../packages/llbase","*.py") +                    self.path2basename("../packages/llbase","_cllsd.so") +                    self.end_prefix() +                self.end_prefix()                       # most everything goes in the Resources directory              if self.prefix(src="", dst="Resources"): @@ -1071,7 +1079,13 @@ class LinuxManifest(ViewerManifest):              #this copies over the python wrapper script, associated utilities and required libraries, see SL-321, SL-322 and SL-323              self.path2basename("../viewer_components/manager","SL_Launcher")              self.path2basename("../viewer_components/manager","*.py") -            self.path2basename("../packages/llbase","*") +            llbase_path = os.path.join(self.get_dst_prefix(),'llbase') +            if not os.path.exists(llbase_path): +                os.makedirs(llbase_path) +            if self.prefix(dst="llbase"): +                self.path2basename("../packages/llbase","*.py") +                self.path2basename("../packages/llbase","_cllsd.so") +                self.end_prefix()                          self.end_prefix("bin")          if self.prefix("res-sdl"): diff --git a/indra/viewer_components/manager/SL_Launcher b/indra/viewer_components/manager/SL_Launcher index a96f2392a7..dde7cd9c2e 100755 --- a/indra/viewer_components/manager/SL_Launcher +++ b/indra/viewer_components/manager/SL_Launcher @@ -17,43 +17,51 @@  # $/LicenseInfo$  # Copyright (c) 2013, Linden Research, Inc. +import os +import sys + +#module globals +log_file_handle = None +cwd = os.path.dirname(os.path.realpath(__file__)) +sys.path.insert(0, os.path.join(cwd, 'llbase')) +  import argparse  import collections  import InstallerUserMessage  #NOTA BENE:   #   For POSIX platforms, llsd.py will be imported from the same directory.    #   For Windows, llsd.py will be compiled into the executable by pyinstaller -import llsd -import os +from llbase import llsd  import platform -import sys  import subprocess  import update_manager -def after_frame(my_message, timeout = 10000): -   #pop up a InstallerUserMessage.basic_message that kills itself after timeout milliseconds -   #note that this blocks the caller for the duration of timeout -   frame = InstallerUserMessage(title = "Second Life Installer", icon_name="head-sl-logo.gif") -   #this is done before basic_message so that we aren't blocked by mainloop() -   frame.after(timout, lambda: frame._delete_window) -   frame.basic_message(message = my_message) -    + +def silent_write(log_file_handle, text): +   #if we have a log file, write.  If not, do nothing. +   #this is so we don't have to keep trapping for an exception with a None handle +   #oh and because it is best effort, it is also a holey_write ;) +   if (log_file_handle): +      #prepend text for easy grepping +      log_file_handle.write("SL LAUNCHER: " + text + "\n") +    def get_cmd_line():     platform_name = platform.system()     #find the parent of the logs and user_settings directories -   if (platform_name == 'mac'): +   if (platform_name == 'Darwin'):        settings_file = os.path.join(os.path.dirname(os.path.dirname(os.path.realpath(__file__))), 'Resources/app_settings/cmd_line.xml') -   elif (platform_name == 'lnx'):  +   elif (platform_name == 'Linux'):         settings_file = os.path.join(os.path.dirname(os.path.realpath(__file__)), 'app_settings/cmd_line.xml')     #using list format of join is important here because the Windows pathsep in a string escapes the next char -   elif (platform_name == 'win'): +   elif (platform_name == 'Windows'):        settings_file = os.path.join(os.path.dirname(os.path.realpath(__file__)), 'app_settings/cmd_line.xml')     else: -      settings_dir = None +      settings_file = None     try:        cmd_line = llsd.parse((open(settings_file)).read())     except: +      silent_write(log_file_handle, "Could not parse settings file %s" % settings_file)        cmd_line = None     return cmd_line @@ -68,7 +76,6 @@ def get_settings():        return None     return settings -     def capture_vmp_args(arg_list = None, cmd_line = None):     #expected input format: arg_list = ['--set', 'foo', 'bar', '-X', '-Y', 'qux']     #take a copy of the viewer parameters that are of interest to VMP. @@ -96,7 +103,8 @@ def capture_vmp_args(arg_list = None, cmd_line = None):                 cli_overrides[vmp_params[param]] = (setting_name, setting_value)           else:              #find out how many args this parameter has -            count = cmd_line[param]['count'] +            no_dashes = vmp_params[param] +            count = cmd_line[no_dashes]['count']              param_args = []              if count:                 for argh in range(1,count): @@ -112,6 +120,7 @@ def capture_vmp_args(arg_list = None, cmd_line = None):           except KeyError:              cli_overrides[key] = None        else: +         cli_overrides["--set"] = {}           for arg in vmp_setters:              try:                 cli_overrides[key][arg] @@ -119,7 +128,10 @@ def capture_vmp_args(arg_list = None, cmd_line = None):                 cli_overrides[key][arg] = None     return cli_overrides -cwd = os.path.dirname(os.path.realpath(__file__)) +#main entry point    +#this and a few other update manager methods really should be refactored into a util lib +parent_dir = update_manager.get_parent_path(update_manager.get_platform_key()) +log_file_handle = update_manager.get_log_file_handle(parent_dir)  executable_name = ""  if sys.platform.startswith('darwin'): @@ -137,23 +149,18 @@ else:     #SL doesn't run on VMS or punch cards     sys.exit("Unsupported platform") -#check for an update -#TODO -  #find the viewer to be lauched  viewer_binary = os.path.join(os.path.dirname(os.path.abspath(sys.argv[0])),executable_name)   parser = argparse.ArgumentParser()  args = parser.parse_known_args(sys.argv) -print args[1] -sys.exit()  #args[1] looks like ['./SL_Launcher', '--set', 'foo', 'bar', '-X', '-Y', 'qux'], dump the progname  args_list_to_pass = args[1][1:]  vmp_args = capture_vmp_args(args_list_to_pass)  #make a copy by value, not by reference  command = list(args_list_to_pass) -(success, state, condition) = update_manager.update_manager(cli_overrides) +(success, state, condition) = update_manager.update_manager(vmp_args)  # From update_manager:  #  (False, 'setup', None): error occurred before we knew what the update was (e.g., in setup or parsing)  #  (False, 'download', version): we failed to download the new version @@ -167,8 +174,8 @@ command = list(args_list_to_pass)  #  No update, update succeeded in place in foreground, or background update started: silently launch the current viewer channel  #  Updated succeed to a different channel, launch that viewer and exit  if not success: -   msg = 'Update failed in the %s process.  Please check logs.  Viewer will launch starting momentarily.' -   after_frame(msg) +   msg = 'Update failed in the %s process.  Please check logs.  Viewer will launch starting momentarily.' % state +   update_manager.after_frame(msg)     command.insert(0,viewer_binary)     viewer_process = subprocess.Popen(command)     #at the moment, we just exit here.  Later, the crash monitor will be launched at this point diff --git a/indra/viewer_components/manager/update_manager.py b/indra/viewer_components/manager/update_manager.py index a7e0a19aef..398c8bb55d 100755 --- a/indra/viewer_components/manager/update_manager.py +++ b/indra/viewer_components/manager/update_manager.py @@ -1,29 +1,35 @@  #!/usr/bin/env python -# $LicenseInfo:firstyear=2016&license=internal$ -#  -# Copyright (c) 2016, Linden Research, Inc. -#  -# The following source code is PROPRIETARY AND CONFIDENTIAL. Use of -# this source code is governed by the Linden Lab Source Code Disclosure -# Agreement ("Agreement") previously entered between you and Linden -# Lab. By accessing, using, copying, modifying or distributing this -# software, you acknowledge that you have been informed of your -# obligations under the Agreement and agree to abide by those obligations. -#  -# ALL LINDEN LAB SOURCE CODE IS PROVIDED "AS IS." LINDEN LAB MAKES NO -# WARRANTIES, EXPRESS, IMPLIED OR OTHERWISE, REGARDING ITS ACCURACY, -# COMPLETENESS OR PERFORMANCE. -# $/LicenseInfo$ -# Copyright (c) 2013, Linden Research, Inc. - -""" -@file   update_manager.py +"""\ +@file update_manager.py  @author coyot -@date   2016-05-16 +@date 2016-05-16 +@brief executes viewer update checking and manages downloading and applying of updates + +$LicenseInfo:firstyear=2016&license=viewerlgpl$ +Second Life Viewer Source Code +Copyright (C) 2016, Linden Research, Inc. + +This library is free software; you can redistribute it and/or +modify it under the terms of the GNU Lesser General Public +License as published by the Free Software Foundation; +version 2.1 of the License only. + +This library is distributed in the hope that it will be useful, +but WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU +Lesser General Public License for more details. + +You should have received a copy of the GNU Lesser General Public +License along with this library; if not, write to the Free Software +Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301  USA + +Linden Research, Inc., 945 Battery Street, San Francisco, CA  94111  USA +$/LicenseInfo$  """  from llbase import llrest +from llbase.llrest import RESTError  from llbase import llsd  from urlparse import urljoin @@ -55,9 +61,9 @@ def silent_write(log_file_handle, text):  def after_frame(my_message, timeout = 10000):      #pop up a InstallerUserMessage.basic_message that kills itself after timeout milliseconds      #note that this blocks the caller for the duration of timeout -    frame = InstallerUserMessage(title = "Second Life Installer", icon_name="head-sl-logo.gif") +    frame = InstallerUserMessage.InstallerUserMessage(title = "Second Life Installer", icon_name="head-sl-logo.gif")      #this is done before basic_message so that we aren't blocked by mainloop() -    frame.after(timout, lambda: frame._delete_window) +    frame.after(timeout, lambda: frame._delete_window)      frame.basic_message(message = my_message)  def convert_version_file_style(version): @@ -146,8 +152,10 @@ def check_for_completed_download(download_dir):  def get_settings(log_file_handle, parent_dir):      #return the settings file parsed into a dict +    print str(parent_dir)      try:          settings_file = os.path.abspath(os.path.join(parent_dir,'user_settings','settings.xml')) +        print "Settings file: " + str(settings_file)          settings = llsd.parse((open(settings_file)).read())      except llsd.LLSDParseError as lpe:          silent_write(log_file_handle, "Could not parse settings file %s" % lpe) @@ -213,7 +221,7 @@ def query_vvm(log_file_handle = None, platform_key = None, settings = None, summ      else:          base_URI = 'https://update.secondlife.com/update/'      channelname = summary_dict['Channel'] -    #this is kind of a mess because the settings value a) in a map and b) is both the cohort and the version +    #this is kind of a mess because the settings value is a) in a map and b) is both the cohort and the version      version = summary_dict['Version']      platform_version = platform.release()      #this will always return something usable, error handling in method @@ -250,7 +258,7 @@ def query_vvm(log_file_handle = None, platform_key = None, settings = None, summ      try:          result_data = VVMService.get(query_string)      except RESTError as re: -        silent_write.write(log_file_handle, "Failed to query VVM using %s failed as %s" % (urljoin(base_URI,query_string, re))) +        silent_write(log_file_handle, "Failed to query VVM using %s failed as %s" % (urljoin(base_URI,query_string), re))          return None      return result_data @@ -342,6 +350,8 @@ def update_manager(cli_overrides = None):      platform_key = get_platform_key()      parent_dir = get_parent_path(platform_key)      log_file_handle = get_log_file_handle(parent_dir) +    settings = None +    print "parent dir: " + str(parent_dir)      #check to see if user has install rights      #get the owner of the install and the current user @@ -367,10 +377,12 @@ def update_manager(cli_overrides = None):              print "Update manager exited with (%s, %s, %s)" % (False, 'setup', None)              return (False, 'setup', None) -    if cli_overrides['settings'] is not None: -        settings = get_settings(log_file_handle, cli_overrides['settings']) -    else: -        settings = get_settings(log_file_handle, parent_dir) +    if cli_overrides is not None:  +        if '--settings' in cli_overrides.keys(): +            if cli_overrides['--settings'] is not None: +                settings = get_settings(log_file_handle, cli_overrides['--settings']) +            else: +                settings = get_settings(log_file_handle, parent_dir)      if settings is None:          silent_write(log_file_handle, "Failed to load viewer settings") @@ -379,7 +391,7 @@ def update_manager(cli_overrides = None):      #323: If a complete download of that update is found, check the update preference:      #settings['UpdaterServiceSetting'] = 0 is manual install -    """ +    """ssh://hg@bitbucket.org/lindenlab/viewer-release-maint-6585      <key>UpdaterServiceSetting</key>          <map>          <key>Comment</key> @@ -390,8 +402,10 @@ def update_manager(cli_overrides = None):              <string>0</string>          </map>      """ -    if cli_overrides['set']['UpdaterServiceSetting'] is not None: -        install_automatically = cli_overrides['set']['UpdaterServiceSetting'] +    if cli_overrides is not None:  +        if '--set' in cli_overrides.keys(): +            if 'UpdaterServiceSetting' in cli_overrides['--set'].keys(): +                install_automatically = cli_overrides['--set']['UpdaterServiceSetting']      else:          try:              install_automatically = settings['UpdaterServiceSetting']['Value'] @@ -399,28 +413,37 @@ def update_manager(cli_overrides = None):          except KeyError:              install_automatically = 1 -    #use default chunk size if none is given         -    if cli_overrides['set']['UpdaterMaximumBandwidth ']: -        chunk_size = cli_overrides['set']['UpdaterMaximumBandwidth '] +    #use default chunk size if none is given      +    if cli_overrides is not None:  +        if '--set' in cli_overrides.keys(): +            if 'UpdaterMaximumBandwidth' in cli_overrides['--set'].keys():     +                chunk_size = cli_overrides['--set']['UpdaterMaximumBandwidth']      else:          chunk_size = 1024      #get channel and version      try:          summary_dict = get_summary(platform_key, os.path.abspath(os.path.realpath(__file__))) -        if cli_overrides['channel']: -            summary_dict['Channel'] = cli_overrides['channel'] -    except: +        if cli_overrides is not None: +            if 'channel' in cli_overrides.keys(): +                summary_dict['Channel'] = cli_overrides['channel'] +    except Exception, e:          silent_write(log_file_handle, "Could not obtain channel and version, exiting.") +        silent_write(log_file_handle, e.message)          print "Update manager exited with (%s, %s, %s)" % (False, 'setup', None)          return (False, 'setup', None)              #323: On launch, the Viewer Manager should query the Viewer Version Manager update api. -    UpdaterServiceURL = cli_overrides['update-service'] +    if cli_overrides is not None: +        if '--update-service' in cli_overrides.keys(): +            UpdaterServiceURL = cli_overrides['--update-service'] +    else: +        #tells query_vvm to use the default +        UpdaterServiceURL = None      result_data = query_vvm(log_file_handle, platform_key, settings, summary_dict, UpdaterServiceURL)      #nothing to do or error      if not result_data: -        silent_write.write(og_file_handle, "No update found.") +        silent_write(log_file_handle, "No update found.")          print "Update manager exited with (%s, %s, %s)" % (True, None, None)          return (True, None, None) | 
