Statistics
| Branch: | Tag: | Revision:

one / share / install_gems / install_gems @ bc0a3a04

History | View | Annotate | Download (11 KB)

1
#!/usr/bin/env ruby
2

    
3
require 'pp'
4

    
5
DEFAULT_PRE=%w{sunstone quota cloud auth_ldap vmware oneflow ec2_hybrid oca onedb}
6

    
7
if defined?(RUBY_VERSION) && RUBY_VERSION>="1.8.7"
8
    SQLITE='sqlite3'
9
else
10
    SQLITE='sqlite3-ruby --version 1.2.0'
11
end
12

    
13
if !defined?(RUBY_VERSION) || RUBY_VERSION < '1.9.0'
14
    $nokogiri='nokogiri --version "< 1.6.0"'
15
    LDAP='net-ldap --version "< 0.9"'
16
    ZENDESK_API='zendesk_api --version "< 1.5"'
17
else
18
    $nokogiri='nokogiri'
19
    DEFAULT = DEFAULT_PRE + %w{hybrid}
20
    LDAP='net-ldap'
21
    ZENDESK_API='zendesk_api'
22
end
23

    
24
TREETOP = 'treetop --version ">= 1.6.3"'
25
DEFAULT = DEFAULT_PRE if !defined?(DEFAULT)
26

    
27
GROUPS={
28
    :quota      => [SQLITE, 'sequel'],
29
    :sunstone   => ['json', 'rack', 'sinatra', 'thin', 'memcache-client',
30
                     ZENDESK_API, SQLITE],
31
    :cloud      => %w{amazon-ec2 rack sinatra thin uuidtools curb json},
32
    :hybrid     => %w{softlayer_api configparser azure},
33
    :auth_ldap  => LDAP,
34
    :vmware     => %w{builder trollop},
35
    :oneflow    => ['sinatra', 'json', TREETOP, 'parse-cron'],
36
    :ec2_hybrid => 'aws-sdk --version "= 1.33"',
37
    :oca        => 'ox',
38
    :onedb      => "mysql"
39
}
40

    
41
PACKAGES=GROUPS.keys
42

    
43
GEM_TEST={
44
    LDAP => 'net/ldap',
45
    ZENDESK_API => 'zendesk_api'
46
}
47

    
48
DISTRIBUTIONS={
49
    :debian => {
50
        :id => ['Ubuntu', 'Debian'],
51
        :dependencies_common => ['ruby-dev', 'make'],
52
        :dependencies => {
53
            SQLITE      => ['gcc', 'libsqlite3-dev'],
54
            'mysql'     => ['gcc', 'libmysqlclient-dev'],
55
            'curb'      => ['gcc', 'libcurl4-openssl-dev'],
56
            $nokogiri   => %w{gcc rake libxml2-dev libxslt1-dev},
57
            'xmlparser' => ['gcc', 'libexpat1-dev'],
58
            'thin'      => ['g++'],
59
            'json'      => ['gcc']
60
        },
61
        :install_command => 'apt-get install',
62
        :gem_env    => {
63
            'rake'      => '/usr/bin/rake'
64
        }
65
    },
66
    :redhat => {
67
        :id => ['CentOS', /^RedHat/, /^Scientific/],
68
        :dependencies_common => ['ruby-devel', 'make'],
69
        :dependencies => {
70
            SQLITE      => ['gcc', 'sqlite-devel'],
71
            'mysql'     => ['gcc', 'mysql-devel'],
72
            'curb'      => ['gcc', 'curl-devel'],
73
            $nokogiri   => %w{gcc rubygem-rake libxml2-devel libxslt-devel},
74
            'xmlparser' => ['gcc', 'expat-devel'],
75
            'thin'      => ['gcc-c++'],
76
            'json'      => ['gcc']
77
        },
78
        :install_command => 'yum install'
79
    }
80
}
81

    
82

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

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

    
95
def select_distribution
96
    items=[]
97
    counter=0
98

    
99
    puts(<<-EOT.unindent(8))
100
        Select your distribution or press enter to continue without
101
        installing dependencies.
102

    
103
EOT
104

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

    
115
        items << name
116

    
117
        puts text
118
    end
119

    
120
    puts
121

    
122
    options=(0..items.length).to_a.map {|k| k.to_s }
123

    
124
    option=STDIN.readline[0,1]
125

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

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

    
142
            Press ENTER to continue...
143

    
144
EOT
145

    
146
        STDIN.readline
147

    
148
        `gem install rubygems-update --version '= 1.3.6'`
149

    
150
        if $?.exitstatus!=0
151
            puts "Error updating rubygems"
152
            exit(-1)
153
        end
154

    
155
        update_rubygems_path=[
156
            '/usr/bin/update_rubygems',
157
            '/var/lib/gems/1.8/bin/update_rubygems',
158
            '/var/lib/gems/1.9/bin/update_rubygems'
159
        ]
160

    
161
        installed=false
162

    
163
        update_rubygems_path.each do |path|
164
            if File.exist?(path)
165
                `#{path}`
166

    
167
                if $?.exitstatus!=0
168
                    puts "Error executing update_rubygems"
169
                    exit(-1)
170
                end
171

    
172
                installed=true
173
                break
174
             end
175
        end
176

    
177
        if !installed
178
            puts "Could not find update_rubygems executable"
179
            exit(-1)
180
        end
181
    end
182
end
183

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

    
193
def try_library(name, error_message)
194
    if GEM_TEST[name.to_s]
195
        lib_test=GEM_TEST[name.to_s]
196
    else
197
        lib_test=name.to_s
198
    end
199

    
200
    begin
201
        require lib_test
202
    rescue LoadError, Exception
203
        STDERR.puts error_message
204
        exit(-1)
205
    end
206
end
207

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

    
218
def help
219
    puts "Specify the package dependencies from this list:"
220
    puts "* "<<PACKAGES.join("\n* ")
221
    puts
222
    puts "If no parameters are specified then this list will be used:"
223
    puts DEFAULT.join(' ')
224
    puts
225
    puts "Use --check parameter to search for non installed libraries."
226
    puts "Use --no-nokogiri parameter if you don't want to install"
227
    puts "nokogiri gem."
228
    puts "Use --showallpackages to show the list of packages required"
229
    puts "to compile the gems."
230
    puts "Use --showallgems to show the complete list of required gems."
231
end
232

    
233
def which_gems(packages)
234
    ([$nokogiri]+packages.map do |package|
235
        GROUPS[package.to_sym]
236
    end).flatten.uniq
237
end
238

    
239
def get_gems(packages)
240
    ([$nokogiri]+packages.map do |package|
241
	GROUPS[package.to_sym]
242
    end).flatten.uniq-installed_gems
243
end
244

    
245

    
246
def detect_distro
247
    begin
248
        lsb_info=`lsb_release -a`
249
    rescue
250
    end
251

    
252
    if $?.exitstatus!=0
253
        STDERR.puts(<<-EOT.unindent(12))
254
            lsb_release command not found. If you are using a RedHat based
255
            distribution install redhat-lsb
256

    
257
EOT
258
        return nil
259
    end
260

    
261
    distribution_id=nil
262

    
263
    lsb_info.scan(/^Distributor ID:\s*(.*?)$/) do |m|
264
        distribution_id=m.first.strip
265
    end
266

    
267
    return nil if !distribution_id
268

    
269
    distro=nil
270

    
271
    DISTRIBUTIONS.find do |dist, info|
272
        info[:id].find do |dist_id|
273
            dist_id===distribution_id
274
        end
275
    end
276
end
277

    
278
def get_dependencies(gems, dependencies)
279
    deps=[]
280

    
281
    gems.each do |gem_name|
282
        deps<<dependencies[gem_name]
283
    end
284

    
285
    deps.flatten!
286
    deps.compact!
287
    deps.uniq!
288

    
289
    deps
290
end
291

    
292
def install_dependencies(gems, distro)
293
    if !distro
294
        puts(<<-EOT.unindent(12))
295
            Distribution not detected. Make sure you manually install the
296
            dependencies described in Building from Source from the OpenNebula
297
            documentation.
298

    
299
            Press enter to continue...
300
        EOT
301
        STDIN.readline
302
    else
303
        puts "Distribution \"#{distro.first}\" detected."
304
        deps=get_dependencies(gems, distro.last[:dependencies])
305
        deps+=distro.last[:dependencies_common]
306

    
307
        if deps.length==0
308
            return
309
        end
310

    
311
        puts "About to install these dependencies:"
312
        puts "* "<<deps.join("\n* ")
313
        puts
314
        puts "Press enter to continue..."
315
        STDIN.readline
316

    
317
        command=distro.last[:install_command]+" "<<deps.join(' ')
318
        puts command
319
        system command
320
    end
321
end
322

    
323
def run_command(cmd)
324
    puts cmd
325
    system cmd
326
    #system "true"
327

    
328
    if $?!=0
329
        puts "Error executing #{cmd}"
330
        exit(-1)
331
    end
332
end
333

    
334
def install_gems(packages)
335
    gems_list=get_gems(packages)
336

    
337
    if gems_list.empty?
338
        puts "Gems already installed"
339
        exit(0)
340
    end
341

    
342
    dist=detect_distro
343
    if !dist
344
        dist=select_distribution
345
    end
346

    
347
    install_dependencies(gems_list, dist)
348

    
349
    packages_string=gems_list.join(' ')
350

    
351
    prefix=""
352

    
353
    if dist && dist.last[:gem_env]
354
        prefix=dist.last[:gem_env].collect do |name, value|
355
            "#{name}=\"#{value}\""
356
        end.join(' ')+' '
357
    end
358

    
359
    command_string = "#{prefix}gem install --no-ri --no-rdoc"
360

    
361
    install_warning(packages)
362

    
363
    special_gems=gems_list.select {|g| g.match(/\s/) }
364
    special_gems.each do |gem|
365
        cmd=command_string+" "<<gem
366
        run_command(cmd)
367
    end
368

    
369
    simple_gems=gems_list.select {|g| !(g.match(/\s/)) }
370
    if simple_gems and !simple_gems.empty?
371
        cmd=command_string+" " << simple_gems.join(' ')
372
        run_command(cmd)
373
    end
374
end
375

    
376
def check_lib(lib)
377
    begin
378
        require lib
379
        true
380
    rescue LoadError, Exception
381
        false
382
    end
383
end
384

    
385
def show_allgems(packages)
386
    all=which_gems(packages)
387
    puts all.join("\n")
388
end
389

    
390
def show_allpackages(packages)
391
    gems=which_gems(packages)
392
    distro=detect_distro
393

    
394
    if !distro
395
        distro=select_distribution
396
    end
397

    
398
    deps=get_dependencies(gems, distro.last[:dependencies])
399
    deps+=distro.last[:dependencies_common]
400

    
401
    if deps.length==0
402
        return
403
    end
404
    puts deps.join("\n")
405
end
406

    
407
def check_gems(packages)
408
    list=get_gems(packages).compact
409
    gems=list.map {|g| g.strip.split(/\s+/).first }
410

    
411
    not_installed=Array.new
412

    
413
    gems.each do |lib_name|
414
        if !check_lib(lib_name)
415
            not_installed << lib_name
416
        end
417
    end
418

    
419
    if not_installed.empty?
420
        puts "All ruby libraries installed"
421
        exit(0)
422
    else
423
        puts "These ruby libraries are not installed:"
424
        puts ""
425
        puts "* "+not_installed.join("\n* ")
426
        exit(-1)
427
    end
428
end
429

    
430
try_library :rubygems, <<-EOT.unindent
431
    rubygems required to use this tool
432

    
433
    Use one of these methods:
434

    
435
        * Debian/Ubuntu
436
            apt-get install rubygems libopenssl-ruby
437

    
438
        * RHEL/CENTOS
439
            yum install rubygems
440

    
441
        * Specific rubygems package for your distro
442

    
443
        * Follow the instructions from http://rubygems.org/pages/download
444
EOT
445

    
446
try_library :openssl, <<-EOT.unindent
447
    ruby openssl libraries are needed. They usually come as companion
448
    package to ruby.
449
EOT
450

    
451
install_rubygems
452

    
453
command=''
454
params=ARGV
455

    
456
if params.include?('--no-nokogiri')
457
    params-=['--no-nokogiri']
458
    $nokogiri=nil
459
end
460

    
461
if params.include?('-h')
462
    params-=['-h']
463
    command='help'
464
elsif params.include?('--check')
465
    params-=['--check']
466
    command='check'
467
elsif params.include?('--showallgems')
468
    params-=['--showallgems']
469
    command='showallgems'
470
elsif params.include?('--showallpackages')
471
    params-=['--showallpackages']
472
    command='showallpackages'
473
else
474
    command='install'
475
end
476

    
477
if params.length>0
478
    packages=params
479
else
480
    packages=DEFAULT
481
end
482

    
483

    
484
case command
485
when 'help'
486
    help
487
    exit(0)
488
when 'check'
489
    check_gems(packages)
490
when 'showallgems'
491
    show_allgems(packages)
492
when 'showallpackages'
493
    show_allpackages(packages)
494
when 'install'
495
    install_gems(packages)
496
end
497

    
498

    
499

    
500