irgat 0.0.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- data/History.txt +4 -0
- data/Manifest.txt +45 -0
- data/PostInstall.txt +4 -0
- data/README.rdoc +29 -0
- data/Rakefile +4 -0
- data/TODO +26 -0
- data/bin/irgat +87 -0
- data/bin/irgat_setup +135 -0
- data/config/hoe.rb +80 -0
- data/config/requirements.rb +15 -0
- data/lib/irgat.rb +94 -0
- data/lib/irgat/console.rb +85 -0
- data/lib/irgat/dependencies.rb +75 -0
- data/lib/irgat/execs.rb +73 -0
- data/lib/irgat/log.rb +116 -0
- data/lib/irgat/mail.rb +88 -0
- data/lib/irgat/utils.rb +17 -0
- data/lib/irgat/version.rb +10 -0
- data/lib/modules/backup.rb +348 -0
- data/lib/modules/console.rb +48 -0
- data/lib/modules/kwallet.rb +133 -0
- data/script/console +10 -0
- data/script/destroy +14 -0
- data/script/generate +14 -0
- data/script/txt2html +82 -0
- data/setup.rb +1585 -0
- data/setup/etc/backup.yml.example +103 -0
- data/setup/etc/chroot.yml.example +42 -0
- data/setup/etc/console.yml.default +11 -0
- data/setup/etc/cron.yml.example +56 -0
- data/setup/etc/dar.yml.example +16 -0
- data/setup/etc/irgat.yml.example +37 -0
- data/setup/etc/kwallet.yml.default +18 -0
- data/setup/etc/kwallet.yml.example +18 -0
- data/setup/etc/ssh.yml.example +17 -0
- data/tasks/deployment.rake +34 -0
- data/tasks/environment.rake +7 -0
- data/tasks/website.rake +17 -0
- data/test/test_helper.rb +2 -0
- data/test/test_irgat.rb +11 -0
- data/website/index.html +83 -0
- data/website/index.txt +83 -0
- data/website/javascripts/rounded_corners_lite.inc.js +285 -0
- data/website/stylesheets/screen.css +138 -0
- data/website/template.html.erb +48 -0
- metadata +157 -0
@@ -0,0 +1,103 @@
|
|
1
|
+
# IRGAT::Backup Class Configuration
|
2
|
+
#
|
3
|
+
# Look REDME.txt in your IRGAT::Irgat::PATG for more information
|
4
|
+
|
5
|
+
#---------------
|
6
|
+
# Backup Config
|
7
|
+
#---------------
|
8
|
+
# only dar avaible
|
9
|
+
backup_program: dar
|
10
|
+
|
11
|
+
# Path to the backups
|
12
|
+
working_path: /mnt/backups
|
13
|
+
|
14
|
+
# days to make a complete backup (0 -> Sunday, 1 -> Monday, etc.)
|
15
|
+
complet_backup_days: [ 0 ]
|
16
|
+
|
17
|
+
# number of complete backups stored in the system
|
18
|
+
number_backup_stored: 2
|
19
|
+
|
20
|
+
# exclude folders from backup, absolute path without first slash
|
21
|
+
# for example var/tmp
|
22
|
+
exclude_folders: [ boot, etc, dev, home, initrd, lib, media, mnt, opt, proc, root, sbin, srv, sys, tmp, usr, var]
|
23
|
+
|
24
|
+
# extensions ommited inside backup files
|
25
|
+
exclude_files: [ .dar ]
|
26
|
+
|
27
|
+
# exclude types in the compress phase
|
28
|
+
exclude_to_compress: [ .gz, .bz2, .zip, .png ]
|
29
|
+
|
30
|
+
#---------------------
|
31
|
+
# Dumps MySQL options
|
32
|
+
#---------------------
|
33
|
+
# if you enable this option, Irgat performs for you a dump for each database
|
34
|
+
# stored in your mysql server, compresed with gzip
|
35
|
+
dump_mysql: false
|
36
|
+
# just in case needed
|
37
|
+
mysql_user: 'root'
|
38
|
+
mysql_pass: ''
|
39
|
+
|
40
|
+
#--------------------------
|
41
|
+
# Distribute backup options
|
42
|
+
#--------------------------
|
43
|
+
# if you enable this option, irgat performs for you a distributed copy of the dar files
|
44
|
+
# to each machined defined inside the distribution_servers option
|
45
|
+
distribute_backups: false
|
46
|
+
# just in case needed
|
47
|
+
# distribution_servers:
|
48
|
+
# balrog:
|
49
|
+
# host: example.com
|
50
|
+
# port: 22
|
51
|
+
# user: foo
|
52
|
+
# remote_folder: /mnt/backup
|
53
|
+
# number_stored_backups: 1
|
54
|
+
|
55
|
+
# Method for distribution, avaible => scp
|
56
|
+
distribute_method: scp
|
57
|
+
# Options for the scp distributed method
|
58
|
+
scp_distribute_method:
|
59
|
+
local_user: nogates # local user to perform the copy and querys
|
60
|
+
with_keys: true # if its true, the scp and ssh commans are maked without pass
|
61
|
+
needed_programs: [ scp, ssh ] # programs needed by scp distributed method
|
62
|
+
# Options for ftp distributed method
|
63
|
+
# TODO
|
64
|
+
|
65
|
+
#-------------------
|
66
|
+
# NFS mounted folder
|
67
|
+
#-------------------
|
68
|
+
# check if the folder target needed to be mounted
|
69
|
+
mounted_folder: false
|
70
|
+
|
71
|
+
#----------------------------
|
72
|
+
# Non common change variables
|
73
|
+
#----------------------------
|
74
|
+
# Subsystem variable
|
75
|
+
subsystem_name: backups
|
76
|
+
subsystem_description: 'Irgat backup module'
|
77
|
+
run_as_user: root
|
78
|
+
# output notification
|
79
|
+
output_log: true # log will be stored in <irgat_log_path>/backup/
|
80
|
+
output_email: true # log will be sended to email
|
81
|
+
|
82
|
+
|
83
|
+
# Folders Tree (change if you known what are you doing!!!)
|
84
|
+
folders_tree:
|
85
|
+
- data
|
86
|
+
- data/local
|
87
|
+
- data/local/current
|
88
|
+
- data/local/old
|
89
|
+
- data/external
|
90
|
+
- catalog
|
91
|
+
- extras
|
92
|
+
- extras/mysql
|
93
|
+
|
94
|
+
|
95
|
+
# Dar variables
|
96
|
+
dar:
|
97
|
+
compression: 256 # enable compression. nil disable
|
98
|
+
file_size: 3500M # size of division each file
|
99
|
+
enable_empty_folders: true # enable backup empty folders
|
100
|
+
root_backup: '/' # root folder from backup
|
101
|
+
encrypt_passwd: 'akOYWka' # password to encrypt backups
|
102
|
+
decrypt_passwd: 'akOYWka' # password to decrypt backups
|
103
|
+
|
@@ -0,0 +1,42 @@
|
|
1
|
+
# IRGAT chroot config file:
|
2
|
+
# Look <your irgat path>/README for more information
|
3
|
+
|
4
|
+
subsystem_name: chroot
|
5
|
+
subsystem_description: 'IRGAT chroot utility, launch and controls daemons'
|
6
|
+
|
7
|
+
# Define your chroot path
|
8
|
+
# ex: chroot_path: '/var/local/chroot/'
|
9
|
+
chroot_path: ''
|
10
|
+
|
11
|
+
# Define the daemons running in chroot
|
12
|
+
init_daemons:
|
13
|
+
apache: true
|
14
|
+
apache2: true
|
15
|
+
bind9: false
|
16
|
+
courier-authdaemon: false
|
17
|
+
courier-pop: false
|
18
|
+
courier-pop-ssl: true
|
19
|
+
courier-imap: false
|
20
|
+
mongrel_cluster: true
|
21
|
+
mysql: true
|
22
|
+
postfix: false
|
23
|
+
proftpd: false
|
24
|
+
vhcs2_daemon: false
|
25
|
+
|
26
|
+
# Define what folders do you want be mounted in chroot
|
27
|
+
# FIXME: insecure mounting of /proc
|
28
|
+
# Mount folders are mounted by normal mount issue
|
29
|
+
# bind folders, are only binding with mount command, so the not appear in /etc/fstab
|
30
|
+
# or in proc from chroot
|
31
|
+
|
32
|
+
mount_folders:
|
33
|
+
mount:
|
34
|
+
- /proc
|
35
|
+
- /sys
|
36
|
+
bind:
|
37
|
+
- /lib/modules
|
38
|
+
|
39
|
+
# Define anothers programs do you want to be launched when chroot start
|
40
|
+
launch_programs:
|
41
|
+
zabbix_server: true
|
42
|
+
zabbix_agentd: true
|
@@ -0,0 +1,11 @@
|
|
1
|
+
# load the following modules
|
2
|
+
load_modules: all # [ array ] || all || none
|
3
|
+
|
4
|
+
#----------------------------
|
5
|
+
# Non common change variables
|
6
|
+
#----------------------------
|
7
|
+
# Subsystem variable
|
8
|
+
subsystem_name: console
|
9
|
+
subsystem_description: 'Irgat console module'
|
10
|
+
run_as_root: false
|
11
|
+
report_email: false
|
@@ -0,0 +1,56 @@
|
|
1
|
+
# IRGAT cron config file:
|
2
|
+
# Look <your irgat path>/README for more information
|
3
|
+
|
4
|
+
subsystem_name: cron
|
5
|
+
subsystem_description: 'IRGAT cron utility'
|
6
|
+
|
7
|
+
# Irgat cron define task, that must be launched at several times...
|
8
|
+
# The config, is more intuitive like cron config...
|
9
|
+
#
|
10
|
+
# Define a period, this period is the repetition
|
11
|
+
# period (each_min || each_hour || each_day || each_week || each_month || each_year)
|
12
|
+
#
|
13
|
+
# Each period, have their own herierchy, for example, if you define each_week
|
14
|
+
# you have to choose which days, which hours and which mins...
|
15
|
+
# if you don't specifym the options under hiererchy, it is asume thats true
|
16
|
+
#
|
17
|
+
# To control the values of the period, you have the variables, except, only and all.
|
18
|
+
# Only launch the cron 'only' in this period... 'except', launch if the period is not
|
19
|
+
# equal as the listed in the option. 'always' asume allways to launch it
|
20
|
+
#
|
21
|
+
# Also, multiple time periods can be defined, in the below example, the task
|
22
|
+
# 'do_backup' is launched all the days (by normal day period time), but not sunday
|
23
|
+
# at 03:00. Sunday is launched at 23:00 hours by sunday_day period time
|
24
|
+
#
|
25
|
+
#
|
26
|
+
#
|
27
|
+
#tasks:
|
28
|
+
# do_backup:
|
29
|
+
# normal_day:
|
30
|
+
# - hour: 03
|
31
|
+
# - minute: 00
|
32
|
+
# - except: 0
|
33
|
+
# sunday_day:
|
34
|
+
# - hour: 01
|
35
|
+
# - minute: 00
|
36
|
+
# - only: 0
|
37
|
+
# command:
|
38
|
+
# - macro: true
|
39
|
+
# - name: 'do_backup'
|
40
|
+
|
41
|
+
|
42
|
+
tasks:
|
43
|
+
do_backup:
|
44
|
+
normal_day:
|
45
|
+
- hour: '2'
|
46
|
+
- min: '00'
|
47
|
+
- always:
|
48
|
+
action:
|
49
|
+
- type: macro
|
50
|
+
- command: 'do_backup'
|
51
|
+
check_zabbix_server:
|
52
|
+
all_min:
|
53
|
+
- always:
|
54
|
+
action:
|
55
|
+
- type: command
|
56
|
+
- command: 'ps aux | grep zabbix_server'
|
@@ -0,0 +1,16 @@
|
|
1
|
+
command: dar
|
2
|
+
description: Disk Archiver
|
3
|
+
alias:
|
4
|
+
options:
|
5
|
+
1:
|
6
|
+
name: create
|
7
|
+
description: creates a backup
|
8
|
+
ci_parameter: [ '-c', '--create']
|
9
|
+
arguments:
|
10
|
+
1: %file_url
|
11
|
+
2:
|
12
|
+
name: extract
|
13
|
+
description: extrac file from the given backup
|
14
|
+
ci_parameter: [ '-x', '--extract']
|
15
|
+
arguments:
|
16
|
+
1: %file_url
|
@@ -0,0 +1,37 @@
|
|
1
|
+
# IRGAT config file:
|
2
|
+
# Look <your irgat path>/README for more information
|
3
|
+
|
4
|
+
# Server Variables
|
5
|
+
# server_name: my server
|
6
|
+
server_name: llopart
|
7
|
+
server_domain: litura.gnoxys.net
|
8
|
+
|
9
|
+
# Email notifications
|
10
|
+
mail_to: maquinas@gnoxys.net
|
11
|
+
|
12
|
+
|
13
|
+
# Enable subsystem
|
14
|
+
enable_subsystem:
|
15
|
+
console : true
|
16
|
+
backup: true
|
17
|
+
|
18
|
+
# Languaje
|
19
|
+
# avaible en
|
20
|
+
lang: en
|
21
|
+
|
22
|
+
# Log facilities
|
23
|
+
log_path: /var/log/irgat
|
24
|
+
|
25
|
+
# debug level: set the nivel of output
|
26
|
+
# 1: standard: Process points && Commands Status
|
27
|
+
# 2: warning: Warnings
|
28
|
+
# 3: complet: Launched Commands && Verbose
|
29
|
+
debug_level: 1
|
30
|
+
|
31
|
+
smtp_mode: sendmail
|
32
|
+
# if smtp
|
33
|
+
smtp_values:
|
34
|
+
server: smtp.gnoxys.net
|
35
|
+
port: 25
|
36
|
+
user: foo
|
37
|
+
password: bar
|
@@ -0,0 +1,18 @@
|
|
1
|
+
# IRGAT config kwallet file:
|
2
|
+
# Look <your irgat path>/README for more information
|
3
|
+
|
4
|
+
# Name of your Def Kwallet
|
5
|
+
kwallet_name: gnoxys
|
6
|
+
|
7
|
+
# path to the files
|
8
|
+
local_path: /home/user/.kde/share/apps/kwallet/
|
9
|
+
# remote path is checked by ssh connections agains the especified server.
|
10
|
+
# No other methods (svn will be great) are implemented yet.
|
11
|
+
remote_path:
|
12
|
+
server: litura.gnoxys.net
|
13
|
+
port: 22229
|
14
|
+
user: nogates
|
15
|
+
folder: /home/nogates/
|
16
|
+
|
17
|
+
|
18
|
+
|
@@ -0,0 +1,18 @@
|
|
1
|
+
# IRGAT config kwallet file:
|
2
|
+
# Look <your irgat path>/README for more information
|
3
|
+
|
4
|
+
# Name of your Def Kwallet
|
5
|
+
kwallet_name: my_wallet
|
6
|
+
|
7
|
+
# path to the files
|
8
|
+
local_path: /home/user/.kde/share/apps/kwallet/
|
9
|
+
# remote path is checked by ssh connections agains the especified server.
|
10
|
+
# No other methods (svn will be great) are implemented yet.
|
11
|
+
remote_path:
|
12
|
+
server: litura.gnoxys.net
|
13
|
+
port: 22229
|
14
|
+
user: nogates
|
15
|
+
folder: /home/nogates/
|
16
|
+
|
17
|
+
|
18
|
+
|
@@ -0,0 +1,17 @@
|
|
1
|
+
# IRGAT config ssh file:
|
2
|
+
# Look <your irgat path>/README for more information
|
3
|
+
|
4
|
+
# Define your servers
|
5
|
+
servers:
|
6
|
+
foo:
|
7
|
+
host: foo.example.com
|
8
|
+
port: 22228
|
9
|
+
user: emma
|
10
|
+
# if use key is true, irgat::ssh won't get the password for kwallet
|
11
|
+
use_key: true
|
12
|
+
allow_root: true
|
13
|
+
# options for the password
|
14
|
+
wallet: gnoxys
|
15
|
+
wallet_folder: gnoxys
|
16
|
+
wallet_key_user: emma_foo
|
17
|
+
wallet_key_root: root_foo
|
@@ -0,0 +1,34 @@
|
|
1
|
+
desc 'Release the website and new gem version'
|
2
|
+
task :deploy => [:check_version, :website, :release] do
|
3
|
+
puts "Remember to create SVN tag:"
|
4
|
+
puts "svn copy svn+ssh://#{rubyforge_username}@rubyforge.org/var/svn/#{PATH}/trunk " +
|
5
|
+
"svn+ssh://#{rubyforge_username}@rubyforge.org/var/svn/#{PATH}/tags/REL-#{VERS} "
|
6
|
+
puts "Suggested comment:"
|
7
|
+
puts "Tagging release #{CHANGES}"
|
8
|
+
end
|
9
|
+
|
10
|
+
desc 'Runs tasks website_generate and install_gem as a local deployment of the gem'
|
11
|
+
task :local_deploy => [:website_generate, :install_gem]
|
12
|
+
|
13
|
+
task :check_version do
|
14
|
+
unless ENV['VERSION']
|
15
|
+
puts 'Must pass a VERSION=x.y.z release version'
|
16
|
+
exit
|
17
|
+
end
|
18
|
+
unless ENV['VERSION'] == VERS
|
19
|
+
puts "Please update your version.rb to match the release version, currently #{VERS}"
|
20
|
+
exit
|
21
|
+
end
|
22
|
+
end
|
23
|
+
|
24
|
+
desc 'Install the package as a gem, without generating documentation(ri/rdoc)'
|
25
|
+
task :install_gem_no_doc => [:clean, :package] do
|
26
|
+
sh "#{'sudo ' unless Hoe::WINDOZE }gem install pkg/*.gem --no-rdoc --no-ri"
|
27
|
+
end
|
28
|
+
|
29
|
+
namespace :manifest do
|
30
|
+
desc 'Recreate Manifest.txt to include ALL files'
|
31
|
+
task :refresh do
|
32
|
+
`rake check_manifest | patch -p0 > Manifest.txt`
|
33
|
+
end
|
34
|
+
end
|
data/tasks/website.rake
ADDED
@@ -0,0 +1,17 @@
|
|
1
|
+
desc 'Generate website files'
|
2
|
+
task :website_generate => :ruby_env do
|
3
|
+
(Dir['website/**/*.txt'] - Dir['website/version*.txt']).each do |txt|
|
4
|
+
sh %{ #{RUBY_APP} script/txt2html #{txt} > #{txt.gsub(/txt$/,'html')} }
|
5
|
+
end
|
6
|
+
end
|
7
|
+
|
8
|
+
desc 'Upload website files to rubyforge'
|
9
|
+
task :website_upload do
|
10
|
+
host = "#{rubyforge_username}@rubyforge.org"
|
11
|
+
remote_dir = "/var/www/gforge-projects/#{PATH}/"
|
12
|
+
local_dir = 'website'
|
13
|
+
sh %{rsync -aCv #{local_dir}/ #{host}:#{remote_dir}}
|
14
|
+
end
|
15
|
+
|
16
|
+
desc 'Generate and upload website files'
|
17
|
+
task :website => [:website_generate, :website_upload, :publish_docs]
|
data/test/test_helper.rb
ADDED
data/test/test_irgat.rb
ADDED
data/website/index.html
ADDED
@@ -0,0 +1,83 @@
|
|
1
|
+
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN"
|
2
|
+
"http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd">
|
3
|
+
<html xmlns="http://www.w3.org/1999/xhtml" xml:lang="en" lang="en">
|
4
|
+
<head>
|
5
|
+
<link rel="stylesheet" href="stylesheets/screen.css" type="text/css" media="screen" />
|
6
|
+
<meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
|
7
|
+
<title>
|
8
|
+
irgat
|
9
|
+
</title>
|
10
|
+
<script src="javascripts/rounded_corners_lite.inc.js" type="text/javascript"></script>
|
11
|
+
<style>
|
12
|
+
|
13
|
+
</style>
|
14
|
+
<script type="text/javascript">
|
15
|
+
window.onload = function() {
|
16
|
+
settings = {
|
17
|
+
tl: { radius: 10 },
|
18
|
+
tr: { radius: 10 },
|
19
|
+
bl: { radius: 10 },
|
20
|
+
br: { radius: 10 },
|
21
|
+
antiAlias: true,
|
22
|
+
autoPad: true,
|
23
|
+
validTags: ["div"]
|
24
|
+
}
|
25
|
+
var versionBox = new curvyCorners(settings, document.getElementById("version"));
|
26
|
+
versionBox.applyCornersToAll();
|
27
|
+
}
|
28
|
+
</script>
|
29
|
+
</head>
|
30
|
+
<body>
|
31
|
+
<div id="main">
|
32
|
+
|
33
|
+
<h1>irgat</h1>
|
34
|
+
<div id="version" class="clickable" onclick='document.location = "http://rubyforge.org/projects/irgat"; return false'>
|
35
|
+
<p>Get Version</p>
|
36
|
+
<a href="http://rubyforge.org/projects/irgat" class="numbers">0.0.1</a>
|
37
|
+
</div>
|
38
|
+
<h1>&#x2192; ‘irgat’</h1>
|
39
|
+
<h2>What</h2>
|
40
|
+
<h2>Installing</h2>
|
41
|
+
<p><pre class='syntax'><span class="ident">sudo</span> <span class="ident">gem</span> <span class="ident">install</span> <span class="ident">irgat</span></pre></p>
|
42
|
+
<h2>The basics</h2>
|
43
|
+
<h2>Demonstration of usage</h2>
|
44
|
+
<h2>Forum</h2>
|
45
|
+
<p><a href="http://groups.google.com/group/irgat">http://groups.google.com/group/irgat</a></p>
|
46
|
+
<p><span class="caps">TODO</span> – create Google Group – irgat</p>
|
47
|
+
<h2>How to submit patches</h2>
|
48
|
+
<p>Read the <a href="http://drnicwilliams.com/2007/06/01/8-steps-for-fixing-other-peoples-code/">8 steps for fixing other people’s code</a> and for section <a href="http://drnicwilliams.com/2007/06/01/8-steps-for-fixing-other-peoples-code/#8b-google-groups">8b: Submit patch to Google Groups</a>, use the Google Group above.</p>
|
49
|
+
<p><span class="caps">TODO</span> – pick <span class="caps">SVN</span> or Git instructions</p>
|
50
|
+
<p>The trunk repository is <code>svn://rubyforge.org/var/svn/irgat/trunk</code> for anonymous access.</p>
|
51
|
+
<p><span class="caps">OOOORRRR</span></p>
|
52
|
+
<p>You can fetch the source from either:</p>
|
53
|
+
<ul>
|
54
|
+
<li>rubyforge: <a href="http://rubyforge.org/scm/?group_id=7188">http://rubyforge.org/scm/?group_id=7188</a></li>
|
55
|
+
</ul>
|
56
|
+
<pre>git clone git://rubyforge.org/irgat.git</pre>
|
57
|
+
<ul>
|
58
|
+
<li>github: <a href="http://github.com/GITHUB_USERNAME/irgat/tree/master">http://github.com/GITHUB_USERNAME/irgat/tree/master</a></li>
|
59
|
+
</ul>
|
60
|
+
<pre>git clone git://github.com/GITHUB_USERNAME/irgat.git</pre>
|
61
|
+
<p><span class="caps">TODO</span> – add “github_username: username” to ~/.rubyforge/user-config.yml and newgem will reuse it for future projects.</p>
|
62
|
+
<ul>
|
63
|
+
<li>gitorious: <a href="git://gitorious.org/irgat/mainline.git">git://gitorious.org/irgat/mainline.git</a></li>
|
64
|
+
</ul>
|
65
|
+
<pre>git clone git://gitorious.org/irgat/mainline.git</pre>
|
66
|
+
<h3>Build and test instructions</h3>
|
67
|
+
<pre>cd irgat
|
68
|
+
rake test
|
69
|
+
rake install_gem</pre>
|
70
|
+
<h2>License</h2>
|
71
|
+
<p>This code is free to use under the terms of the <span class="caps">MIT</span> license.</p>
|
72
|
+
<h2>Contact</h2>
|
73
|
+
<p>Comments are welcome. Send an email to <a href="mailto:FIXME"><span class="caps">FIXME</span> full name</a> email via the <a href="http://groups.google.com/group/irgat">forum</a></p>
|
74
|
+
<p class="coda">
|
75
|
+
<a href="FIXME email">FIXME full name</a>, 27th October 2008<br>
|
76
|
+
Theme extended from <a href="http://rb2js.rubyforge.org/">Paul Battley</a>
|
77
|
+
</p>
|
78
|
+
</div>
|
79
|
+
|
80
|
+
<!-- insert site tracking codes here, like Google Urchin -->
|
81
|
+
|
82
|
+
</body>
|
83
|
+
</html>
|