Statistics
| Branch: | Tag: | Revision:

one / share / install_gems / install_gems @ df6b93e6

History | View | Annotate | Download (10 KB)

1
#!/usr/bin/env ruby
2

    
3
require 'pp'
4

    
5
DEFAULT=%w{optional sunstone quota cloud ozones_server auth_ldap}
6

    
7
if defined?(RUBY_VERSION) && RUBY_VERSION>="1.8.7"
8
    SQLITE='sqlite3'
9

    
10
else
11
    SQLITE='sqlite3-ruby --version 1.2.0'
12
end
13

    
14
GROUPS={
15
    :optional => ['nokogiri'],
16
    :quota => [SQLITE, 'sequel'],
17
    :sunstone => ['json', 'rack', 'sinatra', 'thin', 'sequel', SQLITE],
18
    :cloud => %w{amazon-ec2 rack sinatra thin uuidtools curb json},
19
    :ozones_client => %w{json},
20
    :ozones_server => %w{json data_mapper dm-sqlite-adapter dm-mysql-adapter}+[
21
        SQLITE, 'mysql'
22
    ],
23
    :ozones_server_sqlite => %w{json data_mapper dm-sqlite-adapter}<<SQLITE,
24
    :ozones_server_mysql => %w{json data_mapper dm-mysql-adapter mysql},
25
    :auth_ldap => 'net-ldap'
26
}
27

    
28
PACKAGES=GROUPS.keys
29

    
30
GEM_TEST={
31
    'net-ldap' => 'net/ldap'
32
}
33

    
34
DISTRIBUTIONS={
35
    :debian => {
36
        :id => ['Ubuntu', 'Debian'],
37
        :dependencies => {
38
            SQLITE      => ['gcc', 'libsqlite3-dev'],
39
            'mysql'     => ['gcc', 'libmysqlclient-dev'],
40
            'curb'      => ['gcc', 'libcurl4-openssl-dev'],
41
            'nokogiri'  => %w{gcc rake libxml2-dev libxslt1-dev},
42
            'xmlparser' => ['gcc', 'libexpat1-dev'],
43
            'thin'      => ['g++'],
44
            'json'      => ['make', 'gcc']
45
        },
46
        :install_command => 'apt-get install',
47
        :gem_env    => {
48
            'rake'      => '/usr/bin/rake'
49
        }
50
    },
51
    :redhat => {
52
        :id => ['CentOS', /^RedHat/],
53
        :dependencies => {
54
            SQLITE      => ['gcc', 'sqlite-devel'],
55
            'mysql'     => ['gcc', 'mysql-devel'],
56
            'curb'      => ['gcc', 'curl-devel'],
57
            'nokogiri'  => %w{gcc rubygem-rake libxml2-devel libxslt-devel},
58
            'xmlparser' => ['gcc', 'expat-devel'],
59
            'thin'      => ['gcc-c++'],
60
            'json'      => ['make', 'gcc']
61
        },
62
        :install_command => 'yum install'
63
    },
64
    :suse => {
65
        :id => [/^SUSE/],
66
        :dependencies => {
67
            SQLITE      => ['gcc', 'sqlite3-devel'],
68
            'mysql'     => ['gcc', 'libmysqlclient-devel'],
69
            'curb'      => ['gcc', 'libcurl-devel'],
70
            'nokogiri'  => %w{rubygem-rake gcc rubygem-rake libxml2-devel libxslt-devel},
71
            'xmlparser' => ['gcc', 'libexpat-devel'],
72
            'thin'      => ['rubygem-rake', 'gcc-c++'],
73
            'json'      => ['make', 'gcc']
74
        },
75
        :install_command => 'zypper install'
76
    }
77
}
78

    
79

    
80
class String
81
    def unindent(spaces=4)
82
        self.gsub!(/^ {#{spaces}}/, '')
83
    end
84
end
85

    
86
def good_gem_version?
87
    v=`gem --version`.strip
88
    version=Gem::Version.new(v)
89
    version>=Gem::Version.new('1.3.6')
90
end
91

    
92
def select_distribution
93
    items=[]
94
    counter=0
95

    
96
    puts(<<-EOT.unindent(8))
97
        Select your distribution or press enter to continue without
98
        installing dependencies.
99

    
100
EOT
101

    
102
    DISTRIBUTIONS.each do |name, dist|
103
        names=dist[:id].map do |r|
104
            if Regexp===r
105
                r.source.gsub(/[^\w\d]/, '')
106
            else
107
                r
108
            end
109
        end.join('/')
110
        text="#{items.length}. #{names}"
111

    
112
        items << name
113

    
114
        puts text
115
    end
116

    
117
    puts
118

    
119
    options=(0..items.length).to_a.map {|k| k.to_s }
120

    
121
    option=STDIN.readline[0,1]
122

    
123
    if options.include?(option)
124
        item=items[option.to_i]
125
        [item, DISTRIBUTIONS[items[option.to_i]]]
126
    else
127
        nil
128
    end
129
end
130

    
131
def install_rubygems
132
    if !good_gem_version?
133
        puts(<<-EOT.unindent())
134
            The rubygems version installed is too old to install some required
135
            libraries. We are about to update your rubygems version. If you
136
            want to do this by other means cancel this installation with
137
            CTRL+C now.
138

    
139
            Press ENTER to continue...
140

    
141
EOT
142

    
143
        STDIN.readline
144

    
145
        `gem install rubygems-update --version '= 1.3.6'`
146

    
147
        if $?.exitstatus!=0
148
            puts "Error updating rubygems"
149
            exit(-1)
150
        end
151

    
152
        update_rubygems_path=[
153
            '/usr/bin/update_rubygems',
154
            '/var/lib/gems/1.8/bin/update_rubygems',
155
            '/var/lib/gems/1.9/bin/update_rubygems'
156
        ]
157

    
158
        installed=false
159

    
160
        update_rubygems_path.each do |path|
161
            if File.exist?(path)
162
                `#{path}`
163

    
164
                if $?.exitstatus!=0
165
                    puts "Error executing update_rubygems"
166
                    exit(-1)
167
                end
168

    
169
                installed=true
170
                break
171
             end
172
        end
173

    
174
        if !installed
175
            puts "Could not find update_rubygems executable"
176
            exit(-1)
177
        end
178
    end
179
end
180

    
181
def installed_gems
182
    text=`gem list --no-versions --no-details`
183
    if $?.exitstatus!=0
184
        nil
185
    else
186
        text.split(/\s+/)
187
    end
188
end
189

    
190
def try_library(name, error_message)
191
    if GEM_TEST[name.to_s]
192
        lib_test=GEM_TEST[name.to_s]
193
    else
194
        lib_test=name.to_s
195
    end
196

    
197
    begin
198
        require lib_test
199
    rescue LoadError, Exception
200
        STDERR.puts error_message
201
        exit(-1)
202
    end
203
end
204

    
205
def install_warning(packages)
206
#    puts "Use -h for help"
207
#    puts
208
    puts "About to install the gems for these components:"
209
    puts "* "<<packages.join("\n* ")
210
    puts
211
    puts "Press enter to continue..."
212
    yes=STDIN.readline
213
end
214

    
215
def help
216
    puts "Specify the package dependencies from this list:"
217
    puts "* "<<PACKAGES.join("\n* ")
218
    puts
219
    puts "If no parameters are specified then this list will be used:"
220
    puts DEFAULT.join(' ')
221
    puts
222
    puts "Use --check parameter to search for non installed libraries."
223
end
224

    
225
def get_gems(packages)
226
    packages.map do |package|
227
        GROUPS[package.to_sym]
228
    end.flatten.uniq-installed_gems
229
end
230

    
231
def detect_distro
232
    begin
233
        lsb_info=`lsb_release -a`
234
    rescue
235
    end
236

    
237
    if $?.exitstatus!=0
238
        STDERR.puts(<<-EOT.unindent(12))
239
            lsb_release command not found. If you are using a RedHat based
240
            distribution install redhat-lsb
241

    
242
EOT
243
        return nil
244
    end
245

    
246
    distribution_id=nil
247

    
248
    lsb_info.scan(/^Distributor ID:\s*(.*?)$/) do |m|
249
        distribution_id=m.first.strip
250
    end
251

    
252
    return nil if !distribution_id
253

    
254
    distro=nil
255

    
256
    DISTRIBUTIONS.find do |dist, info|
257
        info[:id].find do |dist_id|
258
            dist_id===distribution_id
259
        end
260
    end
261
end
262

    
263
def get_dependencies(gems, dependencies)
264
    deps=[]
265

    
266
    gems.each do |gem_name|
267
        deps<<dependencies[gem_name]
268
    end
269

    
270
    deps.flatten!
271
    deps.compact!
272
    deps.uniq!
273

    
274
    deps
275
end
276

    
277
def install_dependencies(gems, distro)
278
    if !distro
279
        puts(<<-EOT.unindent(12))
280
            Distribution not detected. Make sure you manually install the
281
            dependencies described in Building from Source from the OpenNebula
282
            documentation.
283

    
284
            Press enter to continue...
285
        EOT
286
        STDIN.readline
287
    else
288
        puts "Distribution \"#{distro.first}\" detected."
289
        deps=get_dependencies(gems, distro.last[:dependencies])
290

    
291
        if deps.length==0
292
            return
293
        end
294

    
295
        puts "About to install these dependencies:"
296
        puts "* "<<deps.join("\n* ")
297
        puts
298
        puts "Press enter to continue..."
299
        STDIN.readline
300

    
301
        command=distro.last[:install_command]+" "<<deps.join(' ')
302
        puts command
303
        system command
304
    end
305
end
306

    
307
def run_command(cmd)
308
    puts cmd
309
    system cmd
310
    #system "true"
311

    
312
    if $?!=0
313
        puts "Error executing #{cmd}"
314
        exit(-1)
315
    end
316
end
317

    
318
def install_gems(packages)
319
    gems_list=get_gems(packages)
320

    
321
    if gems_list.empty?
322
        puts "Gems already installed"
323
        exit(0)
324
    end
325

    
326
    dist=detect_distro
327
    if !dist
328
        dist=select_distribution
329
    end
330

    
331
    install_dependencies(gems_list, dist)
332

    
333
    packages_string=gems_list.join(' ')
334

    
335
    prefix=""
336

    
337
    if dist && dist.last[:gem_env]
338
        prefix=dist.last[:gem_env].collect do |name, value|
339
            "#{name}=\"#{value}\""
340
        end.join(' ')+' '
341
    end
342

    
343
    command_string = "#{prefix}gem install --no-ri --no-rdoc"
344

    
345
    install_warning(packages)
346

    
347
    simple_gems=gems_list.select {|g| !(g.match(/\s/)) }
348
    if simple_gems and !simple_gems.empty?
349
        cmd=command_string+" " << simple_gems.join(' ')
350
        run_command(cmd)
351
    end
352

    
353
    special_gems=gems_list.select {|g| g.match(/\s/) }
354
    special_gems.each do |gem|
355
        cmd=command_string+" "<<gem
356
        run_command(cmd)
357
    end
358
end
359

    
360
def check_lib(lib)
361
    begin
362
        require lib
363
        true
364
    rescue LoadError, Exception
365
        false
366
    end
367
end
368

    
369
def check_gems(packages)
370
    list=get_gems(packages).compact
371
    gems=list.map {|g| g.strip.split(/\s+/).first }
372

    
373
    not_installed=Array.new
374

    
375
    gems.each do |lib_name|
376
        if !check_lib(lib_name)
377
            not_installed << lib_name
378
        end
379
    end
380

    
381
    if not_installed.empty?
382
        puts "All ruby libraries installed"
383
        exit(0)
384
    else
385
        puts "These ruby libraries are not installed:"
386
        puts ""
387
        puts "* "+not_installed.join("\n* ")
388
        exit(-1)
389
    end
390
end
391

    
392
try_library :rubygems, <<-EOT.unindent
393
    rubygems required to use this tool
394

    
395
    Use one of these methods:
396

    
397
        * Debian/Ubuntu
398
            apt-get install rubygems libopenssl-ruby
399

    
400
        * RHEL/CENTOS
401
            yum install rubygems
402

    
403
        * SUSE
404
            zypper install rubygems
405

    
406
        * Specific rubygems package for your distro
407

    
408
        * Follow the instructions from http://rubygems.org/pages/download
409
EOT
410

    
411
try_library :mkmf, <<-EOT.unindent
412
    ruby development package is needed to install gems
413

    
414
    Use one of these methods:
415

    
416
        * Debian/Ubuntu
417
            apt-get install ruby-dev
418

    
419
        * RHEL/CENTOS
420
            yum install ruby-devel
421

    
422
        * Install the ruby development package for your distro
423
EOT
424

    
425
install_rubygems
426

    
427
command=''
428
params=ARGV
429

    
430
if params.include?('-h')
431
    params-=['-h']
432
    command='help'
433
elsif params.include?('--check')
434
    params-=['--check']
435
    command='check'
436
else
437
    command='install'
438
end
439

    
440
if params.length>0
441
    packages=params
442
else
443
    packages=DEFAULT
444
end
445

    
446

    
447
case command
448
when 'help'
449
    help
450
    exit(0)
451
when 'check'
452
    check_gems(packages)
453
when 'install'
454
    install_gems(packages)
455
end
456

    
457

    
458

    
459