Init Script

From OpenSimulator

(Difference between revisions)
Jump to: navigation, search
(Replacing page with '== OpenSim Init Scripts == There is now a forge project for [http://forge.opensimulator.org/gf/linuxservice|Linux Service Scripts for OpenSim] that contains init scripts for r...')
Line 1: Line 1:
−
== Region Init Script ==
+
== OpenSim Init Scripts ==
−
The following is an init script that I wrote for starting, stopping, and monitoring OpenSim on Linux systems.  It makes some assumptions, and is only going to work (unmoddified) if you stay with those assumptions:
+
−
* Your opensim instance is in /opt/opensim/staging/bin (that's an easy change)
+
−
* You are only running 1 OpenSim.exe process per machine (that's '''not''' easy to change)
+
−
* You are using mysql (that's easy to change)
+
−
* Production mono is in /usr/local/bin (that's easy to change)
+
−
While it may not be suitable for all environments, it has been very useful for the environments that I run.
+
  
−
<source lang="ruby">
+
There is now a forge project for [http://forge.opensimulator.org/gf/linuxservice|Linux Service Scripts for OpenSim] that contains init scripts for running OpenSim.
−
#!/usr/bin/ruby
+
−
 
+
−
# Start or stop OpenSim
+
−
#
+
−
# Sean Dague <sdague@gmail.com>
+
−
 
+
−
### BEGIN INIT INFO
+
−
# Provides:          opensim
+
−
# Required-Start:    $local_fs $remote_fs $syslog $named $network $time $mysql
+
−
# Required-Stop:    $local_fs $remote_fs $syslog $named $network
+
−
# Default-Start:    2 3 4 5
+
−
# Default-Stop:      0 1 6
+
−
# Short-Description: start and stop opensim
+
−
# Description:      opensim init script
+
−
### END INIT INFO
+
−
 
+
−
require "rexml/document"
+
−
require "open-uri"
+
−
include REXML
+
−
 
+
−
OpenSimPath = "/opt/opensim/staging/bin"
+
−
Dir.chdir(OpenSimPath)
+
−
 
+
−
@host = "localhost"
+
−
@port = 9000
+
−
@uuid = "0"
+
−
 
+
−
def parse_config
+
−
    # first we figure out the external hostname of a region on the box
+
−
    Dir.new("#{OpenSimPath}/Regions").find do |f|
+
−
        if f =~ /\.xml$/
+
−
            doc = Document.new(File.new("#{OpenSimPath}/Regions/#{f}"))
+
−
           
+
−
            if doc.root.elements['Config'].attributes['external_host_name']
+
−
                @host = doc.root.elements['Config'].attributes['external_host_name']
+
−
            else
+
−
                @host = doc.root.elements['Config'].elements['external_host_name'].text
+
−
            end
+
−
     
+
−
            if doc.root.elements['Config'].attributes['sim_UUID']
+
−
                @uuid = doc.root.elements['Config'].attributes['sim_UUID'].gsub(/-/,'')
+
−
            else
+
−
                @uuid = doc.root.elements['Config'].elements['sim_UUID'].text.gsub(/-/,'')
+
−
            end
+
−
           
+
−
            break
+
−
        end
+
−
    end
+
−
    # then we figure out the external port from opensim.ini
+
−
    open("#{OpenSimPath}/OpenSim.ini") do |f|
+
−
        f.each do |line|
+
−
            if line =~ /^\s*http_listener_port/
+
−
                (key, equal, port) = line.split
+
−
                if port
+
−
                    @port = port
+
−
                end
+
−
            end
+
−
        end
+
−
    end
+
−
end
+
−
 
+
−
def alive?
+
−
    begin
+
−
        open("http://#{@host}:#{@port}/index.php?method=regionImage#{@uuid}") do |f|
+
−
            resp = f.read
+
−
            return true
+
−
        end
+
−
    rescue => e
+
−
    end
+
−
    return false
+
−
end
+
−
 
+
−
def pidof(item)
+
−
    IO.popen("ps auxw | grep #{item} | grep -v grep") do |line|
+
−
        line.each do |l|
+
−
            return l.split[1].to_i
+
−
        end
+
−
    end
+
−
    return nil
+
−
end
+
−
 
+
−
def opensim_pid
+
−
    return pidof("OpenSim.exe")
+
−
end
+
−
 
+
−
def status
+
−
    if alive?
+
−
        puts "OK"
+
−
        exit 0
+
−
    else
+
−
        puts "FAILED"
+
−
        exit 1
+
−
    end
+
−
end
+
−
 
+
−
def start
+
−
    if alive?
+
−
        puts "OpenSim already running"
+
−
        exit 0
+
−
    end
+
−
    if opensim_pid != nil
+
−
        # opensim process is running, but not responding, we're hung
+
−
        stop
+
−
        # this really is needed otherwise you get a wedge
+
−
        system("/etc/init.d/mysql restart")
+
−
        sleep 10
+
−
        # purge the addin cache, this may have been the reason for the hang
+
−
        system("rm -rf addin-db-*")
+
−
    end
+
−
    system("screen -wipe")
+
−
    system("screen -d -S opensim -m /usr/local/bin/mono --debug OpenSim.exe")
+
−
   
+
−
    20.times do |t|
+
−
        if alive?
+
−
            return
+
−
        end
+
−
        sleep 5
+
−
    end
+
−
   
+
−
    puts "FAILED to start region"
+
−
    exit 1
+
−
end
+
−
 
+
−
def stop
+
−
    if opensim_pid == nil
+
−
        puts "OpenSim not running"
+
−
        exit 0
+
−
    end
+
−
    system("screen -wipe")
+
−
    system("screen -S opensim -X eval 'stuff \"shutdown\015\"'")
+
−
    puts "Shutting down... waiting 30 seconds"
+
−
    30.times do |i|
+
−
        if opensim_pid == nil
+
−
            return
+
−
        end
+
−
        $stderr.write "."
+
−
        sleep 1
+
−
    end
+
−
   
+
−
    pid = opensim_pid
+
−
    if pid
+
−
        puts "Process not responding, forcing shutdown"
+
−
        Process.kill(9, pid)
+
−
    end
+
−
   
+
−
end
+
−
 
+
−
def main
+
−
    parse_config
+
−
   
+
−
    mode = ARGV[0]
+
−
   
+
−
    if mode == "start"
+
−
        start
+
−
    elsif mode == "stop"
+
−
        stop
+
−
    elsif mode == "status"
+
−
        status
+
−
    elsif mode == "process"
+
−
        puts opensim_pid
+
−
    elsif mode == "restart"
+
−
        puts "called restart"
+
−
    else
+
−
        puts "unknown"
+
−
    end
+
−
end
+
−
 
+
−
main
+
−
</source>
+
−
 
+
−
== Grid Init Script ==
+
−
'''WARNING''' this is untested, so it may blow up on you.
+
−
<source lang="ruby">
+
−
#!/usr/bin/ruby
+
−
 
+
−
# Start or stop OpenSim
+
−
#
+
−
# Sean Dague <sdague@gmail.com>
+
−
 
+
−
### BEGIN INIT INFO
+
−
# Provides:          opensim-grid
+
−
# Required-Start:    $local_fs $remote_fs $syslog $named $network $time $mysql
+
−
# Required-Stop:    $local_fs $remote_fs $syslog $named $network
+
−
# Default-Start:    2 3 4 5
+
−
# Default-Stop:      0 1 6
+
−
# Short-Description: start and stop opensim-grid
+
−
# Description:      opensim-grid init script
+
−
### END INIT INFO
+
−
 
+
−
require "rexml/document"
+
−
require "open-uri"
+
−
include REXML
+
−
 
+
−
OpenSimPath = "/opt/opensim/staging/bin"
+
−
Dir.chdir(OpenSimPath)
+
−
 
+
−
@host = "localhost"
+
−
@gridport = nil
+
−
@userport = nil
+
−
@invport = nil
+
−
@assetport = nil
+
−
@messageport = nil
+
−
 
+
−
GridExe = "OpenSim.Grid.GridServer.exe"
+
−
UserExe = "OpenSim.Grid.UserServer.exe"
+
−
AssetExe = "OpenSim.Grid.AssetServer.exe"
+
−
InventoryExe = "OpenSim.Grid.InventoryServer.exe"
+
−
MessagingExe = "OpenSim.Grid.MessagingServer.exe"
+
−
 
+
−
def parse_config
+
−
    # Grid
+
−
    begin
+
−
        doc = Document.new(File.new("#{OpenSimPath}/GridServer_Config.xml"))
+
−
        @gridport = doc.root.elements['Config'].attributes['http_port']
+
−
    rescue => e
+
−
    end
+
−
 
+
−
    # User
+
−
    begin
+
−
        doc = Document.new(File.new("#{OpenSimPath}/UserServer_Config.xml"))
+
−
        @userport = doc.root.elements['Config'].attributes['http_port']
+
−
    rescue => e
+
−
    end
+
−
   
+
−
    # Inventory
+
−
    begin
+
−
        doc = Document.new(File.new("#{OpenSimPath}/InventoryServer_Config.xml"))
+
−
        @invport = doc.root.elements['Config'].attributes['http_port']
+
−
    rescue => e
+
−
    end
+
−
   
+
−
    # Asset
+
−
    begin
+
−
        doc = Document.new(File.new("#{OpenSimPath}/AssetServer_Config.xml"))
+
−
        @assetport = doc.root.elements['Config'].attributes['http_port']
+
−
    rescue => e
+
−
    end
+
−
   
+
−
    # Messaging
+
−
    begin
+
−
        doc = Document.new(File.new("#{OpenSimPath}/MessagingServer_Config.xml"))
+
−
        @messageport = doc.root.elements['Config'].attributes['http_port']
+
−
    rescue => e
+
−
    end
+
−
end
+
−
 
+
−
def grid_alive?
+
−
    if not @gridport
+
−
        return false
+
−
    end
+
−
    # we actually only care if we cause an exception, which means the grid server is bust
+
−
    begin
+
−
        xml = open("http://#{@host}:#{@gridport}/sims/fc036b80fed84b3096a50569b60da265").read
+
−
        return true
+
−
    rescue => e
+
−
        return false
+
−
    end
+
−
end
+
−
 
+
−
def user_alive?
+
−
    if not @userport
+
−
      return false
+
−
    end
+
−
    # we actually only care if we cause an exception, which means the grid server is bust
+
−
    begin
+
−
        xml = open("http://#{@host}:#{@userport}/get_grid_info").read
+
−
        return true
+
−
    rescue => e
+
−
        return false
+
−
    end
+
−
end
+
−
 
+
−
def asset_alive?
+
−
    if not @assetport
+
−
        return false
+
−
    end
+
−
    begin
+
−
        # fetch the moon
+
−
        xml = open("http://#{@host}:#{@assetport}/assets/ec4b9f0b-d008-45c6-96a4-01dd947ac621").read
+
−
        # we need to check that we got something, because everything returns success, even if it didn't work
+
−
        if xml.size > 0
+
−
            return true
+
−
        else
+
−
            return false
+
−
        end
+
−
    rescue => e
+
−
        return false
+
−
    end
+
−
end
+
−
 
+
−
def inv_alive?
+
−
    if not @userport
+
−
      return false
+
−
    end
+
−
    return true
+
−
    # THERE IS CURRENTLY NO EASY CALL FOR INV SERVER
+
−
    # we actually only care if we cause an exception, which means the grid server is bust
+
−
    begin
+
−
        xml = open("http://#{@host}:#{@port}/get_grid_info").read
+
−
        return true
+
−
    rescue => e
+
−
        return false
+
−
    end
+
−
end
+
−
 
+
−
def message_alive?
+
−
    if not @messageport
+
−
        return false
+
−
    end
+
−
    return true
+
−
end
+
−
 
+
−
 
+
−
def pidof(item)
+
−
    IO.popen("ps auxw | grep #{item} | grep -v grep") do |line|
+
−
        line.each do |l|
+
−
            return l.split[1].to_i
+
−
        end
+
−
    end
+
−
    return nil
+
−
end
+
−
 
+
−
def grid_pid
+
−
    return pidof(GridExe)
+
−
end
+
−
def user_pid
+
−
    return pidof(UserExe)
+
−
end
+
−
def asset_pid
+
−
    return pidof(AssetExe)
+
−
end
+
−
def inv_pid
+
−
    return pidof(InventoryExe)
+
−
end
+
−
def message_pid
+
−
    return pidof(MessagingExe)
+
−
end
+
−
 
+
−
def failme(msg="")
+
−
    puts "FAIL - #{msg}"
+
−
    exit 1
+
−
end
+
−
 
+
−
def status
+
−
    if @gridport and (not grid_alive?)
+
−
        failme("Grid server not responding")
+
−
    end
+
−
    if @userport and (not user_alive?)
+
−
        failme("User server not responding")
+
−
    end
+
−
    if @assetport and (not asset_alive?)
+
−
        failme("Asset server not responding")
+
−
    end
+
−
    if @invport and (not inv_alive?)
+
−
        failme("Inventory server not responding")
+
−
    end
+
−
    if @messageport and (not message_alive?)
+
−
        failme("Grid server not responding")
+
−
    end
+
−
    puts "OK"
+
−
    exit 0
+
−
end
+
−
 
+
−
def start_service(name, exe)
+
−
    if pidof(exe) != nil
+
−
        puts("#{exe} already running")
+
−
        return
+
−
    end
+
−
    system("screen -d -S #{name} -m /usr/local/bin/mono --debug #{exe}")
+
−
end
+
−
 
+
−
def start
+
−
    # Grid
+
−
    start_service("grid", GridExe)
+
−
    10.times do |d|
+
−
        if grid_alive?
+
−
            break
+
−
        end
+
−
        sleep 2
+
−
    end
+
−
    if not grid_alive?
+
−
        failme("Grid server did not start")
+
−
    end
+
−
 
+
−
    # User
+
−
    start_service("user", UserExe)
+
−
    10.times do |d|
+
−
        if user_alive?
+
−
            break
+
−
        end
+
−
        sleep 2
+
−
    end
+
−
    if not user_alive?
+
−
        failme("User server did not start")
+
−
    end
+
−
 
+
−
    # Asset
+
−
    start_service("asset", AssetExe)
+
−
    10.times do |d|
+
−
        if asset_alive?
+
−
            break
+
−
        end
+
−
        sleep 2
+
−
    end
+
−
    if not asset_alive?
+
−
        failme("Asset server did not start")
+
−
    end
+
−
 
+
−
    # Inventory
+
−
    start_service("inventory", InventoryExe)
+
−
    10.times do |d|
+
−
        if inv_alive?
+
−
            break
+
−
        end
+
−
        sleep 2
+
−
    end
+
−
    if not inv_alive?
+
−
        failme("Inventory server did not start")
+
−
    end
+
−
   
+
−
    # sleep an extra 2 because we didn't sleep at all here
+
−
    sleep 2
+
−
    # Messaging
+
−
    start_service("messaging", MessagingExe)
+
−
    10.times do |d|
+
−
        if message_alive?
+
−
            break
+
−
        end
+
−
        sleep 2
+
−
    end
+
−
    if not message_alive?
+
−
        failme("Messaging server did not start")
+
−
    end
+
−
end
+
−
 
+
−
def stop_service(name, exe)
+
−
    if pidof(exe) == nil
+
−
        puts "WARNING - #{exe} not running"
+
−
    end
+
−
    system("screen -S #{name} -X eval 'stuff \"shutdown\015\"'")
+
−
    puts "Shutting down... waiting 30 seconds"
+
−
    30.times do |i|
+
−
        if pidof(exe) == nil
+
−
            # just puts out a newline
+
−
            puts ""
+
−
            return
+
−
        end
+
−
        $stderr.write "."
+
−
        sleep 1
+
−
    end
+
−
   
+
−
    pid = pidof(exe)
+
−
    if pid
+
−
        puts "Process not responding, forcing shutdown"
+
−
        Process.kill(9, pid)
+
−
    end
+
−
end
+
−
 
+
−
def stop
+
−
    stop_service("messaging",MessagingExe)
+
−
    stop_service("inventory",InventoryExe)
+
−
    stop_service("asset",AssetExe)
+
−
    stop_service("user",UserExe)
+
−
    stop_service("grid",GridExe)
+
−
end
+
−
 
+
−
def process
+
−
    puts "Grid #{grid_pid}"
+
−
    puts "User #{user_pid}"
+
−
    puts "Asset #{asset_pid}"
+
−
    puts "Inventory #{inv_pid}"
+
−
    puts "Messaging #{message_pid}"
+
−
end
+
−
 
+
−
def main
+
−
    parse_config
+
−
   
+
−
    mode = ARGV[0]
+
−
   
+
−
    if mode == "start"
+
−
        start
+
−
    elsif mode == "stop"
+
−
        stop
+
−
    elsif mode == "status"
+
−
        status
+
−
    elsif mode == "process"
+
−
        process
+
−
    elsif mode == "restart"
+
−
        puts "called restart"
+
−
    else
+
−
        puts "unknown"
+
−
    end
+
−
end
+
−
 
+
−
main
+
−
</source>
+

Revision as of 09:58, 31 January 2009

OpenSim Init Scripts

There is now a forge project for Service Scripts for OpenSim that contains init scripts for running OpenSim.

Personal tools
General
About This Wiki