<?xml version="1.0"?>
<?xml-stylesheet type="text/css" href="http://opensimulator.org/skins/common/feed.css?303"?>
<feed xmlns="http://www.w3.org/2005/Atom" xml:lang="en">
		<id>http://opensimulator.org/index.php?action=history&amp;feed=atom&amp;title=User%3AJeffKelley%2FAutomating_grid_management</id>
		<title>User:JeffKelley/Automating grid management - Revision history</title>
		<link rel="self" type="application/atom+xml" href="http://opensimulator.org/index.php?action=history&amp;feed=atom&amp;title=User%3AJeffKelley%2FAutomating_grid_management"/>
		<link rel="alternate" type="text/html" href="http://opensimulator.org/index.php?title=User:JeffKelley/Automating_grid_management&amp;action=history"/>
		<updated>2026-04-21T00:31:48Z</updated>
		<subtitle>Revision history for this page on the wiki</subtitle>
		<generator>MediaWiki 1.19.9</generator>

	<entry>
		<id>http://opensimulator.org/index.php?title=User:JeffKelley/Automating_grid_management&amp;diff=41188&amp;oldid=prev</id>
		<title>JeffKelley: Created page with &quot;'''THIS IS A DRAFT'''   Here is one of many solutions to manage a Linux grid from one unique bin folder.  ==OpenSim configuration==  First, we parametrize our configuration fi...&quot;</title>
		<link rel="alternate" type="text/html" href="http://opensimulator.org/index.php?title=User:JeffKelley/Automating_grid_management&amp;diff=41188&amp;oldid=prev"/>
				<updated>2015-08-18T18:28:32Z</updated>
		
		<summary type="html">&lt;p&gt;Created page with &amp;quot;&amp;#039;&amp;#039;&amp;#039;THIS IS A DRAFT&amp;#039;&amp;#039;&amp;#039;   Here is one of many solutions to manage a Linux grid from one unique bin folder.  ==OpenSim configuration==  First, we parametrize our configuration fi...&amp;quot;&lt;/p&gt;
&lt;p&gt;&lt;b&gt;New page&lt;/b&gt;&lt;/p&gt;&lt;div&gt;'''THIS IS A DRAFT'''&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
Here is one of many solutions to manage a Linux grid from one unique bin folder.&lt;br /&gt;
&lt;br /&gt;
==OpenSim configuration==&lt;br /&gt;
&lt;br /&gt;
First, we parametrize our configuration files to use shell environment variables. We will use only one variable named SIMULATOR. The expression ${Environment|SIMULATOR} can then be used in various parts of OpenSim.ini and GridCommon.ini.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;source lang=&amp;quot;ini&amp;quot;&amp;gt;&lt;br /&gt;
[Environment]&lt;br /&gt;
    SIMULATOR=&amp;quot;&amp;quot;&lt;br /&gt;
&lt;br /&gt;
[Startup]&lt;br /&gt;
    ConsolePrompt = &amp;quot;Simulator ${Environment|SIMULATOR} (\R) &amp;quot;&lt;br /&gt;
    regionload_regionsdir = &amp;quot;path_to_regions/simul${Environment|SIMULATOR}&amp;quot;&lt;br /&gt;
    PIDFile = &amp;quot;/tmp/grid/simu${Environment|SIMULATOR}.pid&amp;quot;&lt;br /&gt;
&lt;br /&gt;
[Network]&lt;br /&gt;
    http_listener_port = 900${Environment|SIMULATOR}&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
With such a configuration, the listening port for simulator N will be 900N. [ Note: We assume a one-digit simulator number. If you need more than 10 simulators, you may use 90${Environment|SIMULATOR} and pass a two-digit SIMULATOR variable. ] The regions file for simulator N is located inside path_to_regions/simulN, so you should have this structure on disk :&lt;br /&gt;
&lt;br /&gt;
 path_to_regions&lt;br /&gt;
    simul1&lt;br /&gt;
        Regions.ini&lt;br /&gt;
    simul2&lt;br /&gt;
        Regions.ini&lt;br /&gt;
    ......&lt;br /&gt;
&lt;br /&gt;
If you are using separate databases for each simulator (this is a design choice), then you can parametrize the ConnectionString in GridCommon.ini this way :&lt;br /&gt;
&lt;br /&gt;
&amp;lt;source lang=&amp;quot;ini&amp;quot;&amp;gt;&lt;br /&gt;
[DatabaseService]&lt;br /&gt;
    ConnectionString = &amp;quot;Data Source=localhost;Database=sim${Environment|SIMULATOR};User ID=xxx;Password=xxx;&amp;quot;&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
==Using GNU screen==&lt;br /&gt;
&lt;br /&gt;
At the hearth of the management system is the '''launch''' script. We take care to label each session with the -S option. &lt;br /&gt;
&lt;br /&gt;
&amp;lt;source lang=&amp;quot;perl&amp;quot;&amp;gt;&lt;br /&gt;
#!/usr/bin/perl&lt;br /&gt;
&lt;br /&gt;
# Starting a grid process&lt;br /&gt;
# Usage : launch [-d] task_name (robust, simulN)&lt;br /&gt;
&lt;br /&gt;
use strict;&lt;br /&gt;
use Getopt::Std;&lt;br /&gt;
use POSIX qw(strftime);&lt;br /&gt;
&lt;br /&gt;
my %OPTS; getopts ('d', \%OPTS);&lt;br /&gt;
my $dflag = '-d' if %OPTS-&amp;gt;{d};&lt;br /&gt;
my ($proc, $dir, $exe, $arg);&lt;br /&gt;
&lt;br /&gt;
$proc = $ARGV[0];&lt;br /&gt;
$bin = '/home/me/grid'; # Where is the bin folder&lt;br /&gt;
&lt;br /&gt;
$exe = 'Robust.exe'	if $proc =~ m/robust/;&lt;br /&gt;
$exe = 'OpenSim.exe'	if $proc =~ m/simul(.*)/;&lt;br /&gt;
&lt;br /&gt;
$arg = 'Robust.HG.ini'	if $proc =~ m/robust/;&lt;br /&gt;
$arg = 'OpenSim.ini'	if $proc =~ m/simul(.*)/;&lt;br /&gt;
&lt;br /&gt;
die &amp;quot;Invalid proccess\n&amp;quot; unless defined $exe;&lt;br /&gt;
&lt;br /&gt;
my $now = strftime &amp;quot;%F %H:%M:%S&amp;quot;, localtime;&lt;br /&gt;
printf  &amp;quot;$now Launching $proc\n&amp;quot;;&lt;br /&gt;
&lt;br /&gt;
chdir $bin or die &amp;quot;Cannot chdir $bin&amp;quot;;&lt;br /&gt;
&lt;br /&gt;
$ENV{SIMULATOR} = $1 if $proc =~ m/simul(.*)/;&lt;br /&gt;
$ENV{PATH} .= ':/usr/local/bin'; # MONO is here&lt;br /&gt;
$ENV{LANG}='C';	# Pour le point décimal&lt;br /&gt;
&lt;br /&gt;
my $exe = &amp;quot;mono $exe -inifile=$arg&amp;quot;;&lt;br /&gt;
my $cmd = &amp;quot;screen -S $proc -t $proc $dflag -m $exe&amp;quot;;&lt;br /&gt;
print &amp;quot;$cmd\n&amp;quot;; exec $cmd;&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Launching the grid is a matter of issuing this sequence of commands :&lt;br /&gt;
&lt;br /&gt;
 launch robust&lt;br /&gt;
 launch simul1&lt;br /&gt;
 launch simul2&lt;br /&gt;
 .............&lt;br /&gt;
&lt;br /&gt;
Then:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;source lang=&amp;quot;bash&amp;quot;&amp;gt;&lt;br /&gt;
$ screen -ls&lt;br /&gt;
There are screens on:&lt;br /&gt;
	26039.simul6	(Multi, attached)&lt;br /&gt;
	24972.simul4	(Multi, attached)&lt;br /&gt;
	24676.simul1	(Multi, attached)&lt;br /&gt;
	24652.robust	(Multi, attached)&lt;br /&gt;
	24750.simul2	(Multi, attached)&lt;br /&gt;
	29220.simul3	(Multi, attached)&lt;br /&gt;
	25481.simul5	(Multi, attached)&lt;br /&gt;
8 Sockets in /var/run/screen/S-jyb.&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
This is not very friendly, so we write the '''procs''' script&lt;br /&gt;
&lt;br /&gt;
&amp;lt;source lang=&amp;quot;perl&amp;quot;&amp;gt;&lt;br /&gt;
#!/usr/bin/perl&lt;br /&gt;
&lt;br /&gt;
# List running grid processes&lt;br /&gt;
# Only detached if -d&lt;br /&gt;
&lt;br /&gt;
use Getopt::Std;&lt;br /&gt;
&lt;br /&gt;
getopts ('d', \%OPTS);&lt;br /&gt;
$detached = $OPTS{d};&lt;br /&gt;
&lt;br /&gt;
@screens = split &amp;quot;\n&amp;quot;, `screen -ls`;&lt;br /&gt;
@wanted;&lt;br /&gt;
&lt;br /&gt;
for (@screens) {&lt;br /&gt;
 	next unless $_ =~ /(\S*)\.(\S*).*\((.*)\)/;&lt;br /&gt;
	($pid,$name,$attr) = ($1,$2,$3);&lt;br /&gt;
	$is_detached = ($attr =~ /detached/i);&lt;br /&gt;
	push @wanted,$name unless $detached &amp;amp;&amp;amp; !$is_detached;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
for (sort @wanted) {&lt;br /&gt;
	print &amp;quot;$_\n&amp;quot;;&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Then:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;source lang=&amp;quot;bash&amp;quot;&amp;gt;&lt;br /&gt;
$ procs&lt;br /&gt;
robust&lt;br /&gt;
simul1&lt;br /&gt;
simul2&lt;br /&gt;
simul3&lt;br /&gt;
simul4&lt;br /&gt;
simul5&lt;br /&gt;
simul6&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
==Automating==&lt;br /&gt;
&lt;br /&gt;
Create a file named proclist:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;source lang=&amp;quot;bash&amp;quot;&amp;gt;&lt;br /&gt;
# processes to launch&lt;br /&gt;
&lt;br /&gt;
robust&lt;br /&gt;
simul1&lt;br /&gt;
simul2&lt;br /&gt;
simul3&lt;br /&gt;
simul4&lt;br /&gt;
simul5&lt;br /&gt;
simul6&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
It is easy now to write a couple of scripts that launch the next wanted process, or re-attach the next detached process.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
Script '''s''' :&lt;br /&gt;
&lt;br /&gt;
&amp;lt;source lang=&amp;quot;perl&amp;quot;&amp;gt;&lt;br /&gt;
#!/usr/bin/perl&lt;br /&gt;
&lt;br /&gt;
# Launch first missing process from proclist&lt;br /&gt;
&lt;br /&gt;
use strict;&lt;br /&gt;
&lt;br /&gt;
my @running = `procs`; # List of running screens&lt;br /&gt;
&lt;br /&gt;
# Get wanted processes list&lt;br /&gt;
&lt;br /&gt;
my $interactive = -t STDIN &amp;amp;&amp;amp; -t STDOUT;&lt;br /&gt;
my $dflag = '-d' unless $interactive;&lt;br /&gt;
my $proclist = &amp;quot;$ENV{HOME}/proclist&amp;quot;;&lt;br /&gt;
&lt;br /&gt;
open IN, &amp;quot;&amp;lt;$proclist&amp;quot; or die &amp;quot;Cannot open $proclist\n&amp;quot;;&lt;br /&gt;
&lt;br /&gt;
my @procs = &amp;lt;IN&amp;gt;;&lt;br /&gt;
&lt;br /&gt;
# Find first not running process&lt;br /&gt;
&lt;br /&gt;
for my $proc (@procs) {&lt;br /&gt;
	chomp $proc;&lt;br /&gt;
	next if $proc eq '';&lt;br /&gt;
	next if $proc =~ /^#/;&lt;br /&gt;
&lt;br /&gt;
	my $running = grep /$proc/,@running;&lt;br /&gt;
	exec &amp;quot;bin/launch $dflag $proc&amp;quot; unless $running;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
print &amp;quot;Nothing to start\n&amp;quot; if $interactive;&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
Script '''r''' :&lt;br /&gt;
&lt;br /&gt;
&amp;lt;source lang=&amp;quot;perl&amp;quot;&amp;gt;&lt;br /&gt;
#!/usr/bin/perl&lt;br /&gt;
&lt;br /&gt;
# Reattach first detached screen process&lt;br /&gt;
&lt;br /&gt;
@detached = `procs -d`; # List detached screens&lt;br /&gt;
die &amp;quot;Nothing to reattach\n&amp;quot; unless @detached;&lt;br /&gt;
&lt;br /&gt;
$process = shift @detached;&lt;br /&gt;
&lt;br /&gt;
printf &amp;quot;Reattaching $process\n&amp;quot;;&lt;br /&gt;
sleep 1; exec &amp;quot;screen -r $process&amp;quot;;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Starting your grid is now as simple as opening as many terminals as you have grid processes and typing '''s''' in each. This can be further automated by having a cron job calling '''s''' every minute. The job will launch any missing process from '''proclist'''. As an added benefit, it will relaunch crashed simulators.&lt;br /&gt;
&lt;br /&gt;
==Adding a simulator==&lt;br /&gt;
&lt;br /&gt;
Add a line to '''proclist'''&lt;br /&gt;
&lt;br /&gt;
&amp;lt;source lang=&amp;quot;bash&amp;quot;&amp;gt;&lt;br /&gt;
# processes to launch&lt;br /&gt;
&lt;br /&gt;
robust&lt;br /&gt;
simul1&lt;br /&gt;
simul2&lt;br /&gt;
simul3&lt;br /&gt;
simul4&lt;br /&gt;
simul5&lt;br /&gt;
simul6&lt;br /&gt;
simul7&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Create a folder path_to_regions/simul7 and put the Regions.ini inside.&lt;br /&gt;
&lt;br /&gt;
That's all.&lt;/div&gt;</summary>
		<author><name>JeffKelley</name></author>	</entry>

	</feed>