diff options
| -rwxr-xr-x | indra/viewer_components/manager/apply_update.py | 232 | 
1 files changed, 0 insertions, 232 deletions
| diff --git a/indra/viewer_components/manager/apply_update.py b/indra/viewer_components/manager/apply_update.py deleted file mode 100755 index 1cf394e008..0000000000 --- a/indra/viewer_components/manager/apply_update.py +++ /dev/null @@ -1,232 +0,0 @@ -#!/usr/bin/env python - -# 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:firstyear=2016&license=viewerlgpl$ -# Copyright (c) 2016, Linden Research, Inc. -# $/LicenseInfo$ - -""" -@file   apply_update.py -@author coyot -@date   2016-06-28 -""" - -""" -Applies an already downloaded update. -""" - -import argparse -import fnmatch -import InstallerUserMessage as IUM -import os -import os.path -import plistlib -import shutil -import subprocess -import sys -import tarfile -import tempfile - -LNX_REGEX = '*' + '.bz2' -MAC_REGEX = '*' + '.dmg' -MAC_APP_REGEX = '*' + '.app' -WIN_REGEX = '*' + '.exe' - -INSTALL_DIR = os.path.abspath(os.path.dirname(os.path.realpath(__file__))) - -BUNDLE_IDENTIFIER = "com.secondlife.indra.viewer" -# Magic OS directory name that causes Cocoa viewer to crash on OS X 10.7.5 -# (see MAINT-3331) -STATE_DIR = os.path.join(os.environ["HOME"], "Library", "Saved Application State", -    BUNDLE_IDENTIFIER + ".savedState") - -def silent_write(log_file_handle, text): -    #if we have a log file, write.  If not, do nothing. -    if (log_file_handle): -        #prepend text for easy grepping -        log_file_handle.write("APPLY UPDATE: " + text + "\n") - -def get_filename(download_dir = None): -    #given a directory that supposedly has the download, find the installable -    for filename in os.listdir(download_dir): -        if (fnmatch.fnmatch(filename, LNX_REGEX)  -          or fnmatch.fnmatch(filename, MAC_REGEX)  -          or fnmatch.fnmatch(filename, WIN_REGEX)):             -            return os.path.join(download_dir, filename) -        else: -            return None -           -def try_dismount(log_file_handle = None, installable = None, tmpdir = None): -    #best effort cleanup try to dismount the dmg file if we have mounted one -    #the French judge gave it a 5.8 -    try: -        command = ["df", os.path.join(tmpdir, "Second Life Installer")] -        output = subprocess.check_output(command) -        mnt_dev = output.split('\n')[1].split()[0] -        command = ["hdiutil", "detach", "-force", mnt_dev] -        output = subprocess.check_output(command) -        silent_write(log_file_handle, "hdiutil detach succeeded") -        silent_write(log_file_handle, output) -    except Exception, e: -        silent_write(log_file_handle, "Could not detach dmg file %s.  Error messages: %s" % (installable, e.message))     - -def apply_update(download_dir = None, platform_key = None, log_file_handle = None): -    #for lnx and mac, returns path to newly installed viewer and "True" for Windows -    #returns None on failure for all three -    installable = get_filename(download_dir) -    if not installable: -        #could not find download -        raise ValueError("Could not find installable in " + download_dir) -     -    if platform_key == 'lnx': -        installed = apply_linux_update(installable, log_file_handle) -    elif platform_key == 'mac': -        installed = apply_mac_update(installable, log_file_handle) -    elif platform_key == 'win': -        installed = apply_windows_update(installable, log_file_handle) -    else: -        #wtf? -        raise ValueError("Unknown Platform: " + platform_key) -     -    if not installed: -        done_filename = os.path.join(os.path.dirname(installable), ".done") -        open(done_filename, 'w+').close() -         -    return installed -     -def apply_linux_update(installable = None, log_file_handle = None): -    try: -        #untar to tmpdir -        tmpdir = tempfile.mkdtemp() -        tar = tarfile.open(name = installable, mode="r:bz2") -        tar.extractall(path = tmpdir) -        #rename current install dir -        shutil.move(INSTALL_DIR,install_dir + ".bak") -        #mv new to current -        shutil.move(tmpdir, INSTALL_DIR) -        #delete tarball on success -        os.remove(installable) -    except Exception, e: -        silent_write(log_file_handle, "Update failed due to " + repr(e)) -        return None -    return INSTALL_DIR - -def apply_mac_update(installable = None, log_file_handle = None): -    #verify dmg file -    try: -        output = subprocess.check_output(["hdiutil", "verify", installable], stderr=subprocess.STDOUT) -        silent_write(log_file_handle, "dmg verification succeeded") -        silent_write(log_file_handle, output) -    except Exception, e: -        silent_write(log_file_handle, "Could not verify dmg file %s.  Error messages: %s" % (installable, e.message)) -        return None -    #make temp dir and mount & attach dmg -    tmpdir = tempfile.mkdtemp() -    try: -        output = subprocess.check_output(["hdiutil", "attach", installable, "-mountroot", tmpdir]) -        silent_write(log_file_handle, "hdiutil attach succeeded") -        silent_write(log_file_handle, output) -    except Exception, e: -        silent_write(log_file_handle, "Could not attach dmg file %s.  Error messages: %s" % (installable, e.message)) -        return None -    #verify plist -    appdir = None -    for top_dir in os.listdir(tmpdir): -        for appdir in os.listdir(os.path.join(tmpdir, top_dir)): -            appdir = os.path.join(os.path.join(tmpdir, top_dir), appdir) -            if fnmatch.fnmatch(appdir, MAC_APP_REGEX): -                try: -                    plist = os.path.join(appdir, "Contents", "Info.plist") -                    CFBundleIdentifier = plistlib.readPlist(plist)["CFBundleIdentifier"] -                except: -                    #there is no except for this try because there are multiple directories that legimately don't have what we are looking for -                    pass -    if not appdir: -        silent_write(log_file_handle, "Could not find app bundle in dmg %s." % (installable,)) -        return None         -    if CFBundleIdentifier != BUNDLE_IDENTIFIER: -        silent_write(log_file_handle, "Wrong or null bundle identifier for dmg %s.  Bundle identifier: %s" % (installable, CFBundleIdentifier)) -        try_dismount(log_file_handle, installable, tmpdir)                    -        return None -    #do the install, finally -    #  swap out old install directory -    bundlename = os.path.basename(appdir) -    #INSTALL_DIR is something like /Applications/Second Life Viewer.app/Contents/MacOS, need to jump up two levels -    installed_test = os.path.dirname(INSTALL_DIR) -    installed_test = os.path.dirname(installed_test) -    if os.path.exists(installed_test): -        silent_write(log_file_handle, "Updating %s" % installed_test) -        swapped_out = os.path.join(tmpdir, INSTALL_DIR.lstrip('/')) -        shutil.move(installed_test, swapped_out) -    else: -        silent_write(log_file_handle, "Installing %s" % installed_test) -         -    #   copy over the new bits -    try: -        shutil.copytree(appdir, installed_test, symlinks=True) -        retcode = 0 -    except Exception, e: -        # try to restore previous viewer -        if os.path.exists(swapped_out): -            silent_write(log_file_handle, "Install of %s failed, rolling back to previous viewer." % installable) -            shutil.move(swapped_out, installed_test) -            retcode = 1 -    finally: -        try_dismount(log_file_handle, installable, tmpdir) -        if retcode: -            return None -     -    #see MAINT-3331         -    with allow_errno(errno.ENOENT): -        shutil.rmtree(STATE_DIR)   -     -    os.remove(installable) -    return INSTALL_DIR -     -def apply_windows_update(installable = None, log_file_handle = None): -    #the windows install is just running the NSIS installer executable -    #from VMP's perspective, it is a black box -    try: -        output = subprocess.check_output(installable, stderr=subprocess.STDOUT) -        silent_write(log_file_handle, "Install of %s succeeded." % installable) -        silent_write(log_file_handle, output) -    except subprocess.CalledProcessError, cpe: -        silent_write(log_file_handle, "%s failed with return code %s. Error messages: %s." %  -                     (cpe.cmd, cpe.returncode, cpe.message)) -        return None -    return True - -def main(): -    parser = argparse.ArgumentParser("Apply Downloaded Update") -    parser.add_argument('--dir', dest = 'download_dir', help = 'directory to find installable', required=True) -    parser.add_argument('--pkey', dest = 'platform_key', help =' OS: lnx|mac|win', required=True) -    parser.add_argument('--log_file', dest = 'log_file', default = None, help = 'file to write messages to') -    args = parser.parse_args() -     -    if args.log_file: -        try: -            f = open(args.log_file,'w+')  -        except: -            print "%s could not be found or opened" % args.log_file -            sys.exit(1) -     -    result = apply_update(download_dir = args.download_dir, platform_key = args.platform_key, log_file_handle = f) -    if not result: -        sys.exit("Update failed") -    else: -        sys.exit(0) - - -if __name__ == "__main__": -    main() | 
