Statistics
| Branch: | Tag: | Revision:

one / src / onedb / onedb @ c03fcc70

History | View | Annotate | Download (16.3 KB)

1
#!/usr/bin/env ruby
2

    
3
# -------------------------------------------------------------------------- #
4
# Copyright 2002-2017, OpenNebula Project, OpenNebula Systems                #
5
#                                                                            #
6
# Licensed under the Apache License, Version 2.0 (the "License"); you may    #
7
# not use this file except in compliance with the License. You may obtain    #
8
# a copy of the License at                                                   #
9
#                                                                            #
10
# http://www.apache.org/licenses/LICENSE-2.0                                 #
11
#                                                                            #
12
# Unless required by applicable law or agreed to in writing, software        #
13
# distributed under the License is distributed on an "AS IS" BASIS,          #
14
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.   #
15
# See the License for the specific language governing permissions and        #
16
# limitations under the License.                                             #
17
#--------------------------------------------------------------------------- #
18

    
19
nk_encoding = nil
20

    
21
if RUBY_VERSION =~ /^1.9/
22
    Encoding.default_external = Encoding::UTF_8
23
    Encoding.default_internal = Encoding::UTF_8
24
    nk_encoding = "UTF-8"
25
end
26

    
27
NOKOGIRI_ENCODING = nk_encoding
28

    
29
ONE_LOCATION = ENV["ONE_LOCATION"]
30

    
31
if !ONE_LOCATION
32
    LIB_LOCATION      = "/usr/lib/one"
33
    RUBY_LIB_LOCATION = LIB_LOCATION + "/ruby"
34
    VAR_LOCATION      = "/var/lib/one"
35
    ETC_LOCATION      = "/etc/one"
36
    LOCK_FILE         = "/var/lock/one/one"
37
else
38
    LIB_LOCATION      = ONE_LOCATION + "/lib"
39
    RUBY_LIB_LOCATION = LIB_LOCATION + "/ruby"
40
    VAR_LOCATION      = ONE_LOCATION + "/var"
41
    ETC_LOCATION      = ONE_LOCATION + "/etc"
42
    LOCK_FILE         = VAR_LOCATION + "/.lock"
43
end
44

    
45
$: << RUBY_LIB_LOCATION
46
$: << RUBY_LIB_LOCATION+'/onedb'
47

    
48
require 'cli/command_parser'
49
require 'optparse/time'
50
require 'onedb'
51
require 'onedb_live'
52
require 'opennebula'
53

    
54
FORCE={
55
    :name => "force",
56
    :short => "-f",
57
    :large => "--force",
58
    :description => "Forces the backup even if the DB exists"
59
}
60

    
61
BACKUP={
62
    :name => "backup",
63
    :short => "-b file",
64
    :large => "--backup file",
65
    :description => "Use this file to store SQL dump",
66
    :format => String
67
}
68

    
69
FEDERATED = {
70
    :name        => "federated",
71
    :large       => "--federated",
72
    :description => "Limit backup/restore to federated tables"
73
}
74

    
75
###############################################################################
76
# SQLite options
77
###############################################################################
78
SQLITE={
79
    :name => "sqlite",
80
    :short => "-s file",
81
    :large => "--sqlite file",
82
    :format => String,
83
    :description => "SQLite DB file",
84
    :proc => lambda { |o, options|
85
        options[:backend] = :sqlite
86
        options[:sqlite]  = o
87
    }
88
}
89

    
90
###############################################################################
91
# MySQL options
92
###############################################################################
93
SERVER={
94
    :name => "server",
95
    :short => "-S host",
96
    :large => "--server host",
97
    :format => String,
98
    :description => "MySQL server hostname or IP. Defaults to localhost",
99
    :proc => lambda { |o, options|
100
        options[:backend] = :mysql
101
        options[:server]  = o
102
    }
103
}
104

    
105
PORT={
106
    :name => "port",
107
    :short => "-P port",
108
    :large => "--port port",
109
    :format => String,
110
    :description => "MySQL server port. Defaults to 3306",
111
    :proc => lambda { |o, options|
112
        options[:backend] = :mysql
113
        options[:port]  = o
114
    }
115
}
116

    
117
USERNAME={
118
    :name => "username",
119
    :short => "-u user",
120
    :large => "--username user",
121
    :format => String,
122
    :description => "MySQL username",
123
    :proc => lambda { |o, options|
124
        options[:backend] = :mysql
125
        options[:user]    = o
126
    }
127
}
128

    
129
PASSWORD={
130
    :name => "password",
131
    :short => "-p pass",
132
    :large => "--password pass",
133
    :format => String,
134
    :description => "MySQL password. Leave unset to be prompted for it",
135
    :proc => lambda { |o, options|
136
        options[:backend] = :mysql
137
        options[:passwd]  = o
138
    }
139
}
140

    
141
DBNAME={
142
    :name => "dbname",
143
    :short => "-d dbname",
144
    :large => "--dbname dbname",
145
    :format => String,
146
    :description => "MySQL DB name for OpenNebula",
147
    :proc => lambda { |o, options|
148
        options[:backend] = :mysql
149
        options[:db_name] = o
150
    }
151
}
152

    
153
###############################################################################
154
# Slave MySQL options
155
###############################################################################
156
SLAVE_SERVER={
157
    :name => "slave-server",
158
    :large => "--slave-server host",
159
    :format => String,
160
    :description => "Slave MySQL server hostname or IP. Defaults to localhost",
161
    :proc => lambda { |o, options|
162
        options[:slave_backend] = :mysql
163
        options[:slave_server]  = o
164
    }
165
}
166

    
167
SLAVE_PORT={
168
    :name => "slave-port",
169
    :large => "--slave-port port",
170
    :format => String,
171
    :description => "Slave MySQL server port. Defaults to 3306",
172
    :proc => lambda { |o, options|
173
        options[:slave_backend] = :mysql
174
        options[:slave_port]  = o
175
    }
176
}
177

    
178
SLAVE_USERNAME={
179
    :name => "slave-username",
180
    :large => "--slave-username user",
181
    :format => String,
182
    :description => "Slave MySQL username",
183
    :proc => lambda { |o, options|
184
        options[:slave_backend] = :mysql
185
        options[:slave_user]    = o
186
    }
187
}
188

    
189
SLAVE_PASSWORD={
190
    :name => "slave-password",
191
    :large => "--slave-password pass",
192
    :format => String,
193
    :description => "Slave MySQL password. Leave unset to be prompted for it",
194
    :proc => lambda { |o, options|
195
        options[:slave_backend] = :mysql
196
        options[:slave_passwd]  = o
197
    }
198
}
199

    
200
SLAVE_DBNAME={
201
    :name => "slave-dbname",
202
    :large => "--slave-dbname dbname",
203
    :format => String,
204
    :description => "Slave MySQL DB name for OpenNebula",
205
    :proc => lambda { |o, options|
206
        options[:slave_backend] = :mysql
207
        options[:slave_db_name] = o
208
    }
209
}
210

    
211
SLAVE_BACKUP={
212
    :name => "slave-backup",
213
    :large => "--slave-backup file",
214
    :description => "Use this file to store SQL dump",
215
    :format => String
216
}
217

    
218
###############################################################################
219
# Extra options
220
###############################################################################
221

    
222
EXTRA={
223
    :name => "extra",
224
    :large => "--extra arg",
225
    :description => "Extra args",
226
    :format => Array
227
}
228

    
229
###############################################################################
230
# Live operation options
231
###############################################################################
232

    
233
START_TIME = {
234
    :name   => "start_time",
235
    :short  => "-s TIME",
236
    :large  => "--start TIME" ,
237
    :description => "First time to process",
238
    :format => Time
239
}
240

    
241
END_TIME = {
242
    :name   => "end_time",
243
    :short  => "-e TIME",
244
    :large  => "--end TIME" ,
245
    :description => "Last time to process",
246
    :format => Time
247
}
248

    
249
ID = {
250
    :name   => "id",
251
    :short  => "-i ID",
252
    :large  => "--id ID" ,
253
    :description => "Filter by ID",
254
    :format => Numeric
255
}
256

    
257
XPATH = {
258
    :name   => "xpath",
259
    :short  => "-x ID",
260
    :large  => "--xpath ID" ,
261
    :description => "Filter by xpath",
262
    :format => String
263
}
264

    
265
EXPR= {
266
    :name   => "expr",
267
    :short  => "-e ID",
268
    :large  => "--expr ID" ,
269
    :description => "Filter by expression (UNAME=oneadmin)",
270
    :format => String
271
}
272

    
273
DRY= {
274
    :name   => "dry",
275
    :large  => "--dry" ,
276
    :description => "Do not write in the database, output xml"
277
}
278

    
279
DELETE= {
280
    :name   => "delete",
281
    :short  => "-d",
282
    :large  => "--delete" ,
283
    :description => "Delete all matched xpaths"
284
}
285

    
286
cmd=CommandParser::CmdParser.new(ARGV) do
287
    description <<-EOT.unindent
288
        This command enables the user to manage the OpenNebula database. It
289
        provides information about the DB version, means to upgrade it to the
290
        latest version, and backup tools.
291
    EOT
292

    
293
    ###########################################################################
294
    # Global options
295
    ###########################################################################
296
    set :option, CommandParser::OPTIONS
297
    set :option, [SQLITE, SERVER, PORT, USERNAME, PASSWORD, DBNAME]
298

    
299
    ###########################################################################
300
    # Backup
301
    ###########################################################################
302
    backup_desc = <<-EOT.unindent
303
        Dumps the DB to a file specified in the argument
304
    EOT
305

    
306
    command :backup, backup_desc, [:output_file, nil],
307
            :options=>[FORCE, FEDERATED] do
308

    
309
        begin
310
            helper = OneDB.new(options)
311
            helper.backup(args[0], options)
312
        rescue Exception => e
313
            [-1, e.message]
314
        end
315
    end
316

    
317
    ###########################################################################
318
    # Version
319
    ###########################################################################
320
    version_desc = <<-EOT.unindent
321
        Prints the current DB version.
322
        Use -v flag to see also OpenNebula version
323
    EOT
324

    
325
    command :version , version_desc do
326
        begin
327
            helper = OneDB.new(options)
328
            helper.version(options)
329
        rescue Exception => e
330
            [-1, e.message]
331
        end
332
    end
333

    
334
    ###########################################################################
335
    # History
336
    ###########################################################################
337
    history_desc = <<-EOT.unindent
338
        Prints the upgrades history
339
    EOT
340

    
341
    command :history , history_desc do
342
        begin
343
            helper = OneDB.new(options)
344
            helper.history
345
        rescue Exception => e
346
            [-1, e.message]
347
        end
348
    end
349

    
350
    ###########################################################################
351
    # Restore
352
    ###########################################################################
353
    restore_desc = <<-EOT.unindent
354
        Restores the DB from a backup file. Only restores backups generated
355
        from the same backend (SQLite or MySQL)
356
    EOT
357

    
358
    command :restore , restore_desc, [:backup_file, nil],
359
            :options=>[FORCE, FEDERATED] do
360

    
361
        begin
362
            helper = OneDB.new(options)
363
            helper.restore(args[0], options)
364
        rescue Exception => e
365
            [-1, e.message]
366
        end
367
    end
368

    
369
    ###########################################################################
370
    # Upgrade
371
    ###########################################################################
372
    upgrade_desc = <<-EOT.unindent
373
        Upgrades the DB to the latest version
374
        where <version> : DB version (e.g. 1, 3) to upgrade.
375
                          By default the DB is upgraded to the latest version
376
    EOT
377

    
378
    command :upgrade , upgrade_desc, [:version, nil], :options=>[FORCE,BACKUP] do
379
        begin
380
            helper = OneDB.new(options)
381
            helper.upgrade(args[0], options)
382
        rescue Exception => e
383
            [-1, e.message]
384
        end
385
    end
386

    
387
    ###########################################################################
388
    # fsck
389
    ###########################################################################
390
    fsck_desc = <<-EOT.unindent
391
        Checks the consistency of the DB, and fixes the problems found
392
    EOT
393

    
394
    command :fsck, fsck_desc, :options=>[FORCE,BACKUP] do
395
        begin
396
            helper = OneDB.new(options)
397
            helper.fsck(options)
398
        rescue Exception => e
399
            [-1, e.message]
400
        end
401
    end
402

    
403
    ###########################################################################
404
    # Import slave
405
    ###########################################################################
406
    import_slave_desc = <<-EOT.unindent
407
        Imports an existing federation slave into the federation master database
408
    EOT
409

    
410
    command :"import-slave", import_slave_desc, :options=>[FORCE,BACKUP,
411
        SLAVE_SERVER,SLAVE_PORT,SLAVE_USERNAME,SLAVE_PASSWORD,
412
        SLAVE_DBNAME,SLAVE_BACKUP] do
413

    
414
        begin
415
            helper = OneDB.new(options)
416
            helper.import_slave(options)
417
        rescue Exception => e
418
            [-1, e.message]
419
        end
420
    end
421

    
422
    ###########################################################################
423
    # Migrate vcenter 54
424
    ###########################################################################
425
    vcenter_one54_desc = <<-EOT.unindent
426
        Migrate VM and templates so they can be used by OpenNebula 5.4
427
    EOT
428

    
429
    command :"vcenter-one54", vcenter_one54_desc, :options=>[FORCE,BACKUP] do
430

    
431
        begin
432
            helper = OneDB.new(options)
433
            helper.vcenter_one54(options)
434
        rescue Exception => e
435
            [-1, e.message]
436
        end
437
    end
438

    
439
    ###########################################################################
440
    # Patch
441
    ###########################################################################
442
    patch_desc = <<-EOT.unindent
443
        Applies a database patch file
444
    EOT
445

    
446
    command :patch , patch_desc, :file, :options=>[BACKUP, EXTRA] do
447
        begin
448
            helper = OneDB.new(options)
449
            helper.patch(args[0], options)
450
        rescue Exception => e
451
            [-1, e.message]
452
        end
453
    end
454

    
455
    ###########################################################################
456
    # Migrate SQLite to MySQL
457
    ###########################################################################
458
    sqlite2mysql_desc = <<-EOT.unindent
459
        Migrates a SQLite OpenNebula Database to MySQL
460
    EOT
461

    
462
    command :sqlite2mysql , sqlite2mysql_desc, :options=>[BACKUP] do
463
        begin
464
            options[:backend] = :sqlite
465
            sqlite = OneDB.new(options)
466

    
467
            options[:backend] = :mysql
468
            mysql = OneDB.new(options)
469

    
470
            mysql.sqlite2mysql(options, sqlite)
471
        rescue Exception => e
472
            [-1, e.message]
473
        end
474
    end
475

    
476
    ###########################################################################
477
    # Purge history
478
    ###########################################################################
479
    purge_history_desc = <<-EOT.unindent
480
        Deletes all but the last history records from non DONE VMs
481
    EOT
482

    
483
    command :'purge-history', purge_history_desc,
484
            :options => [BACKUP, START_TIME, END_TIME] do
485
        begin
486
            action = OneDBLive.new
487
            action.purge_history(options)
488
        rescue Exception => e
489
            pp e.backtrace
490
            [-1, e.message]
491
        end
492

    
493
        0
494
    end
495

    
496
    ###########################################################################
497
    # Purge VMs in DONE state
498
    ###########################################################################
499
    purge_done_desc = <<-EOT.unindent
500
        Deletes all VMs in DONE state
501
    EOT
502

    
503
    command :'purge-done', purge_done_desc,
504
            :options => [BACKUP, START_TIME, END_TIME] do
505
        begin
506
            action = OneDBLive.new
507
            action.purge_done_vm(options)
508
        rescue Exception => e
509
            puts e.name
510
            pp e.backtrace
511
            [-1, e.message]
512
        end
513

    
514
        0 # exit code
515
    end
516

    
517
    ###########################################################################
518
    # Change value in object body
519
    ###########################################################################
520
    change_body_desc = <<-EOT.unindent
521
        Changes a value from the body of an object. The possible objects are:
522
            vm, host, vnet, image, cluster, document, group, marketplace,
523
            marketplaceapp, secgroup, template, vrouter or zone
524

    
525
        You can filter the objects to modify using one of these options:
526

    
527
            * --id: object id, example: 156
528
            * --xpath: xpath expression, example: TEMPLATE[count(NIC)>1]
529
            * --expr: xpath expression, can use operators =, !=, <, >, <= or >=
530
                example: TEMPLATE/NIC/NIC_ID>0
531

    
532
        If you want to change a value use a third parameter. In case you want
533
        to delete it use --delete option.
534
    EOT
535

    
536
    command :'change-body', change_body_desc, :object, :xpath, [:value, nil],
537
            :options => [BACKUP, ID, XPATH, EXPR, DRY, DELETE] do
538
        begin
539
            action = OneDBLive.new
540
            action.change_body(args[0], args[1], args[2], options)
541
        rescue Exception => e
542
            puts e.message
543
            pp e.backtrace
544
            [-1, e.message]
545
        end
546

    
547
        0 # exit code
548
    end
549
end