syncwrap 1.5.2 → 2.0.0

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.
Files changed (107) hide show
  1. checksums.yaml +7 -0
  2. data/History.rdoc +19 -0
  3. data/Manifest.txt +82 -34
  4. data/README.rdoc +96 -48
  5. data/Rakefile +0 -65
  6. data/bin/syncwrap +27 -0
  7. data/examples/LAYOUT.rdoc +70 -0
  8. data/examples/Rakefile +16 -0
  9. data/examples/ec2.rb +44 -0
  10. data/examples/hello.rb +14 -0
  11. data/examples/hello_binding.rb +27 -0
  12. data/examples/jruby.rb +11 -0
  13. data/examples/private/aws.json +4 -0
  14. data/examples/rput.rb +24 -0
  15. data/examples/sync/home/bob/.ssh/authorized_keys +1 -0
  16. data/examples/sync/tmp/sample.erb +3 -0
  17. data/lib/syncwrap/amazon_ec2.rb +236 -0
  18. data/lib/syncwrap/amazon_ws.rb +308 -0
  19. data/lib/syncwrap/base.rb +4 -2
  20. data/lib/syncwrap/cli.rb +328 -0
  21. data/lib/syncwrap/component.rb +443 -0
  22. data/lib/syncwrap/components/commercial_jdk.rb +76 -0
  23. data/lib/syncwrap/components/cruby_vm.rb +144 -0
  24. data/lib/syncwrap/components/etc_hosts.rb +44 -0
  25. data/lib/syncwrap/{geminabox.rb → components/geminabox.rb} +12 -17
  26. data/lib/syncwrap/components/hashdot.rb +97 -0
  27. data/lib/syncwrap/components/iyyov.rb +144 -0
  28. data/lib/syncwrap/components/iyyov_daemon.rb +125 -0
  29. data/lib/syncwrap/components/jruby_vm.rb +122 -0
  30. data/lib/syncwrap/components/mdraid.rb +204 -0
  31. data/lib/syncwrap/components/network.rb +99 -0
  32. data/lib/syncwrap/components/open_jdk.rb +70 -0
  33. data/lib/syncwrap/components/postgresql.rb +159 -0
  34. data/lib/syncwrap/components/qpid.rb +303 -0
  35. data/lib/syncwrap/components/rhel.rb +71 -0
  36. data/lib/syncwrap/components/run_user.rb +99 -0
  37. data/lib/syncwrap/components/ubuntu.rb +85 -0
  38. data/lib/syncwrap/components/users.rb +200 -0
  39. data/lib/syncwrap/context.rb +260 -0
  40. data/lib/syncwrap/distro.rb +53 -60
  41. data/lib/syncwrap/formatter.rb +149 -0
  42. data/lib/syncwrap/host.rb +134 -0
  43. data/lib/syncwrap/main.rb +62 -0
  44. data/lib/syncwrap/path_util.rb +55 -0
  45. data/lib/syncwrap/rsync.rb +227 -0
  46. data/lib/syncwrap/ruby_support.rb +110 -0
  47. data/lib/syncwrap/shell.rb +207 -0
  48. data/lib/syncwrap.rb +367 -1
  49. data/{etc → sync/etc}/gemrc +1 -3
  50. data/sync/etc/hosts.erb +8 -0
  51. data/{etc/init.d/iyyov → sync/etc/init.d/iyyov.erb} +35 -7
  52. data/sync/etc/sysconfig/pgsql/postgresql.erb +2 -0
  53. data/sync/src/hashdot/Makefile.erb +98 -0
  54. data/sync/src/hashdot/profiles/default.hdp.erb +25 -0
  55. data/sync/src/hashdot/profiles/jruby-common.hdp +28 -0
  56. data/sync/src/hashdot/profiles/jruby-shortlived.hdp +9 -0
  57. data/sync/src/hashdot/profiles/jruby.hdp.erb +13 -0
  58. data/sync/src/hashdot/profiles/shortlived.hdp +6 -0
  59. data/sync/var/iyyov/default/config.rb +1 -0
  60. data/sync/var/iyyov/default/daemon.rb.erb +15 -0
  61. data/sync/var/iyyov/jobs.rb.erb +4 -0
  62. data/test/muddled_sync.rb +13 -0
  63. data/test/setup.rb +39 -0
  64. data/test/sync/d1/bar +1 -0
  65. data/test/sync/d1/foo.erb +1 -0
  66. data/test/sync/d3/d2/bar +1 -0
  67. data/test/sync/d3/d2/foo.erb +1 -0
  68. data/test/test_components.rb +108 -0
  69. data/test/test_context.rb +107 -0
  70. data/test/test_context_rput.rb +289 -0
  71. data/test/test_rsync.rb +138 -0
  72. data/test/test_shell.rb +233 -0
  73. data/test/test_space.rb +218 -0
  74. data/test/test_space_main.rb +40 -0
  75. data/test/zfile +1 -0
  76. metadata +204 -71
  77. data/etc/sysconfig/pgsql/postgresql +0 -2
  78. data/lib/syncwrap/aws.rb +0 -448
  79. data/lib/syncwrap/common.rb +0 -161
  80. data/lib/syncwrap/ec2.rb +0 -59
  81. data/lib/syncwrap/hashdot.rb +0 -70
  82. data/lib/syncwrap/iyyov.rb +0 -139
  83. data/lib/syncwrap/java.rb +0 -61
  84. data/lib/syncwrap/jruby.rb +0 -118
  85. data/lib/syncwrap/postgresql.rb +0 -135
  86. data/lib/syncwrap/qpid.rb +0 -251
  87. data/lib/syncwrap/remote_task.rb +0 -199
  88. data/lib/syncwrap/rhel.rb +0 -67
  89. data/lib/syncwrap/ubuntu.rb +0 -78
  90. data/lib/syncwrap/user_run.rb +0 -102
  91. data/test/test_syncwrap.rb +0 -202
  92. data/var/iyyov/jobs.rb +0 -11
  93. /data/{etc → sync/etc}/corosync/corosync.conf +0 -0
  94. /data/{etc → sync/etc}/corosync/uidgid.d/qpid +0 -0
  95. /data/{etc → sync/etc}/init.d/qpidd +0 -0
  96. /data/{etc → sync/etc}/sysctl.d/61-postgresql-shm.conf +0 -0
  97. /data/{usr/local → sync/jruby}/bin/jgem +0 -0
  98. /data/{postgresql → sync/postgresql}/rhel/pg_hba.conf +0 -0
  99. /data/{postgresql → sync/postgresql}/rhel/pg_ident.conf +0 -0
  100. /data/{postgresql → sync/postgresql}/rhel/postgresql.conf +0 -0
  101. /data/{postgresql → sync/postgresql}/ubuntu/environment +0 -0
  102. /data/{postgresql → sync/postgresql}/ubuntu/pg_ctl.conf +0 -0
  103. /data/{postgresql → sync/postgresql}/ubuntu/pg_hba.conf +0 -0
  104. /data/{postgresql → sync/postgresql}/ubuntu/pg_ident.conf +0 -0
  105. /data/{postgresql → sync/postgresql}/ubuntu/postgresql.conf +0 -0
  106. /data/{postgresql → sync/postgresql}/ubuntu/start.conf +0 -0
  107. /data/{usr → sync/usr}/local/etc/qpidd.conf +0 -0
@@ -0,0 +1,44 @@
1
+ #--
2
+ # Copyright (c) 2011-2014 David Kellum
3
+ #
4
+ # Licensed under the Apache License, Version 2.0 (the "License"); you
5
+ # may not use this file except in compliance with the License. You may
6
+ # obtain a copy of the License at
7
+ #
8
+ # http://www.apache.org/licenses/LICENSE-2.0
9
+ #
10
+ # Unless required by applicable law or agreed to in writing, software
11
+ # distributed under the License is distributed on an "AS IS" BASIS,
12
+ # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or
13
+ # implied. See the License for the specific language governing
14
+ # permissions and limitations under the License.
15
+ #++
16
+
17
+ require 'syncwrap/component'
18
+
19
+ module SyncWrap
20
+
21
+ # Provision/update an RFC 952 /etc/hosts file for "internal"
22
+ # intra-Space host resolution. This can be used for simple internal
23
+ # network resolution instead of DNS.
24
+ #
25
+ # Host component dependencies: none
26
+ class EtcHosts < Component
27
+
28
+ def initialize( opts = {} )
29
+ super
30
+ end
31
+
32
+ def install
33
+ rput( "etc/hosts", user: :root )
34
+ end
35
+
36
+ def etc_host_table
37
+ host.space.hosts.map do |h|
38
+ [ h[ :internal_ip ] || "# internal_ip?", [ h[ :name ] ] ]
39
+ end
40
+ end
41
+
42
+ end
43
+
44
+ end
@@ -1,5 +1,5 @@
1
1
  #--
2
- # Copyright (c) 2011-2013 David Kellum
2
+ # Copyright (c) 2011-2014 David Kellum
3
3
  #
4
4
  # Licensed under the Apache License, Version 2.0 (the "License"); you
5
5
  # may not use this file except in compliance with the License. You may
@@ -14,26 +14,21 @@
14
14
  # permissions and limitations under the License.
15
15
  #++
16
16
 
17
- require 'syncwrap/user_run'
18
- require 'syncwrap/jruby'
17
+ require 'syncwrap/components/iyyov_daemon'
19
18
 
20
- # Provisions the
21
- # {boxed-geminabox}[https://github.com/dekellum/boxed-geminabox/]
22
- # gem server.
23
- module SyncWrap::Geminabox
24
- include SyncWrap::UserRun
25
- include SyncWrap::JRuby
19
+ module SyncWrap
26
20
 
27
- attr_accessor :geminabox_version
21
+ # Provision the
22
+ # {boxed-geminabox}[https://github.com/dekellum/boxed-geminabox/]
23
+ # gem server as a simple specialization of IyyovDaemon.
24
+ #
25
+ # Host component dependencies: <Distro>, JrubyVM, RunUser, Iyyov
26
+ class Geminabox < IyyovDaemon
28
27
 
29
- def initialize
30
- super
31
- @geminabox_version = '1.0.0'
32
- end
28
+ def initialize( opts = {} )
29
+ super( { name: 'boxed-geminabox', version: '1.1.0' }.merge( opts ) )
30
+ end
33
31
 
34
- def geminabox_install
35
- jruby_install_gem( 'boxed-geminabox', :version => "=#{geminabox_version}" )
36
- user_run_service_dir_setup( 'boxed-geminabox' )
37
32
  end
38
33
 
39
34
  end
@@ -0,0 +1,97 @@
1
+ #--
2
+ # Copyright (c) 2011-2014 David Kellum
3
+ #
4
+ # Licensed under the Apache License, Version 2.0 (the "License"); you
5
+ # may not use this file except in compliance with the License. You may
6
+ # obtain a copy of the License at
7
+ #
8
+ # http://www.apache.org/licenses/LICENSE-2.0
9
+ #
10
+ # Unless required by applicable law or agreed to in writing, software
11
+ # distributed under the License is distributed on an "AS IS" BASIS,
12
+ # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or
13
+ # implied. See the License for the specific language governing
14
+ # permissions and limitations under the License.
15
+ #++
16
+
17
+ require 'syncwrap/component'
18
+
19
+ module SyncWrap
20
+
21
+ # Provision the {Hashdot}[http://hashdot.sourceforge.net/] JVM/script
22
+ # launcher by building it with gcc on the target host.
23
+ #
24
+ # Host component dependencies: <Distro>, <JDK>, JRubyVM
25
+ class Hashdot < Component
26
+
27
+ # Hashdot version (default: 1.4.0)
28
+ attr_accessor :hashdot_version
29
+
30
+ def initialize( opts = {} )
31
+ @hashdot_version = '1.4.0'
32
+
33
+ super
34
+ end
35
+
36
+ def hashdot_bin_url
37
+ [ 'http://downloads.sourceforge.net/project/hashdot/hashdot',
38
+ hashdot_version,
39
+ "hashdot-#{hashdot_version}-src.tar.gz" ].join( '/' )
40
+ end
41
+
42
+ # Install hashdot if the binary version doesn't match, otherwise
43
+ # just update the profile config files.
44
+ def install
45
+ if !test_hashdot_binary || dryrun?
46
+ install_system_deps
47
+ install_hashdot
48
+ else
49
+ # Just update config as needed.
50
+ rput( 'src/hashdot/profiles/',
51
+ "#{local_root}/lib/hashdot/profiles/",
52
+ excludes: :dev, user: :root )
53
+ end
54
+ end
55
+
56
+ def install_system_deps
57
+ dist_install( %w[ make gcc apr apr-devel ] )
58
+ end
59
+
60
+ def test_hashdot_binary
61
+ binary = "#{local_root}/bin/hashdot"
62
+ code,_ = capture( <<-SH, accept: [0,91,92] )
63
+ if [ -x #{binary} ]; then
64
+ cver=`#{binary} 2>&1 | grep -o -E '([0-9]\.?){2,}'`
65
+ if [ "$cver" = "#{hashdot_version}" ]; then
66
+ exit 0
67
+ fi
68
+ exit 92
69
+ fi
70
+ exit 91
71
+ SH
72
+ (code == 0)
73
+ end
74
+
75
+ def install_hashdot
76
+ src_root = '/tmp/src/hashdot'
77
+ src = "#{src_root}/hashdot-#{hashdot_version}"
78
+
79
+ sh <<-SH
80
+ sudo rm -rf /tmp/src
81
+ mkdir -p #{src_root}
82
+ curl -sSL #{hashdot_bin_url} | tar -C #{src_root} -zxf -
83
+ SH
84
+
85
+ rput( 'src/hashdot/', "#{src}/", :excludes => :dev )
86
+
87
+ sh <<-SH
88
+ cd #{src}
89
+ make
90
+ sudo make install
91
+ SH
92
+
93
+ end
94
+
95
+ end
96
+
97
+ end
@@ -0,0 +1,144 @@
1
+ #--
2
+ # Copyright (c) 2011-2014 David Kellum
3
+ #
4
+ # Licensed under the Apache License, Version 2.0 (the "License"); you
5
+ # may not use this file except in compliance with the License. You may
6
+ # obtain a copy of the License at
7
+ #
8
+ # http://www.apache.org/licenses/LICENSE-2.0
9
+ #
10
+ # Unless required by applicable law or agreed to in writing, software
11
+ # distributed under the License is distributed on an "AS IS" BASIS,
12
+ # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or
13
+ # implied. See the License for the specific language governing
14
+ # permissions and limitations under the License.
15
+ #++
16
+
17
+ require 'syncwrap/component'
18
+
19
+ # For distro class comparison only (pre-load for safety)
20
+ require 'syncwrap/components/ubuntu'
21
+
22
+ module SyncWrap
23
+
24
+ # Provision the {Iyyov}[http://rubydoc.info/gems/iyyov/] job
25
+ # scheduler and process monitor via jruby_gem_install. The
26
+ # installation setup and configuration templates assume use of a
27
+ # jobs.d directory, as supported in \Iyyov 1.3.0.
28
+ #
29
+ # Host component dependencies: <Distro>, JRubyVM, RunUser
30
+ class Iyyov < Component
31
+
32
+ attr_accessor :iyyov_version
33
+
34
+ def initialize( opts = {} )
35
+ @iyyov_version = '1.3.0'
36
+
37
+ super
38
+ end
39
+
40
+ # Deploy iyyov gem, init.d/iyyov and at least an empty jobs.rb.
41
+ def install
42
+ # Shorten if the desired iyyov version is already running
43
+ pid, ver = capture_running_version( 'iyyov' )
44
+ unless ver == iyyov_version
45
+ install_run_dir #as root
46
+ install_iyyov_gem #as root
47
+ install_iyyov_init #as root
48
+ iyyov_restart #as root
49
+ true
50
+ end
51
+ false
52
+ end
53
+
54
+ # Given name(-instance), check for name.pid in service_dir and
55
+ # extract the version number from the associated cmdline. If this
56
+ # is running out of installed gem directory (Iyyov itself,
57
+ # standard Iyyov daemons) then cmdline should reference the gem
58
+ # version. Returns [pid, version] or nil if not found running
59
+ def capture_running_version( name, instance = nil )
60
+ sdir = service_dir( name, instance )
61
+ code, out = capture( <<-SH, user: run_user, accept:[0,1,91] )
62
+ pid=$(< #{sdir}/#{name}.pid)
63
+ if [[ $(< /proc/$pid/cmdline) =~ -(([0-9]+)(\\.[0-9A-Za-z]+)+)[-/] ]]; then
64
+ echo $pid ${BASH_REMATCH[1]}
65
+ exit 0
66
+ fi
67
+ exit 91
68
+ SH
69
+ # Above accepts exit 1 as from $(< missing-file), since it would
70
+ # be a race to pre-check. Note '\\' escape is for this
71
+ # ruby here-doc.
72
+
73
+ if code == 0
74
+ pid, ver = out.strip.split( ' ' )
75
+ [ pid.to_i, ver ]
76
+ else
77
+ nil
78
+ end
79
+ end
80
+
81
+ # Update remote (run_dir/) iyyov/jobs.rb. If force is true, touch
82
+ # root jobs.rb even if it was not changed: forcing an iyyov config
83
+ # reload. Returns any changes in the rput change format,
84
+ # including any forced mtime update.
85
+ def iyyov_install_jobs( force = false )
86
+
87
+ changes = rput( 'var/iyyov/jobs.rb', iyyov_run_dir, user: run_user )
88
+
89
+ if force && changes.empty?
90
+ rudo "touch #{iyyov_run_dir}/jobs.rb"
91
+ changes << [ '.f..T......', "#{iyyov_run_dir}/jobs.rb" ]
92
+ end
93
+ changes
94
+ end
95
+
96
+ def iyyov_run_dir
97
+ "#{run_dir}/iyyov"
98
+ end
99
+
100
+ # Create iyyov run directory and make sure there is at minimum an
101
+ # empty jobs file. Avoid touching it if already present.
102
+ def install_run_dir
103
+ # Run as root for merging with the other install fragments.
104
+ sudo <<-SH
105
+ mkdir -p #{iyyov_run_dir}
106
+ mkdir -p #{iyyov_run_dir}/jobs.d
107
+ SH
108
+ chown_run_user( '-R', iyyov_run_dir )
109
+ sudo <<-SH
110
+ if [ ! -e #{iyyov_run_dir}/jobs.rb ]; then
111
+ su #{run_user} -c "touch #{iyyov_run_dir}/jobs.rb"
112
+ fi
113
+ SH
114
+ end
115
+
116
+ # Ensure install of same gem version as init.d/iyyov script
117
+ def install_iyyov_gem
118
+ jruby_gem_install( 'iyyov', version: iyyov_version )
119
+ end
120
+
121
+ # Install iyyov daemon init.d script and add to init daemons
122
+ def install_iyyov_init
123
+ rput( 'etc/init.d/iyyov', user: :root,
124
+ erb_vars: { lsb: distro.kind_of?( Ubuntu ) } )
125
+
126
+ # Add to init.d
127
+ dist_install_init_service( 'iyyov' )
128
+ end
129
+
130
+ def iyyov_start
131
+ dist_service( 'iyyov', 'start' )
132
+ end
133
+
134
+ def iyyov_stop
135
+ dist_service( 'iyyov', 'stop' )
136
+ end
137
+
138
+ def iyyov_restart
139
+ dist_service( 'iyyov', 'restart' )
140
+ end
141
+
142
+ end
143
+
144
+ end
@@ -0,0 +1,125 @@
1
+ #--
2
+ # Copyright (c) 2011-2014 David Kellum
3
+ #
4
+ # Licensed under the Apache License, Version 2.0 (the "License"); you
5
+ # may not use this file except in compliance with the License. You may
6
+ # obtain a copy of the License at
7
+ #
8
+ # http://www.apache.org/licenses/LICENSE-2.0
9
+ #
10
+ # Unless required by applicable law or agreed to in writing, software
11
+ # distributed under the License is distributed on an "AS IS" BASIS,
12
+ # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or
13
+ # implied. See the License for the specific language governing
14
+ # permissions and limitations under the License.
15
+ #++
16
+
17
+ require 'syncwrap/component'
18
+
19
+ module SyncWrap
20
+
21
+ # Provision a gem installed, Iyyov launched and monitored jruby
22
+ # daemon using a standard set of conventions. Can be used directly
23
+ # in the common case, or sub-classed as needed.
24
+ #
25
+ # Two :sync_paths files are searched for deployment: a config.rb and
26
+ # a jobs.d/<name>.rb. If concrete or .erb variants of these are not
27
+ # found than an (empty) default/config.rb and a generic
28
+ # default/daemon.rb.erb is used. Again, these will work in the common
29
+ # case.
30
+ #
31
+ # Host component dependencies: <Distro>, JRubyVM, RunUser, Iyyov
32
+ class IyyovDaemon < Component
33
+
34
+ # The daemon process name, also used for service_dir (along with any
35
+ # instance) and as the default gem_name. (required)
36
+ attr_accessor :name
37
+
38
+ # Name of the gem (set if different than name)
39
+ attr_writer :gem_name
40
+
41
+ # The (gem) version String (required)
42
+ attr_accessor :version
43
+
44
+ # An optional secondary instance name, useful if running more than
45
+ # one of 'name' on a host (default: nil)
46
+ attr_accessor :instance
47
+
48
+ def initialize( opts = {} )
49
+ @gem_version = nil
50
+ @gem_name = nil
51
+ @daemon_name = nil
52
+ @instance = nil
53
+
54
+ super
55
+
56
+ raise "IyyovDaemon#name property not set" unless name
57
+ raise "IyyovDaemon#version property not set" unless version
58
+ end
59
+
60
+ def gem_name
61
+ @gem_name || @name
62
+ end
63
+
64
+ def install
65
+ standard_install
66
+ end
67
+
68
+ protected
69
+
70
+ def standard_install
71
+
72
+ create_service_dir( name, instance )
73
+ changes = rput_service_config
74
+
75
+ # Shorten if the desired versioned process is already running.
76
+ pid, ver = capture_running_version( name, instance )
77
+ if ver != version
78
+ gem_install( gem_name, version: version )
79
+ changes += rput( job_source,
80
+ "#{iyyov_run_dir}/jobs.d/#{name_instance}.rb",
81
+ user: run_user )
82
+ changes += iyyov_install_jobs
83
+ elsif !changes.empty?
84
+ rudo( "kill #{pid} || true" ) # ..and let Iyyov restart it
85
+ end
86
+ changes
87
+ end
88
+
89
+ def rput_service_config
90
+ rput( config_source, "#{daemon_service_dir}/config.rb", user: run_user )
91
+ end
92
+
93
+ def daemon_service_dir
94
+ service_dir( name, instance )
95
+ end
96
+
97
+ def name_instance
98
+ [ name, instance ].compact.join( '-' )
99
+ end
100
+
101
+ def job_source
102
+ sjob = "var/iyyov/jobs.d/#{name_instance}.rb"
103
+ unless find_source( sjob )
104
+ sjob = "var/iyyov/jobs.d/#{name}.rb"
105
+ unless find_source( sjob )
106
+ sjob = "var/iyyov/default/daemon.rb.erb"
107
+ end
108
+ end
109
+ sjob
110
+ end
111
+
112
+ def config_source
113
+ sconf = "var/#{name_instance}/config.rb"
114
+ unless find_source( sconf )
115
+ sconf = "var/#{name}/config.rb"
116
+ unless find_source( sconf )
117
+ sconf = 'var/iyyov/default/config.rb'
118
+ end
119
+ end
120
+ sconf
121
+ end
122
+
123
+ end
124
+
125
+ end
@@ -0,0 +1,122 @@
1
+ #--
2
+ # Copyright (c) 2011-2014 David Kellum
3
+ #
4
+ # Licensed under the Apache License, Version 2.0 (the "License"); you
5
+ # may not use this file except in compliance with the License. You may
6
+ # obtain a copy of the License at
7
+ #
8
+ # http://www.apache.org/licenses/LICENSE-2.0
9
+ #
10
+ # Unless required by applicable law or agreed to in writing, software
11
+ # distributed under the License is distributed on an "AS IS" BASIS,
12
+ # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or
13
+ # implied. See the License for the specific language governing
14
+ # permissions and limitations under the License.
15
+ #++
16
+
17
+ require 'syncwrap/component'
18
+ require 'syncwrap/ruby_support'
19
+
20
+ module SyncWrap
21
+
22
+ # Provision JRuby (jruby.org - Ruby on the Java Virtual Machine) by
23
+ # direct download from public S3 repo. Includes utility methods for
24
+ # checking and installing JRuby gems.
25
+ #
26
+ # Host component dependencies: <Distro>
27
+ class JRubyVM < Component
28
+ include RubySupport
29
+
30
+ # JRuby version to install (default: 1.7.10)
31
+ attr_accessor :jruby_version
32
+
33
+ def initialize( opts = {} )
34
+ @jruby_version = '1.7.10'
35
+
36
+ super( { gem_command: 'jgem' }.merge( opts ) )
37
+ end
38
+
39
+ def jruby_dist_path
40
+ "#{local_root}/lib/jruby/jruby-#{jruby_version}"
41
+ end
42
+
43
+ def gemrc_path
44
+ "#{jruby_dist_path}/etc"
45
+ end
46
+
47
+ def jruby_gem_home
48
+ "#{local_root}/lib/jruby/gems"
49
+ end
50
+
51
+ # Install jruby if the jruby_version is not already present.
52
+ def install
53
+ jruby_install
54
+ install_gemrc
55
+ end
56
+
57
+ def jruby_bin_url
58
+ [ 'http://jruby.org.s3.amazonaws.com/downloads',
59
+ jruby_version,
60
+ "jruby-bin-#{jruby_version}.tar.gz" ].join( '/' )
61
+ end
62
+
63
+ # Install jruby, including usr/local/bin local contents
64
+ def jruby_install
65
+
66
+ root = "#{local_root}/lib/jruby"
67
+
68
+ sudo <<-SH
69
+ if [ ! -d #{jruby_dist_path} ]; then
70
+ mkdir -p #{root}
71
+ mkdir -p #{root}/gems
72
+ curl -sSL #{jruby_bin_url} | tar -C #{root} -zxf -
73
+ mkdir -p #{gemrc_path}
74
+ cd #{root} && ln -sfn jruby-#{jruby_version} jruby
75
+ cd #{local_root}/bin && ln -sf ../lib/jruby/jruby/bin/jirb .
76
+ fi
77
+ SH
78
+
79
+ rput( 'jruby/bin/', "#{local_root}/bin/", excludes: :dev, user: :root )
80
+ end
81
+
82
+ # See RubySupport#gem_install for usage.
83
+ #
84
+ # The jruby jgem command tends to be slow on virtual hardware.
85
+ # This implementation adds a faster short-circuit when an exact,
86
+ # single :version is given that avoids calling gem if the rubygems
87
+ # same version gemspec file is found.
88
+ def gem_install( gem, opts = {} )
89
+ version = Array( opts[ :version ] )
90
+ ver = (version.length == 1) && version[0] =~ /^=?\s*([0-9]\S+)/ && $1
91
+
92
+ unless ( opts[:check] || opts[:user_install] ||
93
+ opts[:minimize] == false || opts[:spec_check] == false ||
94
+ !version )
95
+
96
+ specs = [ "#{jruby_gem_home}/specifications/#{gem}-#{ver}-java.gemspec",
97
+ "#{jruby_gem_home}/specifications/#{gem}-#{ver}.gemspec" ]
98
+
99
+ sudo( "if [ ! -e '#{specs[0]}' -a ! -e '#{specs[1]}' ]; then",
100
+ close: "fi" ) do
101
+ super
102
+ end
103
+ else
104
+ super
105
+ end
106
+
107
+ end
108
+
109
+ alias :jruby_gem_install :gem_install
110
+
111
+ def min_deps_supported?
112
+ varray = jruby_version.split('.').map { |n| n.to_i }
113
+ ( varray <=> [1, 7, 5] ) >= 0
114
+ end
115
+
116
+ def jruby_gem_version_flags( reqs )
117
+ Array( reqs ).flatten.compact.map { |req| "-v'#{req}'" }
118
+ end
119
+
120
+ end
121
+
122
+ end