From dec4f9b4be6936ad4b342eb6030c740359713f06 Mon Sep 17 00:00:00 2001 From: Nicky Date: Sun, 26 Aug 2012 12:56:13 +0200 Subject: Gracefully handle 'Started' status. Ignore it and continue login. --- indra/viewer_components/login/lllogin.cpp | 10 ++++++++++ 1 file changed, 10 insertions(+) (limited to 'indra/viewer_components') diff --git a/indra/viewer_components/login/lllogin.cpp b/indra/viewer_components/login/lllogin.cpp index d480b63094..bdcb068200 100644 --- a/indra/viewer_components/login/lllogin.cpp +++ b/indra/viewer_components/login/lllogin.cpp @@ -271,6 +271,16 @@ void LLLogin::Impl::login_(LLCoros::self& self, std::string uri, LLSD login_para } return; // Done! } + + /* Sometimes we end with "Started" here. Slightly slow server? + * Seems to be ok to just skip it. Otherwise we'd error out and crash in the if below. + */ + if( status == "Started") + { + LL_DEBUGS("LLLogin") << mAuthResponse << LL_ENDL; + continue; + } + // If we don't recognize status at all, trouble if (! (status == "CURLError" || status == "XMLRPCError" -- cgit v1.2.3 From 3653727e7f84f10caefb6ea7dc33859455ebfa0b Mon Sep 17 00:00:00 2001 From: Nat Goodspeed Date: Wed, 10 Oct 2012 14:57:43 -0400 Subject: Introduce new LLDir::findSkinnedFilenames() method. Use as needed. In a number of different places, for different reasons, the viewer wants to load a UI-related file that might be overridden by a non-default skin; and within that skin, might further be overridden by a non-default language. Apparently, for each of those use cases, every individual developer approached it as an entirely new problem, solving it idiosyncratically for that one case. Not only is this a maintenance problem, but it rubs one's nose in the fact that most such solutions consider only a subset of the relevant skin directories. Richard and I evolved an API intended to address all such cases: a central LLDir method returning a list of relevant pathnames, from most general to most localized, filtered to present only existing files; plus a couple of convenience methods to specifically obtain the most general and most localized available file. There were several load-skinned-file methods (LLFloater::buildFromFile(), LLPanel::buildFromFile() and LLUICtrlFactory::createFromFile() -- apparently cloned-and-modified from each other) that contained funky bolted-on logic to output the loaded data to an optional passed LLXMLNodePtr param. The trouble is that passing that param forced each of these methods to subvert its normal search: specifically for that case, it needed to find the baseline XML file instead of the localized one. Richard agreed that for the intended usage (reformatting XML files) we should use XML schema instead, and that the hacky functionality should be removed. Remove it. Also remove LLUICtrlFactory::getLocalizedXMLNode(), only used for those three special cases. Some callers explicitly passed the optional LLXMLNodePtr param as NULL. Remove that. Remove LLFloaterUIPreview::displayFloater(save) param, which relied on the optional output LLXMLNodePtr param. Make onClickSaveFloater() and onClickSaveAll() emit popupAndPrintWarning() about discontinued functionality. Recast LLFloater::buildFromFile(), LLPanel::buildFromFile(), LLUICtrlFactory::createFromFile(), LLNotifications::loadTemplates(), LLUI::locateSkin(), LLFontRegistry::parseFontInfo(), LLUIColorTable::loadFromSettings(), LLUICtrlFactory::loadWidgetTemplate(), LLUICtrlFactory::getLayeredXMLNode(), LLUIImageList::initFromFile(), LLAppViewer::launchUpdater() and LLMediaCtrl::navigateToLocalPage() to use findSkinnedFilenames(). (Is LLAppViewer::launchUpdater() ever called any more? Apparently so -- though the linux-updater.bin logic to process the relevant command-line switch has been disabled. Shrug.) (Is LLMediaCtrl::navigateToLocalPage() ever used?? If so, why?) Remove LLUI::setupPaths(), getXUIPaths(), getSkinPath() and getLocalizedSkinPath(). Remove the skins/paths.xml file read by setupPaths(). The only configuration it contained was the pair of partial paths "xui/en" and "xui/[LANGUAGE]" -- hardly likely to change. getSkinPath() specifically returned the first of these, while getLocalizedSkinPath() specifically returned the second. This knowledge is now embedded in findSkinnedFilenames(). Also remove paths.xml from viewer_manifest.py. Remove injected xui_paths from LLFontGL::initClass() and LLFontRegistry::LLFontRegistry(). These are no longer needed since LLFontRegistry can now directly consult LLDir for its path search. Stop passing LLUI::getXUIPaths() to LLFontGL::initClass() in LLViewerWindow's constructor and initFonts() method. Add LLDir::append() and add() methods for the simple task of combining two path components separated by getDirDelimiter() -- but only if they're both non-empty. Amazing how often that logic is replicated. Replace some existing concatenations with add() or append(). New LLDir::findSkinnedFilenames() method must know current language. Allow injecting current language by adding an LLDir::setSkinFolder(language) param, and pass it where LLAppViewer::init() and initConfiguration() currently call setSkinFolder(). Also add LLDir::getSkinFolder() and getLanguage() methods. Change LLFLoaterUIPreview's LLLocalizationResetForcer helper to "forcibly reset language" using LLDir::setSkinFolder() instead of LLUI::setupPaths(). Update LLDir stubs in lldir_stub.cpp and llupdaterservice_test.cpp. Add LLDir::getUserDefaultSkinDir() to obtain often-overlooked possible skin directory -- like getUserSkinDir() but with "default" in place of the current skin name as the last path component. (However, we hope findSkinnedFilenames() obviates most explicit use of such individual skin directory pathnames.) Add LLDir unit tests for new findSkinnedFilenames() and add() methods -- the latter exercises append() as well. Tweak indra/integration_tests/llui_libtest/llui_libtest.cpp for all the above. Notably, comment out its export_test_floaters() function, since the essential LLFloater::buildFromFile(optional LLXMLNodePtr) functionality has been removed. This may mean that llui_libtest.cpp has little remaining value, not sure. --- indra/viewer_components/updater/tests/llupdaterservice_test.cpp | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) (limited to 'indra/viewer_components') diff --git a/indra/viewer_components/updater/tests/llupdaterservice_test.cpp b/indra/viewer_components/updater/tests/llupdaterservice_test.cpp index 7c016fecf9..db52e6c55f 100644 --- a/indra/viewer_components/updater/tests/llupdaterservice_test.cpp +++ b/indra/viewer_components/updater/tests/llupdaterservice_test.cpp @@ -78,7 +78,9 @@ S32 LLDir::deleteFilesInDir(const std::string &dirname, void LLDir::setChatLogsDir(const std::string &path){} void LLDir::setPerAccountChatLogsDir(const std::string &username){} void LLDir::setLindenUserDir(const std::string &username){} -void LLDir::setSkinFolder(const std::string &skin_folder){} +void LLDir::setSkinFolder(const std::string &skin_folder, const std::string& language){} +std::string LLDir::getSkinFolder() const { return "default"; } +std::string LLDir::getLanguage() const { return "en"; } bool LLDir::setCacheDir(const std::string &path){ return true; } void LLDir::dumpCurrentDirectories() {} -- cgit v1.2.3 From 374f20edf09ff8194c715d190c114eaacac00bfe Mon Sep 17 00:00:00 2001 From: Dave Parks Date: Wed, 3 Oct 2012 14:30:21 -0500 Subject: Fix non-thread-safe refcounting of LLHTTPClient::Responder and fix out-of-order deletion of LLTextureFetch on shutdown --- .../viewer_components/updater/llupdatechecker.cpp | 39 +--------------------- indra/viewer_components/updater/llupdatechecker.h | 34 +++++++++++++++++-- 2 files changed, 33 insertions(+), 40 deletions(-) (limited to 'indra/viewer_components') diff --git a/indra/viewer_components/updater/llupdatechecker.cpp b/indra/viewer_components/updater/llupdatechecker.cpp index 4da774a5f6..5edbbf9914 100644 --- a/indra/viewer_components/updater/llupdatechecker.cpp +++ b/indra/viewer_components/updater/llupdatechecker.cpp @@ -51,37 +51,6 @@ public: }; -class LLUpdateChecker::Implementation: - public LLHTTPClient::Responder -{ -public: - Implementation(Client & client); - ~Implementation(); - void checkVersion(std::string const & protocolVersion, std::string const & hostUrl, - std::string const & servicePath, std::string channel, std::string version); - - // Responder: - virtual void completed(U32 status, - const std::string & reason, - const LLSD& content); - virtual void error(U32 status, const std::string & reason); - -private: - static const char * sProtocolVersion; - - Client & mClient; - LLHTTPClient mHttpClient; - bool mInProgress; - std::string mVersion; - - std::string buildUrl(std::string const & protocolVersion, std::string const & hostUrl, - std::string const & servicePath, std::string channel, std::string version); - - LOG_CLASS(LLUpdateChecker::Implementation); -}; - - - // LLUpdateChecker //----------------------------------------------------------------------------- @@ -134,13 +103,7 @@ void LLUpdateChecker::Implementation::checkVersion(std::string const & protocolV std::string checkUrl = buildUrl(protocolVersion, hostUrl, servicePath, channel, version); LL_INFOS("UpdateCheck") << "checking for updates at " << checkUrl << llendl; - // The HTTP client will wrap a raw pointer in a boost::intrusive_ptr causing the - // passed object to be silently and automatically deleted. We pass a self- - // referential intrusive pointer to which we add a reference to keep the - // client from deleting the update checker implementation instance. - LLHTTPClient::ResponderPtr temporaryPtr(this); - boost::intrusive_ptr_add_ref(temporaryPtr.get()); - mHttpClient.get(checkUrl, temporaryPtr); + mHttpClient.get(checkUrl, this); } void LLUpdateChecker::Implementation::completed(U32 status, diff --git a/indra/viewer_components/updater/llupdatechecker.h b/indra/viewer_components/updater/llupdatechecker.h index d882169068..23f62a7c5e 100644 --- a/indra/viewer_components/updater/llupdatechecker.h +++ b/indra/viewer_components/updater/llupdatechecker.h @@ -29,6 +29,7 @@ #include +#include "llhttpclient.h" // // Implements asynchronous checking for updates. @@ -36,7 +37,36 @@ class LLUpdateChecker { public: class Client; - class Implementation; + class Implementation: + + public LLHTTPClient::Responder + { + public: + Implementation(Client & client); + ~Implementation(); + void checkVersion(std::string const & protocolVersion, std::string const & hostUrl, + std::string const & servicePath, std::string channel, std::string version); + + // Responder: + virtual void completed(U32 status, + const std::string & reason, + const LLSD& content); + virtual void error(U32 status, const std::string & reason); + + private: + static const char * sProtocolVersion; + + Client & mClient; + LLHTTPClient mHttpClient; + bool mInProgress; + std::string mVersion; + + std::string buildUrl(std::string const & protocolVersion, std::string const & hostUrl, + std::string const & servicePath, std::string channel, std::string version); + + LOG_CLASS(LLUpdateChecker::Implementation); + }; + // An exception that may be raised on check errors. class CheckError; @@ -48,7 +78,7 @@ public: std::string const & servicePath, std::string channel, std::string version); private: - boost::shared_ptr mImplementation; + LLPointer mImplementation; }; -- cgit v1.2.3 From eca619985206462d39dc9ae665857e97948562da Mon Sep 17 00:00:00 2001 From: Aura Linden Date: Mon, 12 Nov 2012 18:06:32 -0800 Subject: Ported slplugin and some other missing components for cocoa. --- indra/viewer_components/updater/tests/llupdaterservice_test.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'indra/viewer_components') diff --git a/indra/viewer_components/updater/tests/llupdaterservice_test.cpp b/indra/viewer_components/updater/tests/llupdaterservice_test.cpp index 7c016fecf9..f0d3fcbd07 100644 --- a/indra/viewer_components/updater/tests/llupdaterservice_test.cpp +++ b/indra/viewer_components/updater/tests/llupdaterservice_test.cpp @@ -63,7 +63,7 @@ class LLDir_Mock : public LLDir const std::string &mask, std::string &fname) {} std::string getCurPath() { return ""; } - BOOL fileExists(const std::string &filename) const { return false; } + bool fileExists(const std::string &filename) const { return false; } std::string getLLPluginLauncher() { return ""; } std::string getLLPluginFilename(std::string base_name) { return ""; } -- cgit v1.2.3 From 34f231cc66bc746228fe367712447058d76757b3 Mon Sep 17 00:00:00 2001 From: Nat Goodspeed Date: Wed, 9 Jan 2013 20:39:06 -0500 Subject: MAINT-1481: remove linux-updater; move logic to Linux update_install Now that the viewer's own background updater logic is responsible for downloading a new installer, the only functionality we still use in linux-updater that couldn't be expressed more simply in bash is the UI. But since most Linux distros capable of running SL at all have zenity, and all will have xmessage, we can handle even the UI part. Add xmenity wrapper script so update_install doesn't have to care which is present, and make the bash script that used to launch linux-updater do the real work. --- .../updater/scripts/linux/update_install | 151 ++++++++++++++++++++- .../updater/scripts/linux/xmenity | 55 ++++++++ 2 files changed, 200 insertions(+), 6 deletions(-) create mode 100755 indra/viewer_components/updater/scripts/linux/xmenity (limited to 'indra/viewer_components') diff --git a/indra/viewer_components/updater/scripts/linux/update_install b/indra/viewer_components/updater/scripts/linux/update_install index e0505a9f72..7c08966830 100644 --- a/indra/viewer_components/updater/scripts/linux/update_install +++ b/indra/viewer_components/updater/scripts/linux/update_install @@ -1,10 +1,149 @@ #! /bin/bash -INSTALL_DIR=$(cd "$(dirname "$0")/.." ; pwd) -export LD_LIBRARY_PATH="$INSTALL_DIR/lib" -bin/linux-updater.bin --file "$1" --dest "$INSTALL_DIR" --name "Second Life Viewer" --stringsdir "$INSTALL_DIR/skins/default/xui/en" --stringsfile "strings.xml" -if [ $? -ne 0 ] - then echo $3 >> "$2" +# @file update_install +# @author Nat Goodspeed +# @date 2013-01-09 +# @brief Update the containing Second Life application bundle to the version in +# the specified tarball. +# +# This bash implementation is derived from the previous linux-updater.bin +# application. +# +# $LicenseInfo:firstyear=2013&license=viewerlgpl$ +# Copyright (c) 2013, Linden Research, Inc. +# $/LicenseInfo$ + +tarball="$1" # the file to install +markerfile="$2" # create this file on failure +mandatory="$3" # what to write to markerfile on failure + +function log { + # our log file will be open as stderr -- but until we set up that + # redirection, logging to stderr is better than nothing + echo "$*" 1>&2 +} + +function status { + log "$@" + # Prefix with '#' so xmenity will recognize it as a status message + echo "#$*" +} + +function fail { + # Log the message + log "$@" + # tell subsequent viewer things went south + echo "$mandatory" > "$markerfile" + # add boilerplate + local msg="An error occurred while updating Second Life: +$* +Please download the latest viewer from www.secondlife.com." + # Restate test from xmenity to detect whether we can use zenity or must + # fall back to xmessage + zenpath="$(which zenity)" + if [ -n "$zenpath" -a -x "$zenpath" ] + then "$zenpath" --error --title "Second Life Viewer Updater" \ + --width=320 --height=120 --text="$msg" + else xmessage -buttons -OK:2 -center "$msg" + fi + exit 1 +} + +function sudo_mv { + # If we have write permission to both parent directories, shouldn't need + # sudo. + if [ -w "$(dirname "$1")" -a -w "$(dirname "$2")" ] + then mv "$1" "$2" || fail "Couldn't move $1 to $2" + else # use one of the likely sudo programs + sudo="$(which gksudo)" + if [ -z "$sudo" ] + then sudo="$(which kdesu)" + fi + if [ -z "$sudo" ] + then # couldn't find either one, just try it anyway + mv "$1" "$2" || fail "Couldn't move $1 to $2" + else # even with sudo, could fail, e.g. different filesystems + "$sudo" mv "$1" "$2" || fail "Couldn't move $1 to $2" + fi + fi +} + +# empty array +cleanups=() + +function cleanup { + # wacky bash syntax for appending to array + cleanups[${#cleanups[*]}]="$*" +} + +function onexit { + for action in "${cleanups[@]}" + do # don't quote, support actions consisting of multiple words + $action + done +} + +trap 'onexit' EXIT + +mydir="$(dirname "$0")" +# We happen to know that the viewer specifies a marker-file pathname within +# the logs directory. +logsdir="$(dirname "$markerfile")" +logname="$logsdir/updater.log" + +# move aside old updater.log; we're about to create a new one +[ -f "$logname" ] && mv "$logname" "$logname.old" + +# Set up redirections for this script such that stderr is logged, while +# special stdout messages drive our UI, as described in xmenity. +exec 2> "$logname" | "$mydir/xmenity" +# Piping to xmenity requires that we end with a line consisting of the string +# "100" to terminate zenity progress bar. +cleanup echo 100 + +# Rather than setting up a special pipeline to timestamp every line of stderr, +# produce header lines into log file indicating timestamp and the arguments +# with which we were invoked. +date 1>&2 +log "$0 $*" + +# Log every command we execute, along with any stderr it might produce +set -x + +status 'Installing Second Life...' + +# Creating tempdir under /tmp means it's possible that tempdir is on a +# different filesystem than INSTALL_DIR. One is tempted to create tempdir on a +# path derived from `dirname INSTALL_DIR`, but then we might need to add +# another sudo prompt to create it. +tempdir="/tmp/$(basename "$0").$$" +tempinstall="$tempdir/install" +mkdir -p "$tempinstall" || fail "Couldn't create $tempinstall" +cleanup rm -rf "$tempdir" + +# If we already knew the name of the tarball's top-level directory, we could +# just move that when all was said and done. Since we don't, untarring to the +# 'install' subdir with --strip 1 effectively renames that top-level +# directory. +tar --strip 1 -xjf "$tarball" -C "$tempinstall" || fail "Untar command failed" + +INSTALL_DIR="$(cd "$mydir/.." ; pwd)" + +# Considering we're launched from a subdirectory of INSTALL_DIR, would be +# surprising if it did NOT already exist... +if [ -f "$INSTALL_DIR" ] +then backup="$INSTALL_DIR.backup" + backupn=1 + while [ -f "$backup" ] + do backup="$INSTALL_DIR.backup.$backupn" + ((backupn += 1)) + done + sudo_mv "$INSTALL_DIR" "$backup" fi +# We unpacked the tarball into tempinstall. Move that. +sudo_mv "$tempinstall" "$INSTALL_DIR" + +rm -f "$tarball" -rm -f "$1" +# launch the updated viewer +"$INSTALL_DIR/secondlife" & diff --git a/indra/viewer_components/updater/scripts/linux/xmenity b/indra/viewer_components/updater/scripts/linux/xmenity new file mode 100755 index 0000000000..c0c033904c --- /dev/null +++ b/indra/viewer_components/updater/scripts/linux/xmenity @@ -0,0 +1,55 @@ +#!/bin/bash + +# @file xmenity +# @author Nat Goodspeed +# @date 2013-01-09 +# @brief Provide progress UI for bash scripts (e.g. update_install) using +# zenity if available, xmessage if not. +# +# $LicenseInfo:firstyear=2013&license=viewerlgpl$ +# Copyright (c) 2013, Linden Research, Inc. +# $/LicenseInfo$ + +# This script invokes either zenity --progress or, if zenity is unavailable, +# wraps xmessage in a zenity-like interface. That is its mutant power. +# Pass $1 as the title for your zenity box. It is ignored by xmessage. +# Send updates on stdin: +# A line containing only a decimal integer from 0 - 100 sets that progress. +# End with 100 to tell zenity to terminate. +# A line starting with '#' replaces the progress text. +# All other stdin lines are ignored. + +zenpath="$(which zenity)" +if [ -n "$zenpath" -a -x "$zenpath" ] +then # if executable zenity is on PATH, run that instead of this. + exec "$zenpath" --progress --title="$1" --auto-close --width=320 --height=120 +fi + +# Arriving here means we don't have zenity available. The remainder of this +# script is the xmessage wrapper. + +# We operate by leaving one background xmessage process running. This is the +# pid of that process. +xmpid="" + +function clear_message { + [ -n "$xmpid" ] && kill $xmpid + xmpid="" +} + +# Cancel any pending xmessage, regardless of how we exit. +trap 'clear_message' EXIT + +while read line +do # terminate like zenity --progress + [ "$line" == "100" ] && break + # ignore everything but replacement text + nohash="${line#'#'}" + # if stripping leading hash doesn't change line, it doesn't have one + [ "$nohash" == "$line" ] && continue + # clear any previous message + clear_message + # put up a new xmessage and capture its pid + xmessage -buttons OK:2 -center "$nohash" & + xmpid=$! +done -- cgit v1.2.3 From 6e9782f79f6d3cac2bfeb72c6cd43b409020c76e Mon Sep 17 00:00:00 2001 From: Nat Goodspeed Date: Thu, 10 Jan 2013 09:40:20 -0500 Subject: MAINT-1481: minor bug fix plus incomplete UI tweaks. Test for existence of target name using -e rather than -f. (-d would work too, but in this case we must respond to any name collision, whether file or directory.) Instead of terminating on failure, make sudo_mv return rc of the [sudo] mv command to its caller. If the attempt to move new install to actual viewer directory fails, restore previous viewer before failing. When redirecting the script's stderr to updater.log, first save existing stderr to another file descriptor, and restore it when we launch viewer. Otherwise updater.log ends up collecting the viewer's duplicate stderr log output! The construct 'exec ... | program' doesn't work. In fact it causes any other redirections on that command to fail too. Remove it -- real fix pending. --- .../updater/scripts/linux/update_install | 30 +++++++++++++--------- 1 file changed, 18 insertions(+), 12 deletions(-) (limited to 'indra/viewer_components') diff --git a/indra/viewer_components/updater/scripts/linux/update_install b/indra/viewer_components/updater/scripts/linux/update_install index 7c08966830..167e2b7881 100644 --- a/indra/viewer_components/updater/scripts/linux/update_install +++ b/indra/viewer_components/updater/scripts/linux/update_install @@ -53,7 +53,7 @@ function sudo_mv { # If we have write permission to both parent directories, shouldn't need # sudo. if [ -w "$(dirname "$1")" -a -w "$(dirname "$2")" ] - then mv "$1" "$2" || fail "Couldn't move $1 to $2" + then mv "$1" "$2" else # use one of the likely sudo programs sudo="$(which gksudo)" if [ -z "$sudo" ] @@ -61,9 +61,9 @@ function sudo_mv { fi if [ -z "$sudo" ] then # couldn't find either one, just try it anyway - mv "$1" "$2" || fail "Couldn't move $1 to $2" + mv "$1" "$2" else # even with sudo, could fail, e.g. different filesystems - "$sudo" mv "$1" "$2" || fail "Couldn't move $1 to $2" + "$sudo" mv "$1" "$2" fi fi } @@ -94,9 +94,9 @@ logname="$logsdir/updater.log" # move aside old updater.log; we're about to create a new one [ -f "$logname" ] && mv "$logname" "$logname.old" -# Set up redirections for this script such that stderr is logged, while -# special stdout messages drive our UI, as described in xmenity. -exec 2> "$logname" | "$mydir/xmenity" +# Set up redirections for this script such that stderr is logged. (But first +# move the previous stderr to file descriptor 3.) +exec 3>&2- 2> "$logname" # Piping to xmenity requires that we end with a line consisting of the string # "100" to terminate zenity progress bar. cleanup echo 100 @@ -131,19 +131,25 @@ INSTALL_DIR="$(cd "$mydir/.." ; pwd)" # Considering we're launched from a subdirectory of INSTALL_DIR, would be # surprising if it did NOT already exist... -if [ -f "$INSTALL_DIR" ] +if [ -e "$INSTALL_DIR" ] then backup="$INSTALL_DIR.backup" backupn=1 - while [ -f "$backup" ] + while [ -e "$backup" ] do backup="$INSTALL_DIR.backup.$backupn" ((backupn += 1)) done - sudo_mv "$INSTALL_DIR" "$backup" + sudo_mv "$INSTALL_DIR" "$backup" || fail "Couldn't move $INSTALL_DIR to $backup" fi # We unpacked the tarball into tempinstall. Move that. -sudo_mv "$tempinstall" "$INSTALL_DIR" +if ! sudo_mv "$tempinstall" "$INSTALL_DIR" +then # If we failed to move the temp install to INSTALL_DIR, try to restore + # INSTALL_DIR from backup + sudo_mv "$backup" "$INSTALL_DIR" + fail "Couldn't move $1 to $2" +fi rm -f "$tarball" -# launch the updated viewer -"$INSTALL_DIR/secondlife" & +# Launch the updated viewer. Restore original stderr from file descriptor 3, +# though -- otherwise updater.log gets cluttered with the viewer log! +"$INSTALL_DIR/secondlife" 2>&3- & -- cgit v1.2.3 From 83f625445b87b8c5cb53c1a152f03402c0606dee Mon Sep 17 00:00:00 2001 From: Nat Goodspeed Date: Fri, 11 Jan 2013 12:24:44 -0500 Subject: MAINT-1481: Remove xmenity script and viewer_manifest.py references. --- .../updater/scripts/linux/xmenity | 55 ---------------------- 1 file changed, 55 deletions(-) delete mode 100755 indra/viewer_components/updater/scripts/linux/xmenity (limited to 'indra/viewer_components') diff --git a/indra/viewer_components/updater/scripts/linux/xmenity b/indra/viewer_components/updater/scripts/linux/xmenity deleted file mode 100755 index c0c033904c..0000000000 --- a/indra/viewer_components/updater/scripts/linux/xmenity +++ /dev/null @@ -1,55 +0,0 @@ -#!/bin/bash - -# @file xmenity -# @author Nat Goodspeed -# @date 2013-01-09 -# @brief Provide progress UI for bash scripts (e.g. update_install) using -# zenity if available, xmessage if not. -# -# $LicenseInfo:firstyear=2013&license=viewerlgpl$ -# Copyright (c) 2013, Linden Research, Inc. -# $/LicenseInfo$ - -# This script invokes either zenity --progress or, if zenity is unavailable, -# wraps xmessage in a zenity-like interface. That is its mutant power. -# Pass $1 as the title for your zenity box. It is ignored by xmessage. -# Send updates on stdin: -# A line containing only a decimal integer from 0 - 100 sets that progress. -# End with 100 to tell zenity to terminate. -# A line starting with '#' replaces the progress text. -# All other stdin lines are ignored. - -zenpath="$(which zenity)" -if [ -n "$zenpath" -a -x "$zenpath" ] -then # if executable zenity is on PATH, run that instead of this. - exec "$zenpath" --progress --title="$1" --auto-close --width=320 --height=120 -fi - -# Arriving here means we don't have zenity available. The remainder of this -# script is the xmessage wrapper. - -# We operate by leaving one background xmessage process running. This is the -# pid of that process. -xmpid="" - -function clear_message { - [ -n "$xmpid" ] && kill $xmpid - xmpid="" -} - -# Cancel any pending xmessage, regardless of how we exit. -trap 'clear_message' EXIT - -while read line -do # terminate like zenity --progress - [ "$line" == "100" ] && break - # ignore everything but replacement text - nohash="${line#'#'}" - # if stripping leading hash doesn't change line, it doesn't have one - [ "$nohash" == "$line" ] && continue - # clear any previous message - clear_message - # put up a new xmessage and capture its pid - xmessage -buttons OK:2 -center "$nohash" & - xmpid=$! -done -- cgit v1.2.3 From 9e755ee98d6851154874a735c559c80509d7501d Mon Sep 17 00:00:00 2001 From: Nat Goodspeed Date: Fri, 11 Jan 2013 12:36:03 -0500 Subject: MAINT-1481: Clean up update_install UI, including error output. Capture actual error output from mkdir and mv; display it to user. Introduce mysudo function used by sudo_mv function for graphical sudo command. Since update_install actually only displays a single status message, just use zenity --info instead of a zenity progress box: need not update its message. Borrow semantics for clear_message and status functions from xmenity script. Introduce errorbox function so we only have to make zenity/xmessage test once. Move cleanup, onexit to top so we can use for clear_message. --- .../updater/scripts/linux/update_install | 164 ++++++++++++++------- 1 file changed, 113 insertions(+), 51 deletions(-) (limited to 'indra/viewer_components') diff --git a/indra/viewer_components/updater/scripts/linux/update_install b/indra/viewer_components/updater/scripts/linux/update_install index 167e2b7881..0f624c4dee 100644 --- a/indra/viewer_components/updater/scripts/linux/update_install +++ b/indra/viewer_components/updater/scripts/linux/update_install @@ -13,78 +13,136 @@ # Copyright (c) 2013, Linden Research, Inc. # $/LicenseInfo$ +# **************************************************************************** +# script parameters +# **************************************************************************** tarball="$1" # the file to install markerfile="$2" # create this file on failure mandatory="$3" # what to write to markerfile on failure +# **************************************************************************** +# helper functions +# **************************************************************************** +# empty array +cleanups=() + +# add a cleanup action to execute on exit +function cleanup { + # wacky bash syntax for appending to array + cleanups[${#cleanups[*]}]="$*" +} + +# called implicitly on exit +function onexit { + for action in "${cleanups[@]}" + do # don't quote, support actions consisting of multiple words + $action + done +} +trap 'onexit' EXIT + +# write to log file function log { # our log file will be open as stderr -- but until we set up that # redirection, logging to stderr is better than nothing echo "$*" 1>&2 } -function status { - log "$@" - # Prefix with '#' so xmenity will recognize it as a status message - echo "#$*" +# We display status by leaving one background xmessage process running. This +# is the pid of that process. +statuspid="" + +function clear_message { + [ -n "$statuspid" ] && kill $statuspid + statuspid="" } +# make sure we remove any message box we might have put up +cleanup clear_message + +# can we use zenity, or must we fall back to xmessage? +zenpath="$(which zenity)" +if [ -n "$zenpath" ] +then # zenity on PATH and is executable + # display a message box and continue + function status { + # clear any previous message + clear_message + # put up a new zenity box and capture its pid + "$zenpath" --info --title "Second Life Viewer Updater" \ + --width=320 --height=120 --text="$*" & + statuspid=$! + } + + # display an error box and wait for user + function errorbox { + "$zenpath" --error --title "Second Life Viewer Updater" \ + --width=320 --height=120 --text="$*" + } + +else # no zenity, use xmessage instead + # display a message box and continue + function status { + # clear any previous message + clear_message + # put up a new xmessage and capture its pid + xmessage -buttons OK:2 -center "$*" & + statuspid=$! + } + + # display an error box and wait for user + function errorbox { + xmessage -buttons OK:2 -center "$*" + } +fi + +# display an error box and terminate function fail { # Log the message log "$@" # tell subsequent viewer things went south echo "$mandatory" > "$markerfile" # add boilerplate - local msg="An error occurred while updating Second Life: + errorbox "An error occurred while updating Second Life: $* Please download the latest viewer from www.secondlife.com." - # Restate test from xmenity to detect whether we can use zenity or must - # fall back to xmessage - zenpath="$(which zenity)" - if [ -n "$zenpath" -a -x "$zenpath" ] - then "$zenpath" --error --title "Second Life Viewer Updater" \ - --width=320 --height=120 --text="$msg" - else xmessage -buttons -OK:2 -center "$msg" - fi exit 1 } +# Find a graphical sudo program and define mysudo function. On error, $? is +# nonzero; output is in $err instead of being written to stdout/stderr. +gksudo="$(which gksudo)" +kdesu="$(which kdesu)" +if [ -n "$gksudo" ] +then function mysudo { + # gksudo allows you to specify description + err="$("$gksudo" --description "Second Life Viewer Updater" "$@" 2>&1)" + } +elif [ -n "$kdesu" ] +then function mysudo { + err="$("$kdesu" "$@" 2>&1)" + } +else # couldn't find either one, just try it anyway + function mysudo { + err="$("$@" 2>&1)" + } +fi + +# Move directories, using mysudo if we think it necessary. On error, $? is +# nonzero; output is in $err instead of being written to stdout/stderr. function sudo_mv { # If we have write permission to both parent directories, shouldn't need # sudo. if [ -w "$(dirname "$1")" -a -w "$(dirname "$2")" ] - then mv "$1" "$2" - else # use one of the likely sudo programs - sudo="$(which gksudo)" - if [ -z "$sudo" ] - then sudo="$(which kdesu)" - fi - if [ -z "$sudo" ] - then # couldn't find either one, just try it anyway - mv "$1" "$2" - else # even with sudo, could fail, e.g. different filesystems - "$sudo" mv "$1" "$2" - fi + then err="$(mv "$@" 2>&1)" + else # use available sudo program; mysudo sets $? and $err + mysudo mv "$@" fi } -# empty array -cleanups=() - -function cleanup { - # wacky bash syntax for appending to array - cleanups[${#cleanups[*]}]="$*" -} - -function onexit { - for action in "${cleanups[@]}" - do # don't quote, support actions consisting of multiple words - $action - done -} - -trap 'onexit' EXIT - +# **************************************************************************** +# main script logic +# **************************************************************************** mydir="$(dirname "$0")" # We happen to know that the viewer specifies a marker-file pathname within # the logs directory. @@ -97,9 +155,6 @@ logname="$logsdir/updater.log" # Set up redirections for this script such that stderr is logged. (But first # move the previous stderr to file descriptor 3.) exec 3>&2- 2> "$logname" -# Piping to xmenity requires that we end with a line consisting of the string -# "100" to terminate zenity progress bar. -cleanup echo 100 # Rather than setting up a special pipeline to timestamp every line of stderr, # produce header lines into log file indicating timestamp and the arguments @@ -114,17 +169,19 @@ status 'Installing Second Life...' # Creating tempdir under /tmp means it's possible that tempdir is on a # different filesystem than INSTALL_DIR. One is tempted to create tempdir on a -# path derived from `dirname INSTALL_DIR`, but then we might need to add -# another sudo prompt to create it. +# path derived from `dirname INSTALL_DIR` -- but it seems modern 'mv' can +# handle moving across filesystems?? tempdir="/tmp/$(basename "$0").$$" tempinstall="$tempdir/install" -mkdir -p "$tempinstall" || fail "Couldn't create $tempinstall" +# capture the actual error message, if any +err="$(mkdir -p "$tempinstall" 2>&1)" || fail "$err" cleanup rm -rf "$tempdir" # If we already knew the name of the tarball's top-level directory, we could # just move that when all was said and done. Since we don't, untarring to the # 'install' subdir with --strip 1 effectively renames that top-level # directory. +# untar failures tend to be voluminous -- don't even try to capture, just log tar --strip 1 -xjf "$tarball" -C "$tempinstall" || fail "Untar command failed" INSTALL_DIR="$(cd "$mydir/.." ; pwd)" @@ -138,16 +195,21 @@ then backup="$INSTALL_DIR.backup" do backup="$INSTALL_DIR.backup.$backupn" ((backupn += 1)) done - sudo_mv "$INSTALL_DIR" "$backup" || fail "Couldn't move $INSTALL_DIR to $backup" + # on error, fail with actual error message from sudo_mv: permissions, + # cross-filesystem mv, ...? + sudo_mv "$INSTALL_DIR" "$backup" || fail "$err" fi # We unpacked the tarball into tempinstall. Move that. if ! sudo_mv "$tempinstall" "$INSTALL_DIR" then # If we failed to move the temp install to INSTALL_DIR, try to restore - # INSTALL_DIR from backup + # INSTALL_DIR from backup. Save $err because next sudo_mv will trash it! + realerr="$err" sudo_mv "$backup" "$INSTALL_DIR" - fail "Couldn't move $1 to $2" + fail "$realerr" fi +# Removing the tarball here, rather than with a 'cleanup' action, means we +# only remove it if we succeeded. rm -f "$tarball" # Launch the updated viewer. Restore original stderr from file descriptor 3, -- cgit v1.2.3 From 22db60ed0dfd606ab8f8d49141446442a4a72a48 Mon Sep 17 00:00:00 2001 From: Nat Goodspeed Date: Fri, 11 Jan 2013 15:58:50 -0500 Subject: MAINT-1481: use 'mktemp -d' to generate tempdir. Responding to Lex's code-review comments. --- indra/viewer_components/updater/scripts/linux/update_install | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'indra/viewer_components') diff --git a/indra/viewer_components/updater/scripts/linux/update_install b/indra/viewer_components/updater/scripts/linux/update_install index 0f624c4dee..a9df9042fd 100644 --- a/indra/viewer_components/updater/scripts/linux/update_install +++ b/indra/viewer_components/updater/scripts/linux/update_install @@ -171,7 +171,7 @@ status 'Installing Second Life...' # different filesystem than INSTALL_DIR. One is tempted to create tempdir on a # path derived from `dirname INSTALL_DIR` -- but it seems modern 'mv' can # handle moving across filesystems?? -tempdir="/tmp/$(basename "$0").$$" +tempdir="$(mktemp -d)" tempinstall="$tempdir/install" # capture the actual error message, if any err="$(mkdir -p "$tempinstall" 2>&1)" || fail "$err" -- cgit v1.2.3 From af969270990ca719277def274b8ebf20539cc435 Mon Sep 17 00:00:00 2001 From: Merov Linden Date: Mon, 28 Jan 2013 15:41:01 -0800 Subject: Fix test failure --- indra/viewer_components/updater/tests/llupdaterservice_test.cpp | 1 + 1 file changed, 1 insertion(+) (limited to 'indra/viewer_components') diff --git a/indra/viewer_components/updater/tests/llupdaterservice_test.cpp b/indra/viewer_components/updater/tests/llupdaterservice_test.cpp index a49bc4161e..de07beee7c 100644 --- a/indra/viewer_components/updater/tests/llupdaterservice_test.cpp +++ b/indra/viewer_components/updater/tests/llupdaterservice_test.cpp @@ -83,6 +83,7 @@ std::string LLDir::getSkinFolder() const { return "default"; } std::string LLDir::getLanguage() const { return "en"; } bool LLDir::setCacheDir(const std::string &path){ return true; } void LLDir::dumpCurrentDirectories() {} +void LLDir::updatePerAccountChatLogsDir() {} std::string LLDir::getExpandedFilename(ELLPath location, const std::string &filename) const -- cgit v1.2.3