From f92e3e7c49fef4d136ddd7d2e7f817cb0b255f4b Mon Sep 17 00:00:00 2001 From: onefang Date: Tue, 8 Sep 2020 21:31:56 +1000 Subject: Add the old bash scripts. Most of these will eventually be rewritten as C + Lua. --- BuildIt.sh | 44 +++++++ RunIt.sh | 4 + TestIt.sh | 23 ++++ example/config/config.ini | 47 +++++++ example/config/sim_skeleton/ThisSim.ini | 44 +++++++ example/start.sh | 16 +++ scripts/backup-grid.sh | 5 + scripts/backup-inventories.sh | 31 +++++ scripts/backup-inventory | 1 + scripts/backup-sims.sh | 19 +++ scripts/common.sh | 75 +++++++++++ scripts/fix_some_assets.pl | 227 ++++++++++++++++++++++++++++++++ scripts/gitAR.sh | 108 +++++++++++++++ scripts/install/create_sim.sh | 75 +++++++++++ scripts/install/go_live.sh | 12 ++ scripts/install/group_migrate.sql | 48 +++++++ scripts/install/opensim.tmux.conf | 97 ++++++++++++++ scripts/install/secure.sh | 26 ++++ scripts/show-console | 3 + scripts/start-sim | 218 ++++++++++++++++++++++++++++++ 20 files changed, 1123 insertions(+) create mode 100755 BuildIt.sh create mode 100755 RunIt.sh create mode 100755 TestIt.sh create mode 100644 example/config/config.ini create mode 100644 example/config/sim_skeleton/ThisSim.ini create mode 100755 example/start.sh create mode 100755 scripts/backup-grid.sh create mode 100755 scripts/backup-inventories.sh create mode 120000 scripts/backup-inventory create mode 100755 scripts/backup-sims.sh create mode 100755 scripts/common.sh create mode 100755 scripts/fix_some_assets.pl create mode 100755 scripts/gitAR.sh create mode 100755 scripts/install/create_sim.sh create mode 100755 scripts/install/go_live.sh create mode 100644 scripts/install/group_migrate.sql create mode 100644 scripts/install/opensim.tmux.conf create mode 100755 scripts/install/secure.sh create mode 100755 scripts/show-console create mode 100755 scripts/start-sim diff --git a/BuildIt.sh b/BuildIt.sh new file mode 100755 index 0000000..2046ac9 --- /dev/null +++ b/BuildIt.sh @@ -0,0 +1,44 @@ +#!/bin/bash + +# Poor mans git sub modules / subtrees, coz otherwise it gets complex. +#if [ ! -d git-sub-modules/opensim-moneymodule-gloebit ]; then +# pushd git-sub-modules >/dev/null +# git clone https://github.com/gloebit/opensim-moneymodule-gloebit.git +# popd >/dev/null +#else +# pushd git-sub-modules/opensim-moneymodule-gloebit >/dev/null +# git pull +# popd >/dev/null +#fi +#rm -rf addon-modules/Gloebit/GloebitMoneyModule +#cp -r git-sub-modules/opensim-moneymodule-gloebit/addon-modules/Gloebit/GloebitMoneyModule addon-modules/Gloebit/ + +./runprebuild.sh autoclean +# Clean the stuff autoclean forgets to clean. I feel so dirty. +find -name obj -type d -print | xargs /bin/rm -fr +# Clean the stuff the tests created. +rm -fr bin/ScriptEngines +rm Test*.txt +./runprebuild.sh vs2015 + +# Prebuild converts Microsoft.CSharp.targets to Microsoft.CSHARP.Targets, which case sensitive file systems fail to find. +#find -name *.csproj | xargs sed -i "s@Microsoft.CSHARP.Targets@Microsoft.CSharp.targets@g" + +# Debian no longer provides nant. +#./nant-color + +if [ "4" == $(mono -V | head -n 1 | cut -d ' ' -f 5 | cut -d '.' -f 1) ]; then + export XBUILD_COLORS=errors=brightred,warnings=yellow,events=blue + xbuild /target:clean + xbuild /p:TargetFrameworkVersion="v4.5"xbuild /p:TargetFrameworkVersion="v4.5" +else + # Use this for Mono 5 and later. + msbuild /p:Configuration=Release +# msbuild /p:Configuration=Debug +fi + +#cp -f addon-modules/Gloebit/GloebitMoneyModule/bin/Gloebit.dll bin + +pushd src >/dev/null +./BuildIt.sh +popd >/dev/null diff --git a/RunIt.sh b/RunIt.sh new file mode 100755 index 0000000..55ed7c3 --- /dev/null +++ b/RunIt.sh @@ -0,0 +1,4 @@ +#!/bin/bash + +cd bin +./sledjchisl diff --git a/TestIt.sh b/TestIt.sh new file mode 100755 index 0000000..d1ebecf --- /dev/null +++ b/TestIt.sh @@ -0,0 +1,23 @@ +#!/bin/bash + +export MONO_THREADS_PER_CPU=100 + +# For printing out line numbers use "exec /usr/bin/cli --debug /usr/lib/nunit/nunit-console.exe" instead of "nunit-console". + +echo "Standard tests." +mkdir -p ../db +nunit-console bin/OpenSim.Tests.dll bin/OpenSim.Framework.Tests.dll bin/OpenSim.Framework.Servers.Tests.dll bin/OpenSim.Framework.Serialization.Tests.dll bin/OpenSim.Region.ClientStack.LindenCaps.Tests.dll bin/OpenSim.Region.ClientStack.LindenUDP.Tests.dll bin/OpenSim.Region.ScriptEngine.Tests.dll bin/OpenSim.Region.CoreModules.Tests.dll bin/OpenSim.Region.Framework.Tests.dll -nologo -output=TestOutput.txt -err=TestError.txt -labels -noxml +echo "SQL tests." +nunit-console bin/OpenSim.Data.Tests.dll -nologo -output=TestSQLOutput.txt -err=TestSQLError.txt -labels -noxml +echo "Standard tests, part two." +nunit-console bin/OpenSim.Capabilities.Handlers.Tests.dll bin/OpenSim.Server.Handlers.Tests.dll bin/OpenSim.Services.InventoryService.Tests.dll bin/OpenSim.Tests.Permissions.dll -nologo -output=Test1Output.txt -err=Test1Error.txt -labels -noxml +echo "Physics tests." +nunit-console bin/OpenSim.Region.PhysicsModule.BulletS.Tests.dll bin/OpenSim.Region.PhysicsModule.Ode.Tests.dll -nologo -output=TestPhysicsOutput.txt -err=TestPhysicsError.txt -labels -noxml +echo "Stress tests." +nunit-console bin/OpenSim.Tests.Stress.dll -nologo -output=TestStressOutput.txt -err=TestStressError.txt -labels -noxml +echo "Performance tests." +nunit-console bin/OpenSim.Tests.Performance.dll -nologo -output=TestPerfOutput.txt -err=TestPerfError.txt -labels -noxml +#echo "Optional tests." +#nunit-console bin/OpenSim.Region.OptionalModules.Tests.dll -nologo -output=TestOptOutput.txt -err=TestOptError.txt -labels -noxml +echo "Robust tests." +nunit-console bin/Robust.Tests.dll -nologo -output=TestRobustOutput.txt -err=TestRobustError.txt -labels -noxml diff --git a/example/config/config.ini b/example/config/config.ini new file mode 100644 index 0000000..e95b04c --- /dev/null +++ b/example/config/config.ini @@ -0,0 +1,47 @@ +; The Const section allows us to define some basic information that we +; will use throughout our configuration. We will provide examples for +; setting the base url of the ROBUST server and the public and private ports +; it uses. Changing the values of the constants will set the operating +; parameters thoughout the configuration. Other constants that may prove +; to be useful may be added to the followin section. They may be +; referenced anywhere in the configuration by using ${Const|Name}. One +; such use is providing a base path for setting locations that ROBUST +; uses to write data. + +; Also put grid specific stuff here. + + +[Paths] + AssetsPath = "../../AssetFiles" + BackupPath = "../../backups" + CachePath = "../../caches" + ConfigPath = "../../config" + DbPath = "../../db" + LogPath = "../../logs" + WebPath = "../../web" + +[Const] + MOTD = "Welcome to your local grid." + + GridName = "localhost Grid" + ShortGridName = "lg" + + ; For a grid these will usually be the externally accessible IP/DNS + ; name and use default public port 8002 and default private port 8003 + ; For a standalone this will usually be the externally accessible IP/DNS + ; name and use default public port 9000. The private port is not used + ; in the configuration for a standalone. + BaseHostname = "127.0.0.1" + HostName = "localhost" + BaseURL = http://${Const|BaseHostname} + GridURL = http://${Const|BaseHostname} + + PublicPort = "8002" + PrivatePort = "8003" + + ; The public port of the ROBUST asset server, which might be different. + AssetServerPort = "8003" + + ; Database credentials. + DataProvider = "OpenSim.Data.MySQL.dll" + ConnectionString = "Data Source=MYSQL_HOST;Database=MYSQL_DB;User ID=MYSQL_USER;Password=MYSQL_PASSWORD;Old Guids=true;" diff --git a/example/config/sim_skeleton/ThisSim.ini b/example/config/sim_skeleton/ThisSim.ini new file mode 100644 index 0000000..44749bb --- /dev/null +++ b/example/config/sim_skeleton/ThisSim.ini @@ -0,0 +1,44 @@ +[Const] + mysim="SIM_NUMBER" + +[Startup] + PIDFile = "${Paths|CachePath}/sim${Const|mysim}.pid" + LogFile = "${Paths|LogPath}/OpenSim_sim${Const|mysim}.log" + StatsLogFile = "${Paths|LogPath}/OpenSimStats_sim${Const|mysim}.log" + ConsoleHistoryFile = "${Paths|LogPath}/OpenSimConsoleHistory_sim${Const|mysim}.txt" + +[Region] + RegionName = "SIM_NAME" + RegionUUID = "SIM_UUID" + Location = "SIM_POS" + InternalPort = "SIM_INT_PORT" + RegionType = "private sim" + SizeX = SIM_SIZE + SizeY = SIM_SIZE + SizeZ = 16384 + MaxAgents = 100 + MaxPrims = 45000 + PhysicalPrimMax = 640 + NonPhysicalPrimMax = 2560 + ClampPrimSize = False + MaptileStaticUUID = "00000000-0000-0000-0000-000000000000" + ; NonPhysicalPrimMin = 0 + ; PhysicalPrimMin = 0 + ; MaxPrimsPerUser = -1 + ; LinksetPrims = 0 + ; DefaultLanding = "<128, 128, 30>" + ; MaptileStaticFile = "" + ; ScopeID = "00000000-0000-0000-0000-000000000000" + ; Datastore = "" + ; ResolveAddress = "" + +[Network] + http_listener_port = SIM_PORT + +[Performance] + ;; Select the performance characteristics of OpenSim. + ; Include-Performance = "config-include/SimFast.ini" + Include-Performance = "config-include/SimBalanced.ini" + ; Include-Performance = "config-include/SimDefault.ini" + ; Include-Performance = "config-include/SimLean.ini" + diff --git a/example/start.sh b/example/start.sh new file mode 100755 index 0000000..c479f78 --- /dev/null +++ b/example/start.sh @@ -0,0 +1,16 @@ +#!/bin/bash + +cd /opt/opensim_SC/current/bin + +source ../../common.sh + +USER=$(whoami) + +if [ $USER = "${OS_USER}" ] +then + SUDO="" +else + SUDO="sudo -Hu ${OS_USER}" +fi + +${SUDO} mono OpenSim.exe -inidirectory=../../config/sim01 diff --git a/scripts/backup-grid.sh b/scripts/backup-grid.sh new file mode 100755 index 0000000..0b762b0 --- /dev/null +++ b/scripts/backup-grid.sh @@ -0,0 +1,5 @@ +#!/bin/bash + +./backup-sims.sh +./backup-inventories.sh +#./backup-assets.sh diff --git a/scripts/backup-inventories.sh b/scripts/backup-inventories.sh new file mode 100755 index 0000000..e4e7158 --- /dev/null +++ b/scripts/backup-inventories.sh @@ -0,0 +1,31 @@ +#!/bin/bash + +source common.sh +getPrgDir + +# Get the database credentials. +declare -A creds +while read -d ';' p; do + k=$(echo ${p} | cut -d '=' -f 1) + v=$(echo ${p} | cut -d '=' -f 2) + creds[${k}]="${v}" +done < <(grep ConnectionString ${PRGDIR}/../../config/config.ini | cut -d '"' -f 2) +# The above seems the best way to get bash to let the creds assignments survive outside the loop. + +# Only backup those that have not logged on since their last backup, but returning prims from sims will bypass this check. +timestamp=$(ls -o --time-style="+%s" ${PRGDIR}/../../backups/.keep | cut -d ' ' -f 5) +touch ${PRGDIR}/../../backups/.keep +# Well it was good in theory, but looks like they broke it in 8.2, no logging in or out updates to GridUser. + +# Get the user names, and back 'em up. +mysql --host="${creds[Data Source]}" "${creds[Database]}" --user="${creds[User ID]}" --password="${creds[Password]}" \ + -e "select FirstName,LastName from UserAccounts,GridUser where UserAccounts.PrincipalID=LEFT(GridUser.UserID,36) and GridUser.Login>${timestamp};" -ss | while read user; do + # Replace tab with space + user=${user// / } + # Find out the size of the last backup, base our later sleep on that, but do it now before backup-inventory packs it away. + sizeSleep=`sleepPerSize i "${user}"` + ${PRGDIR}/backup-inventory "${user}" + # Sleep for a while, so that there is plenty of time to do the backup, + # and we are not keeping the computer very busy if there are lots of users. + sleep ${sizeSleep} +done diff --git a/scripts/backup-inventory b/scripts/backup-inventory new file mode 120000 index 0000000..d326a74 --- /dev/null +++ b/scripts/backup-inventory @@ -0,0 +1 @@ +start-sim \ No newline at end of file diff --git a/scripts/backup-sims.sh b/scripts/backup-sims.sh new file mode 100755 index 0000000..06cb780 --- /dev/null +++ b/scripts/backup-sims.sh @@ -0,0 +1,19 @@ +#!/bin/bash + +source common.sh +getPrgDir + +for i in $(seq -w 1 99) +do + if [ -e "${PRGDIR}/../../config/sim${i}" ] + then + pushd ${PRGDIR}/../../config/sim${i} >/dev/null + # Find out the size of the last backup, base our later sleep on that, but do it now before backup-sim packs it away. + sizeSleep=`sleepPerSize o "$(getSimName ${i})"` + ./backup-sim + # Sleep for a while, so that there is plenty of time to do the backup, + # and we are not keeping the computer very busy if there are lots of sims. + sleep ${sizeSleep} + popd > /dev/null + fi +done diff --git a/scripts/common.sh b/scripts/common.sh new file mode 100755 index 0000000..75aebb0 --- /dev/null +++ b/scripts/common.sh @@ -0,0 +1,75 @@ +#!/bin/echo Don't run this file, it's for common functions." + +OS_PATH="/opt/opensim_SC" +OS_USER="opensimsc" + +# Figure out where we are, most of this mess is to troll through soft links. +# PRGDIR=$(getPrgDir) +getPrgDir() +{ + PRG="$0" + while [ -h "${PRG}" ] ; do + ls=$(ls -ld "${PRG}") + link=`expr "${ls}" : '.*-> \(.*\)$'` + if expr "${link}" : '.*/.*' > /dev/null; then + PRG="${link}" + else + PRG=$(dirname "${PRG}")/"${link}" + fi + done + PRGDIR=$(dirname "${PRG}") + pushd ${PRGDIR} >/dev/null + export PRGDIR=$(pwd) + popd >/dev/null +} + + +# Convert number to sim name +# name=$(num2name 1) +num2name() +{ + /usr/bin/printf 'sim%02d' "$1" +} + + +# Sanitize the name. Not removing [ or ], couldn't get that to work, only important for Windows. +# name=$(sanitize "the name") +sanitize() +{ + echo "$1" | sed -e 's/[\\/:\*\?"<>\|@#$%&\x01-\x1F\x27\x40\x60\x7F. ]/_/g' -e 's/^$/NONAME/' +} + + +# Grab the first Section line of the sims .ini file, cut it down to the name. +# name=$(getSimName 1) +getSimName() +{ + grep "RegionName" ${PRGDIR}/../../config/sim$1/*.ini | head -n 1 | cut -d '"' -f 2 +} + + +# Calculate size of the sleep @ one second per megabyte of combined I/OAR file sizes. +# sleepPerSize o "the name" +# sleepPerSize i "the name" +sleepPerSize() +{ + type="$1" + name=$(sanitize "$2") + + rm -f ${PRGDIR}/../../backups/${name}-sleepPerSize + for file in ${PRGDIR}/../../backups/${name}-*.${type}ar; do + if [ -f ${file} ]; then + # We only loop through them coz bash sucks, we can find the total size now and jump out of the loop. + echo $(du -c -BM ${PRGDIR}/../../backups/${name}-*.${type}ar | tail -n 1 | cut -f 1 | cut -d 'M' -f 1) + touch ${PRGDIR}/../../backups/${name}-sleepPerSize + break + fi + done + + # Sleep 200 instead if we can't find any files. + if [ -f ${PRGDIR}/../../backups/${name}-sleepPerSize ]; then + rm -f ${PRGDIR}/../../backups/${name}-sleepPerSize + else + echo 200 + fi +} diff --git a/scripts/fix_some_assets.pl b/scripts/fix_some_assets.pl new file mode 100755 index 0000000..08fdcb2 --- /dev/null +++ b/scripts/fix_some_assets.pl @@ -0,0 +1,227 @@ +#!/usr/bin/perl +use strict; +use warnings; + + +# Took almost two and a half hours on IG. + + +=pod +# 7/30/2015 3:58PM +Rev B - cleanup +Rev C - added in missing UPDATE + + quthor Jeff Kelley + mods by Fred Beckhusen aka Ferd Frederix + + This version has minimum Perl module dependencies. + + This script connects to an Opensim asset database and scans and fixed bug Mantis-7514 + The files that are fixed have multiple xmlns : in it, such as xmlns:xmlns: + + http://opensimulator.org/mantis/view.php?id=7514 + +############################################################################ +# DO A BACKUP BEFORE YOU ATTEMPT THIS. DO A DRY RUN WITH UPDATE SET TO ZERO # +############################################################################# + + Set variable UPDATE to a 1 to write updates to the db. A 0 will show you what it would change and also save the bad + data to disk in a folder name 'corrupt' for you to examine. + + For safety, we will never update a record unless the UPDATE flag is on. + +############################################################# +# DO NOT RUN THIS UNTIL YOU SET THE CONSTANTS BELOW # +############################################################# + +=cut + +# these are typically found in StandaloneCommon.ini or GridCommon.ini + +my $username = '*****'; +my $password = '*****'; +my $hostname = '*****'; # probably you use localhost for standalone, but it could be an IP address or a DNS name for a asset server. +my $robustDB = '*****'; # your MySQl DB name + +# for safety, we will never update a record unless the UPDATE flag is on. +use constant LISTALL => 0; # show all assets as they are scanned +use constant UPDATE => 0; # set to 1 if you want to actually update the database +use constant MAX => 16000000; # max size of blob from your MySQL ini - see My.ini : max_allowed_packet = 16M, You may need to set this to 64 MB if you have large assets. My largest was over 10 MB..jeepers! +use constant GETMAX => 1; # set to 1 to query MAX object size (see above line) automatically - much slower to start, but less memory is used overall both at the server and at the client +use constant MANTIS7514 => '/tmp/fix_some_assets.ini'; # path to a temp file to keep track of each run. Delete the file to start at the beginning + +# all these modules should already be in core. If not, run "cpan name_of_module', or just go get Strawberry Perl. +use v5.10; # so we can say, and not need to add a newline +use DBI; # database I/O +$|=1; #no buffering STDIO + +my $counter = 0; # count of xmlmns corruption +my $havedone = 0; +my $OddCounter = 0; # other corrupt data + +mkdir 'corrupt'; # save the data in this folder + +my $dbh = DBI->connect( + "dbi:mysql:dbname=$robustDB;host=$hostname", + $username, $password,{RaiseError => 1 , LongReadLen => MAX, LongTruncOk => 0,AutoCommit => 1}, + ) or die $DBI::errstr; + +# Get the largest blob in table data in the DB and set our size of memory buffers to that. +if (GETMAX) { + my $max_len = GetLenData (); + say "Largest object is $max_len bytes"; + $dbh->{LongReadLen} = $max_len; +} + +my $todo; +my $objectsList = GetAssetList(); # get a hash of all objects +$todo = scalar @$objectsList if ref $objectsList; # count them +say "Found $todo objects"; + +for (@$objectsList) { + my $obj_uuid = $_->{id}; + my $obj_name = $_->{name}; + my $obj_time = $_->{create_time}; + + $havedone++; # keep track of how many done + + my $obj_data = GetAssetData ($obj_uuid); # grab the blob + + ValidateXML ($obj_data,$obj_uuid, $obj_name); # repair it and check it + + #save where we are at so we can be stopped and run again some other rainy day + open(my $in_file, ">",MANTIS7514) || die 'Cannot save the last file date'; + print $in_file $obj_time; + close $in_file; +} + +say "Found $counter corrupt xmlns objects"; +say "Found $OddCounter other possibly corrupted objects"; +say "Done!"; + + +sub GetAssetList { + + my $answref; + + my $time = 0; + # read the last run date from a file + if (open(my $in_file, "<",MANTIS7514)) + { + $time = <$in_file> || 0; + close $in_file; + } + my $query = "SELECT id,name, create_time FROM $robustDB.assets WHERE assetType=6 and create_time > $time order by create_time asc;"; + $answref = $dbh->selectall_arrayref ($query, { Slice => {} }); + + return $answref; +} + +sub GetAssetData { + my $uuid = shift; + my $query = "SELECT data FROM $robustDB.assets WHERE id='$uuid';"; + my $answr = $dbh->selectall_arrayref ($query, { Slice => {} }); + return @$answr[0]->{data}; +} + +sub UpdateData { + return unless UPDATE; + my $uuid = shift; + my $data = shift; + + my $sth = $dbh->prepare("UPDATE $robustDB.assets set data = ? WHERE id = ?;"); + $sth->execute($data, $uuid) or die $DBI::errstr;; +} +sub GetLenData { + my $len = $dbh->selectrow_array("SELECT MAX(OCTET_LENGTH(data)) FROM $robustDB.assets WHERE assetType=6;"); +} + + +sub ValidateXML { + my $data = shift; + my $obj_uuid = shift; + my $obj_name = shift || ''; + + #### FORCES AN ERROR FOR DEBUG $data =~ s/xmlns:/xmlns:xmlns:/g; # the fix is in !!!!!!!!! + + # Test for repeated xmlns, clever RegEx by Jeff Kelley. + my $corrupt = ($data =~ m/((xmlns:){2,}+)/g); + my $err = $1 || ''; + + # show them where we are at, if enabled or corrupted. + printf "%d/%d | %s | %s | %s\n", $havedone, $todo, $corrupt ? 'Bad ' : 'Ok ', $obj_uuid, $obj_name if ($corrupt || LISTALL); + + if ($corrupt) + { + $counter++; + + print ("Found $err\n", 'red') ; + my $original = $data; # so we can save it to disk later, if need be. + + $data =~ s/(xmlns:){2,}+/xmlns:/g; # the fix is in + + UpdateData($obj_uuid,$data) if UPDATE; # we update if we are enabled and had an error Rev C + + save({ + name => "$obj_uuid-$obj_name-before.txt", + uuid => $obj_uuid, + corrupt => $err, + data => $original, + type => 0, + }); + + save({ + name => "$obj_uuid-$obj_name-after.txt", + uuid => $obj_uuid, + corrupt => $err, + data => $data, + type => 0, + }); + } + + return $corrupt; # in case the caller wants to know +} + +sub save { + my $c = shift; + + $c->{name} =~ s/[^A-Za-z0-9\-\.]//g; # make a safe file name + + # may have to force an UTF-16LE or UTF-BE encoding here but my tests show the data is always UTF-8 or ASCII. + + if (open(my $out_file, "> :encoding(UTF-8)",'corrupt/' . $c->{name})) { + binmode ($out_file,":encoding(UTF-8)"); + + $c->{data} =~ s/encoding="utf-8"/encoding="utf-16"/; # not right, but that's they way they coded the XML in the DB. + + print $out_file $c->{data}; + print $out_file "\0"; # zero termination is in the OAR, lets put it back + } else { + say "Failed to open file"; + die; + } + +} + +__END__ + +BSD License: +Copyright (c) 2015 +Redistribution and use in source and binary forms, with or without +modification, are permitted provided that the following conditions are met: +* Redistributions of source code must retain the above copyright notice, this + list of conditions and the following disclaimer. +* Redistributions in binary form must reproduce the above copyright notice, + this list of conditions and the following disclaimer in the documentation + and/or other materials provided with the distribution. +THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" +AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE +IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE +DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE +FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL +DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR +SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER +CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, +OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. +Space here is intentionally left blank for note taking diff --git a/scripts/gitAR.sh b/scripts/gitAR.sh new file mode 100755 index 0000000..d988077 --- /dev/null +++ b/scripts/gitAR.sh @@ -0,0 +1,108 @@ +#!/bin/bash + +# Work around OpenSims slow database corruption bug by using git to store all old backups. +# Try to squeeze every last byte out of the tarballs. Seems to cut the total storage size down to one third the size of just the raw I/OAR files. +# Saves even more if there's been no changes. +# On the other hand, these backup files will grow indefinately, the more changes, the faster it grows. I can live with that for more reliable backups that go back further. +# Tries to avoid loosing data if things go wrong. I think the main remaining problem would be running out of space, in which case you have bigger problems to deal with. + +# Strategy - unpack the last one, unpack and commit any old I/OARs, pack up the result, delete it's working directory, THEN run the save i/oar. +# Avoids having to sync with OpenSim finishing the current I/OAR, and as a bonus, an easy to deliver latest I/OAR for people that want it. + +# Not really meant to be called by users, so don't bother validating the input and such. + +source common.sh +getPrgDir + +type=$1 +title=$2 +date=$(date '+%F_%T') + +# Convert the type to uppercase. +gar="_git$(echo -n ${type} | tr '[:lower:]' '[:upper:]')AR" +name=$(sanitize "${title}") + +if [ -d ${PRGDIR}/../../backups/temp_backup${type}_${name} ]; then + echo "WARNING - Mess left over from last backup, not gonna run!" + mv ${PRGDIR}/../../backups/temp_backup${type}_${name}/*.oar ${PRGDIR}/../backups + exit 1 +fi + +mkdir -p ${PRGDIR}/../../backups/temp_backup${type}_${name} +pushd ${PRGDIR}/../../backups/temp_backup${type}_${name} >/dev/null +if [ -f ../${name}${gar}.tar.xz ]; then + ionice -c3 nice -n 19 tar -xf ../${name}${gar}.tar.xz +else + mkdir -p ${name}${gar} + git init ${name}${gar} >log +fi + +pushd ${name}${gar} >/dev/null + +# Make sure stuff that's already compressed doesn't get compressed by git. +# Also tries to protect binaries from mangling. +cat >.gitattributes <<- zzzzEOFzzzz +*.bvh -delta -diff -text +*.jp2 -delta -diff -text +*.jpg -delta -diff -text +*.llmesh -delta -diff -text +*.ogg -delta -diff -text +*.png -delta -diff -text +*.r32 -delta -diff -text +*.tga -delta -diff -text +zzzzEOFzzzz +# Coz git insists. +git config user.email "opensim@$(hostname -A | cut -d ' ' -f 1)" +git config user.name "opensim" + +# Git is such a pedantic bitch, let's just fucking ignore any errors it gives due to lack of anything to do. +# Even worse the OpenSim devs breaking logout tracking gives git plenty of nothing to do. lol + +# Looping through them in case there's a bunch of I/OARs from previous versions of this script. +# Ignore files of zero size that OpenSim might create. +find ../.. -maxdepth 1 -type f -name "${name}-*.${type}ar" -size '+0c' | sort | while read file; do + # Deal with deletions in the inventory / sim, easy method, which becomes a nop for files that stay in the git add below. + git rm -fr * &>>../log #|| echo "ERROR - Could not clean git for ${file} !" >>../errors + if [ ! -f ../errors ]; then + ionice -c3 nice -n 19 tar -xzf "${file}" || echo "ERROR - Could not unpack ${file} !" >>../errors + fi + if [ ! -f ../errors ]; then + git add * &>>../log + git add */\* &>>../log #|| echo "ERROR - Could not add ${file} to git!" >>../errors + git add .gitattributes &>>../log + # Magic needed to figure out if there's anything to commit. + # After all the pain to get this to work, there's an ever changing timestamp in archive.xml that screws it up. + # Like this system didn't have enough timestamps in it already. lol + # TODO - I could sed out that timestamp, and put it back again based on the OAR file name when extracting. + # IARs don't seem to have the timestamp. + if t=$(git status --porcelain) && [ -z "${t}" ]; then + true + else + # Note this commit message has to be just the file name, as the ungitAR script uses it. + git commit -qm "$(basename ${file})" &>>../log || echo "ERROR - Could not commit ${file} !" >>../errors + fi + if [ ! -f ../errors ]; then + mv ${file} .. + fi + fi + if [ -f ../errors ]; then + exit 1 # Seems to only exit from this loop, not the script. Makes me want to rewrite this in a real language. lol + fi +done + +#git gc --aggressive --prune=now # Takes a long time, doesn't gain much. Even worse, it increases the size of the resulting tarball. lol + +popd >/dev/null + +if [ ! -f errors ]; then + XZ_OPT="-9e" ionice -c3 nice -n 19 tar -c --xz ${name}${gar} -f ../${name}${gar}.tar.xz || echo "ERROR - Could not pack gitAR!" >>errors +fi + +popd >/dev/null + +if [ -f ${PRGDIR}/../../backups/temp_backup${type}_${name}/errors ]; then + echo "NOT cleaning up coz - " + cat ${PRGDIR}/../../backups/temp_backup${type}_${name}/errors +else + rm -fr ${PRGDIR}/../../backups/temp_backup${type}_${name} +fi diff --git a/scripts/install/create_sim.sh b/scripts/install/create_sim.sh new file mode 100755 index 0000000..b940315 --- /dev/null +++ b/scripts/install/create_sim.sh @@ -0,0 +1,75 @@ +#!/bin/bash + +source ../common.sh +getPrgDir + +NAME=$1 +LOCATION=$2 +SIZE=$3 + +cd ${OS_PATH}/config + +k=0 +for i in $(seq -w 1 99) +do + if [ -e "sim$i" ] + then + k=$i + fi +done + +if [ "x${NAME}" = "x" ] +then + NAME="No name sim $RANDOM" # Should be unique per grid. + echo "WARNING setting the sim name to [${NAME}], this may not be what you want." +fi +# Sanitize the name. Not removing [ or ], couldn't get that to work, only important for Windows. +sim=$(sanitize ${NAME}) + +if [ "x${LOCATION}" = "x" ] +then + LOCATION="$RANDOM,$RANDOM" # again UNIQUE (i.e. ONLY ONE) per grid in THIS case! + echo "WARNING setting the Location to ${LOCATION}, this may not be what you want." +fi + +if [ "x${SIZE}" = "x" ] +then + SIZE="256" +fi + +# Wow, the hoops we have to jump through to avoid octal. +if [ 9 -gt $k ]; then + NUM=$(printf '0%1s' $(( 10#$k + 1 )) ) +else + NUM=$(printf '%2s' $(( 10#$k + 1 )) ) +fi + +PORT=$(( 9005 + (10#$k * 2) )) # 9002 is used for HTTP/UDP so START with port 9003! CAUTION Diva/D2 starts at port 9000. +UUID=$(uuidgen) + +echo "Creating sim${NUM} on port ${PORT} @ ${LOCATION} - ${NAME}." + +cp -r sim_skeleton sim${NUM} + +cd sim${NUM} +sed -i "s@SIM_NAME@${NAME}@g" ThisSim.ini +sed -i "s@SIM_UUID@${UUID}@g" ThisSim.ini +sed -i "s@SIM_POS@${LOCATION}@g" ThisSim.ini +sed -i "s@SIM_INT_PORT@$(( ${PORT} + 1 ))@g" ThisSim.ini +sed -i "s@SIM_SIZE@${SIZE}@g" ThisSim.ini + +ln -s ../../current/scripts/common.sh common.sh +ln -s ../../current/scripts/start-sim start-sim +cp -P start-sim backup-sim +cp -P start-sim stop-sim + +sed -i "s@SIM_NUMBER@${NUM}@g" ThisSim.ini +sed -i "s@SIM_PORT@${PORT}@g" ThisSim.ini + +sed -i "s@OS_PATH@${OS_PATH}@g" opensim-monit.conf +sed -i "s@SIM_NUMBER@${NUM}@g" opensim-monit.conf + +mv ThisSim.ini $(sanitize "${NAME}").ini + +sudo chown -R ${OS_USER}:${OS_USER} .. +sudo chmod -R g+w .. diff --git a/scripts/install/go_live.sh b/scripts/install/go_live.sh new file mode 100755 index 0000000..c5ce90e --- /dev/null +++ b/scripts/install/go_live.sh @@ -0,0 +1,12 @@ +#!/bin/bash + +source common.sh + +for i in $(seq 99) +do + j=$(printf "sim%02d" $i) + if [ -e "$OSPATH/config/$j" ] + then + sudo ln -s $OSPATH/config/$j/opensim-monit.conf /etc/monit/conf.d/$j.conf + fi +done diff --git a/scripts/install/group_migrate.sql b/scripts/install/group_migrate.sql new file mode 100644 index 0000000..6c15011 --- /dev/null +++ b/scripts/install/group_migrate.sql @@ -0,0 +1,48 @@ +INSERT INTO `griddy`.`os_groups_groups` +(GroupID, Name, Charter, InsigniaID, FounderID, MembershipFee, OpenEnrollment, ShowInList, +AllowPublish, MaturePublish, OwnerRoleID) +SELECT GroupID, Name, Charter, InsigniaID, FounderID, MemberShipFee, OpenEnrollment, ShowInList, AllowPublish, +MaturePublish, OwnerRoleID +FROM `griddy`.osgroup; + +/*fill os_groups_invites in ROBUST database with values from osgroupinvite +or FlotSam osgroupinvite*/ +INSERT INTO `griddy`.`os_groups_invites` +(InviteID, GroupID, RoleID, PrincipalID, TMStamp) +SELECT InviteID, GroupID, RoleID, AgentID, TMStamp +FROM `griddy`.osgroupinvite; + +/*fill os_groups_membership in ROBUST database with values from osgroupmembership +or FlotSam osgroupmembership*/ +INSERT INTO `griddy`.`os_groups_membership` +(GroupID, PrincipalID, SelectedRoleID, Contribution, ListInProfile, AcceptNotices) +SELECT GroupID, AgentID, SelectedRoleID, Contribution, ListInProfile, AcceptNotices +FROM `griddy`.osgroupmembership; + +/*fill os_groups_notices in ROBUST database with values from osgroupnotice +or FlotSam osgroupnotice*/ +INSERT INTO `griddy`.`os_groups_notices` +(GroupID, NoticeID, TMStamp, FromName, Subject, Message) +SELECT GroupID, NoticeID, Timestamp, FromName, Subject, Message +FROM `griddy`.osgroupnotice; + +/*fill os_groups_principals in ROBUST database with values from osagent +or FlotSam osagent*/ +INSERT INTO `griddy`.`os_groups_principals` +(PrincipalID, ActiveGroupID) +SELECT AgentID, ActiveGroupID +FROM `griddy`.osagent; + +/*fill os_groups_rolemembership in ROBUST database with values from osrolemembership +or FlotSam osgrouprolemembership*/ +INSERT INTO `griddy`.os_groups_rolemembership +(GroupID, RoleID, PrincipalID) +SELECT GroupID, RoleID, AgentID +FROM `griddy`.osgrouprolemembership; + +/*fill os_groups_roles in ROBUST database with values from osroles +or FlotSam osrole*/ +INSERT INTO `griddy`.os_groups_roles +(GroupID, RoleID, Name, Description, Title, Powers) +SELECT GroupID, RoleID, Name, Description, Title, Powers +FROM `griddy`.osrole; diff --git a/scripts/install/opensim.tmux.conf b/scripts/install/opensim.tmux.conf new file mode 100644 index 0000000..84e0c21 --- /dev/null +++ b/scripts/install/opensim.tmux.conf @@ -0,0 +1,97 @@ +# Tmux has a habit of changing what these options are for each version, so this is a bit of a mess. + +# Screen compatibility, change the command key. And rebind the prefix sending command. +set-option -g prefix C-a +unbind-key C-b +bind-key C-a send-prefix + +# r reloads the configuration, handy +bind r source-file ~/.tmux.conf + +bind R clear-history + +# More sane pane gain. B-) +unbind % # Remove default binding since we’re replacing them. +unbind '"' +bind | split-window -h +bind - split-window -v + +# set-options -g global, -s server, -w window, otherwise a session option. +# -a appends a string to the existing option. +# -u unsets an option. +# -o prevents setting an aption if it is already set. +# -q shut up info messages. + +# SESSION OPTIONS + +set-option -g bell-action any +set-option -g bell-on-alert on + +# Not actually documented what the limit is, but there is one. +set-option -g history-limit 100000 + +# All this mouse stuff is unreliable in UTF8 mode. At least on roxterm. +# Also keep in mind the terminal specs mouse report limit of 256 characters, being less than my typical terminal width. +# Hmm, still wont pass mouse through like the docs say they will. +# Ah, mc needs "mc -x". Though once again, watch that right edge on huge terminals. +# These three wont work under Ubuntu 16.04. +##set-option -g mouse-resize-pane on +##set-option -g mouse-select-pane on +##set-option -g mouse-select-window on +# This wont work under Ubuntu 16.04. +##set-option -g mode-mouse on # on - mouse does copy mode stuff; copy-mode - mouse can't go into copy mode, but does stuff once in there; off - mouse is unmolested. +# Instead do this (also defaults to turning on the above three mouse things) - +set-option -g mouse on +# Or this. sigh +#set-option -g mouse +##set-option -g mouse-utf8 off # Defaults to on. + +set-option -g set-remain-on-exit on + +# How to set the title of the terminal window. +set-option -g set-titles on +set-option -g set-titles-string '#W' # Default is "#S:#I:#W - "#T"" + +set-option -g status-interval 1 # Redraw status line every second, for the clock. +set-option -g status-justify centre # Window list in the middle. +##set-option -g status-utf8 on + +# Character pair Replaced with + #(shell-command) First line of the command's output + #[attributes] Colour or attribute change + #H Hostname of local host (not FDQN) + #h Hostname of local host without the domain name + #F Current window flag + #I Current window index + #D Current pane unique identifier + #P Current pane index + #S Session name + #T Current pane title + #W Current window name + ## A literal ‘#’ + +# Yes, my terminal really is bigger than 160 characters. +set-option -g status-left-length 42 +#set-option -g status-left '[#H #S #F]' +set-option -g status-left '#H [#S:#I.#P]#F' +set-option -g status-right-length 64 +set-option -g status-right "%F #(uptime | cut -d ' ' -f 2-2,10-)" # %F is ISO date, uptime starts with the current time, and ends with the load average. B-) + +# Set window notifications +set-option -g visual-activity on # Show status message for activity in monitor-activity windows. +#set-option -g visual-content on # Show status message for content in monitor-content windows. Based on a fnmatch(3) string. +set-option -g visual-silence on # Show status message for silence in monitor-silence windows. Based on a set interval. + +set-option -gw alternate-screen off # Don't save the original screen before starting tmux, may also allow use of the terminals original scrollback buffer. +set-option -gw clock-mode-style 24 # We are using the uptime clock anyway, so this is pointless. + +# Highlight active window +set-option -gw window-status-current-bg red +set-option -gw window-status-current-format '[#I:#W]' +set-option -gw window-status-format '[#I:#W]#F' + +# Set window notifications +set-option -gw monitor-activity on # Bell on activity. + +# We want 256 colours in our terminal. +set-option -g default-terminal "screen-256color" diff --git a/scripts/install/secure.sh b/scripts/install/secure.sh new file mode 100755 index 0000000..95aae84 --- /dev/null +++ b/scripts/install/secure.sh @@ -0,0 +1,26 @@ +#!/bin/bash + +source ../common.sh + +echo "Securing OpenSim." +sudo chmod 600 ${OS_PATH}/config/*.ini +sudo chmod 600 ${OS_PATH}/config/ROBUST/*.ini +sudo chown -R ${OS_USER}:${OS_USER} ${OS_PATH} +sudo chmod -R 775 ${OS_PATH} +sudo chmod -R a-x ${OS_PATH} +sudo chmod -R a+X ${OS_PATH} +sudo chmod -R g+w ${OS_PATH} +sudo chmod -R a+x ${OS_PATH}/current/*.sh +sudo chmod -R a+x ${OS_PATH}/current/scripts/*.sh +sudo chmod -R a+x ${OS_PATH}/current/scripts/install/*.sh +sudo chmod a+x ${OS_PATH}/current/scripts/show-console +sudo chmod a+x ${OS_PATH}/current/scripts/start-sim + +sudo chmod ug+rwx ${OS_PATH}/config +sudo chmod g+s ${OS_PATH}/config +sudo chmod 600 ${OS_PATH}/config/*.ini +sudo chmod 600 ${OS_PATH}/config/ROBUST/*.ini + +chmod ug+rwx ${OS_PATH}/caches +chmod o-rwx ${OS_PATH}/caches +chmod g+s ${OS_PATH}/caches diff --git a/scripts/show-console b/scripts/show-console new file mode 100755 index 0000000..d8b1775 --- /dev/null +++ b/scripts/show-console @@ -0,0 +1,3 @@ +#!/bin/bash + +tmux -S ../../var/run/opensim-tmux.socket select-window -t "SledjChisl" \; attach-session -t "SledjChisl" diff --git a/scripts/start-sim b/scripts/start-sim new file mode 100755 index 0000000..0a58294 --- /dev/null +++ b/scripts/start-sim @@ -0,0 +1,218 @@ +#!/bin/bash + +source common.sh +getPrgDir + +USER=$(whoami) +console_name="SledjChisl" +tmux_command="tmux -S ${PRGDIR}/../../var/run/opensim-tmux.socket" +tmux_session=${console_name} +tmux_window="${tmux_command} select-window -t ${tmux_session}" +tmux_send="${tmux_command} send-keys -t ${tmux_session}" +bindir="${PRGDIR}/../bin" +date=$(date '+%F_%T') +all="" +delay=45 +quiet="" +waiting="" +inventory="" + +function wait_for_text() +{ + while :; do + sleep 10 + ${tmux_command} capture-pane -t ${tmux_session}:"${1}" -p | grep -E "${2}" 2>&1 > /dev/null && return + done +} + + +if [ $USER = "${OS_USER}" ] +then + SUDO="" +else + SUDO="sudo -Hu ${OS_USER}" +fi + +if [ "$1" = "-a" ] +then + all="-a" + shift 1 +fi + +if [ "$1" = "-d" ] +then + delay=$2 + shift 2 +fi + +if [ "$1" = "-q" ] +then + quiet="-q" + shift 1 +fi + +if [ "$1" = "-w" ] +then + waiting="-w" + shift 1 +fi + +if [ "x$1" = "x" ]; then + tgt=$(basename $(pwd)) + # These checks are kludgy. + if [ "$tgt" = "scripts" ]; then + all="-a" + cd ${PRGDIR}/../../config/ROBUST + tgt="ROBUST" + fi + if [ "$tgt" = "bin" ]; then + uptime + wait_for_text "ROBUST" "INITIALIZATION COMPLETE FOR ROBUST" + if [ ! "x$all" = "x" ] + then + echo "Sleeping for $((${delay} / 2)) seconds." + sleep $((${delay} / 2)) + for i in $(seq -w 1 99) + do + if [ -e "${PRGDIR}/../../config/sim${i}" ] + then + uptime + echo "Starting sim${i}." + cd ${PRGDIR}/../../config/sim${i}; ./start-sim -w + uptime + # Sleep for a while, so that there is plenty of time to finish starting scripts and such, + # and we are not keeping the computer very busy if there are lots of sims. + echo "Sleeping for ${delay} seconds." + sleep ${delay} + fi + done + uptime + fi + exit 0 + fi + num="$(echo ${tgt} | cut -c 4-)" +elif [ -d "$1" ]; then + tgt=$1 +elif [ -d "sim$1" ]; then + num=$1 + tgt="sim${num}" +else + tgt=$1 + inventory=$1 +fi + +if [ "x$tgt" = "x" ]; then + echo "usage:" + echo " $ $(basename $0) " + echo "where is one of: " robust sim[0-9][0-9] + exit 1 +fi + +cd ${bindir} + +if ( ${tmux_command} -q list-sessions 2>/dev/null | grep -q ${console_name}: ); then + true +else + # The sudo is only so that the session is owned by opensim, otherwise it's owned by whoever ran this script, which is a likely security hole. + # After the session is created, we rely on the ${PRGDIR}/../../caches/ directory to be group sticky, so that anyone in the opensim group can attach to the tmux socket. + $SUDO ${tmux_command} new-session -d -s ${console_name} -n "ROBUST" +fi + + +if [ "x$tgt" = "xROBUST" ]; then + exe="Robust" + title="ROBUST" +elif [ "x$inventory" = "x" ]; then + exe="OpenSim" + # Grab the first RegionName line of the sims .ini file, cut it down to the name. + title=$(getSimName ${num}) +fi + +case $(basename $0) in + "start-sim") + cmd="mono ${exe}.exe -inidirectory=../../config/${tgt} " + + # Check if it's already running. + if [ -e ${PRGDIR}/../../caches/${tgt}.pid ] + then + # Double check if it's REALLY running. + if [ "x$(ps -p $(cat ${PRGDIR}/../../caches/${tgt}.pid) --no-headers -o comm)" = "x" ]; then + $SUDO rm -f ${PRGDIR}/../../caches/${tgt}.pid + fi + fi + # Now see if it's really really running. lol + if [ ! -e ${PRGDIR}/../../caches/${tgt}.pid ] + then + if [ "x$tgt" = "xROBUST" ]; then + ${tmux_command} split-window -hp 50 -t "${tmux_session}:" "${cmd}" + else + ${tmux_command} new-window -dn "${title}" -t "${tmux_session}:${num}" "${cmd}" + fi + fi + + if [ ! "x$all" = "x" ] + then + ${tmux_send}:ROBUST.{left} "../scripts/start-sim -a -d ${delay}" Enter + fi + + if [ "x$quiet" = "x" ] + then + if [ "x$tgt" = "xROBUST" ]; then + ${tmux_window} \; attach-session -t "${tmux_session}" + fi + fi + + if [ ! "x$waiting" = "x" ] + then + wait_for_text "${title}" "INITIALIZATION COMPLETE FOR ${title}" + fi + ;; + + "backup-inventory") + cd ${PRGDIR} + $SUDO ${PRGDIR}/gitAR.sh i "${inventory}" + user=$(sanitize "${inventory}") + # Add the full date and time to create the IAR file name. + cmd="save iar -c ${inventory} / password ${PRGDIR}/../../backups/${user}-${date}.iar" + # Do it in the highest numbered window. + ${tmux_send}:"$" "${cmd}" Enter + wait_for_text "$" "Saved archive with [[:digit:]]+ items for ${user/_/ }" + ${tmux_send}:"$" "force gc" Enter Enter Enter + ;; + + "backup-sim") + if [ -e ${PRGDIR}/../../caches/${tgt}.pid ]; then + cd ${PRGDIR} + $SUDO ${PRGDIR}/gitAR.sh o "${title}" + sim=$(sanitize "${title}") + # Add the full date and time to create the OAR file name. + cmd="save oar --all ${PRGDIR}/../../backups/${sim}-${date}.oar" + ${tmux_send}:"${title}" "${cmd}" Enter + wait_for_text "${title}" "Finished writing out OAR for ${title}" + # Generate the map tiles, coz the good generator leaks memory badly if you leave it turned on. + ${tmux_send}:"${title}" "generate map" Enter + ${tmux_send}:"${title}" "force gc" Enter Enter Enter + else + echo "No OAR created for ${title}, it's not running." + fi + ;; + + "stop-sim") + if [ -e ${PRGDIR}/../../caches/${tgt}.pid ]; then + ${tmux_send}:"${title}" "alert WARNING - Emergency shutdown in one minute!" Enter + ${tmux_send}:"${title}" "alert WARNING - Emergency shutdown in one minute!" Enter + sleep 30 + ${tmux_send}:"${title}" "alert WARNING - Emergency shutdown in thirty seconds!" Enter + ${tmux_send}:"${title}" "alert WARNING - Emergency shutdown in thirty seconds!" Enter + sleep 30 + ${tmux_send}:"${title}" "shutdown" Enter + sleep 30 + if [ -e ${PRGDIR}/../../caches/${tgt}.pid ]; then + echo "Killing it with extreme prejudice!" + kill -TERM `cat ${PRGDIR}/../../caches/${tgt}.pid` + fi + else + echo "Sim ${title} is not running, so not stopping." + fi + ;; +esac -- cgit v1.1