continuent-tools-core 0.6.0 → 0.7.0
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/bin/tungsten_create_load +0 -0
- data/lib/tungsten.rb +1 -0
- data/lib/tungsten/datasource.rb +73 -0
- data/lib/tungsten/datasources/mysql.rb +170 -0
- data/lib/tungsten/install.rb +46 -3
- data/lib/tungsten/script.rb +8 -6
- metadata +4 -2
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA1:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 74053e6e0e912c97fddd639ce0cfbb22867afbb0
|
4
|
+
data.tar.gz: 4539d7e8893ab90a1f914694cba029b25569b315
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: e116cf8026fc58de55e80100a712bd5f86a410732dae9b7d8dd8cbb554b9642ac32a86411d4440f161b3a9e8f6fdd323f7b734a42cc89fc281b2febd0f61a937
|
7
|
+
data.tar.gz: 0a91e46815ed643e64c7c3523d7d62962d9e60a80300d5d4b0b5e33fb5557a0a468c1fe1e9f3aa14a09d1089f6d409f37acb8260d94dd3e3f1bd21e2288d277b
|
data/bin/tungsten_create_load
CHANGED
File without changes
|
data/lib/tungsten.rb
CHANGED
@@ -0,0 +1,73 @@
|
|
1
|
+
class TungstenScriptDatasource
|
2
|
+
def initialize(ti, service, is_direct = false)
|
3
|
+
@ti = ti
|
4
|
+
@service = service
|
5
|
+
@is_direct = is_direct
|
6
|
+
end
|
7
|
+
|
8
|
+
def can_manage_service?
|
9
|
+
false
|
10
|
+
end
|
11
|
+
|
12
|
+
def is_running?
|
13
|
+
raise "Undefined function: #{self.class.name()}.is_running?"
|
14
|
+
end
|
15
|
+
|
16
|
+
def stop
|
17
|
+
if @is_direct == true
|
18
|
+
raise "Unable to stop the direct datasource for #{@service} replication service"
|
19
|
+
end
|
20
|
+
|
21
|
+
unless can_manage_service?()
|
22
|
+
raise "Unable to stop the datasource for #{@service} replication service"
|
23
|
+
end
|
24
|
+
|
25
|
+
if is_running?() == false
|
26
|
+
return
|
27
|
+
end
|
28
|
+
|
29
|
+
TU.notice("Stop the #{self.class.name()} service")
|
30
|
+
_stop_server()
|
31
|
+
end
|
32
|
+
|
33
|
+
def _stop_server
|
34
|
+
raise "Undefined function: #{self.class.name()}._stop_server"
|
35
|
+
end
|
36
|
+
|
37
|
+
def start
|
38
|
+
if @is_direct == true
|
39
|
+
raise "Unable to start the direct datasource for #{@service} replication service"
|
40
|
+
end
|
41
|
+
|
42
|
+
unless can_manage_service?()
|
43
|
+
raise "Unable to start the datasource for #{@service} replication service"
|
44
|
+
end
|
45
|
+
|
46
|
+
if is_running?() == true
|
47
|
+
return
|
48
|
+
end
|
49
|
+
|
50
|
+
TU.notice("Start the #{self.class.name()} service")
|
51
|
+
_start_server()
|
52
|
+
end
|
53
|
+
|
54
|
+
def _stop_server
|
55
|
+
raise "Undefined function: #{self.class.name()}._start_server"
|
56
|
+
end
|
57
|
+
|
58
|
+
def snapshot_paths
|
59
|
+
raise "Undefined function: #{self.class.name()}.snapshot_paths"
|
60
|
+
end
|
61
|
+
|
62
|
+
def can_sql?
|
63
|
+
@ti.can_sql?(@service, @is_direct)
|
64
|
+
end
|
65
|
+
|
66
|
+
def sql_results(sql)
|
67
|
+
@ti.sql_results(@service, sql, @is_direct)
|
68
|
+
end
|
69
|
+
|
70
|
+
def sql_result(sql)
|
71
|
+
@ti.sql_result(@service, sql, @is_direct)
|
72
|
+
end
|
73
|
+
end
|
@@ -0,0 +1,170 @@
|
|
1
|
+
class TungstenScriptMySQLDatasource < TungstenScriptDatasource
|
2
|
+
def is_running?
|
3
|
+
begin
|
4
|
+
sql_result("SELECT 1")
|
5
|
+
return true
|
6
|
+
rescue
|
7
|
+
return false
|
8
|
+
end
|
9
|
+
end
|
10
|
+
|
11
|
+
def _stop_server
|
12
|
+
begin
|
13
|
+
pid_file = get_variable("pid_file")
|
14
|
+
pid = TU.cmd_result("#{@ti.sudo_prefix()}cat #{pid_file}")
|
15
|
+
rescue CommandError
|
16
|
+
pid = ""
|
17
|
+
end
|
18
|
+
|
19
|
+
begin
|
20
|
+
TU.cmd_result("#{@ti.sudo_prefix()}#{get_service_command()} stop")
|
21
|
+
rescue CommandError
|
22
|
+
end
|
23
|
+
|
24
|
+
# Raise an error if we got a response to the previous command
|
25
|
+
if is_running?() == true
|
26
|
+
raise "Unable to properly shutdown the MySQL service"
|
27
|
+
end
|
28
|
+
|
29
|
+
# We saw issues where MySQL would not close completely. This will
|
30
|
+
# watch the PID and make sure it does not appear
|
31
|
+
unless pid.to_s() == ""
|
32
|
+
begin
|
33
|
+
TU.debug("Verify that the MySQL pid has gone away")
|
34
|
+
Timeout.timeout(30) {
|
35
|
+
pid_missing = false
|
36
|
+
|
37
|
+
while pid_missing == false do
|
38
|
+
begin
|
39
|
+
TU.cmd_result("#{@ti.sudo_prefix()}ps -p #{pid}")
|
40
|
+
sleep 5
|
41
|
+
rescue CommandError
|
42
|
+
pid_missing = true
|
43
|
+
end
|
44
|
+
end
|
45
|
+
}
|
46
|
+
rescue Timeout::Error
|
47
|
+
raise "Unable to verify that MySQL has fully shutdown"
|
48
|
+
end
|
49
|
+
end
|
50
|
+
end
|
51
|
+
|
52
|
+
def _start_server
|
53
|
+
begin
|
54
|
+
TU.cmd_result("#{@ti.sudo_prefix()}#{get_service_command()} start")
|
55
|
+
rescue CommandError
|
56
|
+
end
|
57
|
+
|
58
|
+
# Wait 30 seconds for the MySQL service to be responsive
|
59
|
+
begin
|
60
|
+
Timeout.timeout(30) {
|
61
|
+
while true
|
62
|
+
if is_running?()
|
63
|
+
break
|
64
|
+
else
|
65
|
+
# Pause for a second before running again
|
66
|
+
sleep 1
|
67
|
+
end
|
68
|
+
end
|
69
|
+
}
|
70
|
+
rescue Timeout::Error
|
71
|
+
raise "The MySQL server has taken too long to start"
|
72
|
+
end
|
73
|
+
end
|
74
|
+
|
75
|
+
# Read the configured value for a mysql variable
|
76
|
+
def get_option(opt)
|
77
|
+
begin
|
78
|
+
cnf = @ti.setting(@ti.setting_key(REPL_SERVICES, @service, "repl_datasource_mysql_service_conf"))
|
79
|
+
val = TU.cmd_result("my_print_defaults --config-file=#{cnf} mysqld | grep -e'^--#{opt.gsub(/[\-\_]/, "[-_]")}='")
|
80
|
+
rescue CommandError => ce
|
81
|
+
return nil
|
82
|
+
end
|
83
|
+
|
84
|
+
return val.split("\n")[0].split("=")[1]
|
85
|
+
end
|
86
|
+
|
87
|
+
# Read the current value for a mysql variable
|
88
|
+
def get_variable(var)
|
89
|
+
begin
|
90
|
+
sql_result("SHOW VARIABLES LIKE '#{var}'")[0]["Value"]
|
91
|
+
rescue => e
|
92
|
+
TU.debug(e)
|
93
|
+
return nil
|
94
|
+
end
|
95
|
+
end
|
96
|
+
|
97
|
+
def get_service_command
|
98
|
+
if @mysql_service_command == nil
|
99
|
+
if @mysql_service_command == nil
|
100
|
+
@mysql_service_command = @ti.setting(TI.setting_key(REPL_SERVICES, @service, "repl_datasource_boot_script"))
|
101
|
+
end
|
102
|
+
if @mysql_service_command == nil
|
103
|
+
begin
|
104
|
+
service_command=TU.cmd_result("which service")
|
105
|
+
if TU.cmd("#{@ti.sudo_prefix()}test -x #{service_command}")
|
106
|
+
if TU.cmd("#{@ti.sudo_prefix()}test -x /etc/init.d/mysqld")
|
107
|
+
@mysql_service_command = "#{service_command} mysqld"
|
108
|
+
elsif TU.cmd("#{@ti.sudo_prefix()}test -x /etc/init.d/mysql")
|
109
|
+
@mysql_service_command = "#{service_command} mysql"
|
110
|
+
else
|
111
|
+
TU.error "Unable to determine the service command to start/stop mysql"
|
112
|
+
end
|
113
|
+
else
|
114
|
+
if TU.cmd("#{@ti.sudo_prefix()}test -x /etc/init.d/mysqld")
|
115
|
+
@mysql_service_command = "/etc/init.d/mysqld"
|
116
|
+
elsif TU.cmd("#{@ti.sudo_prefix()}test -x /etc/init.d/mysql")
|
117
|
+
@mysql_service_command = "/etc/init.d/mysql"
|
118
|
+
else
|
119
|
+
TU.error "Unable to determine the service command to start/stop mysql"
|
120
|
+
end
|
121
|
+
end
|
122
|
+
rescue CommandError
|
123
|
+
TU.error "Unable to determine the service command to start/stop mysql"
|
124
|
+
end
|
125
|
+
end
|
126
|
+
end
|
127
|
+
|
128
|
+
@mysql_service_command
|
129
|
+
end
|
130
|
+
|
131
|
+
def get_system_user
|
132
|
+
if @mysql_user == nil
|
133
|
+
@mysql_user = get_option("user")
|
134
|
+
if @mysql_user.to_s() == ""
|
135
|
+
@mysql_user = "mysql"
|
136
|
+
end
|
137
|
+
end
|
138
|
+
|
139
|
+
@mysql_user
|
140
|
+
end
|
141
|
+
|
142
|
+
def snapshot_paths
|
143
|
+
paths = []
|
144
|
+
|
145
|
+
# The datadir may not exist in my.cnf but we need the value
|
146
|
+
# If we don't see it in my.cnf get the value from the dbms
|
147
|
+
val = get_option("datadir")
|
148
|
+
if val == nil
|
149
|
+
val = get_variable("datadir")
|
150
|
+
end
|
151
|
+
paths << val
|
152
|
+
|
153
|
+
# These values must appear in my.cnf if they are to be used
|
154
|
+
val = get_option("innodb_data_home_dir")
|
155
|
+
if val != nil
|
156
|
+
paths << val
|
157
|
+
end
|
158
|
+
val = get_option("innodb_log_group_home_dir")
|
159
|
+
if val != nil
|
160
|
+
paths << val
|
161
|
+
end
|
162
|
+
|
163
|
+
# Only return a unique set of paths
|
164
|
+
paths.uniq()
|
165
|
+
end
|
166
|
+
|
167
|
+
def can_manage_service?
|
168
|
+
true
|
169
|
+
end
|
170
|
+
end
|
data/lib/tungsten/install.rb
CHANGED
@@ -236,7 +236,26 @@ class TungstenInstall
|
|
236
236
|
def trepctl_value(service, key)
|
237
237
|
TU.cmd_result("#{trepctl(service)} status | grep #{key} | awk -F: '{ st = index($0,\":\");print substr($0,st+1)}' | tr -d ' '")
|
238
238
|
end
|
239
|
-
|
239
|
+
|
240
|
+
def trepctl_name_value(service, name_value, stage, key)
|
241
|
+
begin
|
242
|
+
output=JSON.parse(TU.cmd_result("#{trepctl(service)} status -name #{name_value} -json"))
|
243
|
+
rescue Exception => e
|
244
|
+
output=nil
|
245
|
+
end
|
246
|
+
stage_values=output.find{|x| x['stage']=stage}
|
247
|
+
stage_values[key]
|
248
|
+
end
|
249
|
+
|
250
|
+
def trepctl_name_all(service, name_value)
|
251
|
+
begin
|
252
|
+
output=JSON.parse(TU.cmd_result("#{trepctl(service)} status -name #{name_value} -json"))
|
253
|
+
rescue Exception => e
|
254
|
+
output=nil
|
255
|
+
end
|
256
|
+
output
|
257
|
+
end
|
258
|
+
|
240
259
|
def trepctl_property(service, key)
|
241
260
|
properties = JSON.parse(TU.cmd_result("#{trepctl(service)} properties -filter #{key}"))
|
242
261
|
if properties.has_key?(key)
|
@@ -246,8 +265,12 @@ class TungstenInstall
|
|
246
265
|
end
|
247
266
|
end
|
248
267
|
|
249
|
-
def thl(service)
|
250
|
-
|
268
|
+
def thl(service = nil)
|
269
|
+
if service == nil
|
270
|
+
"#{tungsten_sudo_prefix()}#{@root}/#{CURRENT_RELEASE_DIRECTORY}/tungsten-replicator/bin/thl"
|
271
|
+
else
|
272
|
+
"#{tungsten_sudo_prefix()}#{@root}/#{CURRENT_RELEASE_DIRECTORY}/tungsten-replicator/bin/thl -service #{service}"
|
273
|
+
end
|
251
274
|
end
|
252
275
|
|
253
276
|
def service_path(component)
|
@@ -312,6 +335,14 @@ class TungstenInstall
|
|
312
335
|
end
|
313
336
|
end
|
314
337
|
|
338
|
+
def sudo_prefix
|
339
|
+
if ENV['USER'] == "root" || setting("root_command_prefix") != "true"
|
340
|
+
return ""
|
341
|
+
else
|
342
|
+
return "sudo -n "
|
343
|
+
end
|
344
|
+
end
|
345
|
+
|
315
346
|
def datasource_type(service, use_direct_extractor = false)
|
316
347
|
if use_direct_extractor == true
|
317
348
|
key = "repl_direct_datasource_type"
|
@@ -322,6 +353,18 @@ class TungstenInstall
|
|
322
353
|
setting(setting_key(REPL_SERVICES, service, key))
|
323
354
|
end
|
324
355
|
|
356
|
+
def datasource(service, use_direct_extractor = false)
|
357
|
+
type = datasource_type(service, use_direct_extractor)
|
358
|
+
|
359
|
+
case type
|
360
|
+
when "mysql"
|
361
|
+
require "#{File.dirname(__FILE__)}/datasources/mysql.rb"
|
362
|
+
return TungstenScriptMySQLDatasource.new(self, service, use_direct_extractor)
|
363
|
+
else
|
364
|
+
raise "Unable to create a TungstenDatasource for #{service} because it uses #{type}"
|
365
|
+
end
|
366
|
+
end
|
367
|
+
|
325
368
|
def can_sql?(service, use_direct_extractor = false)
|
326
369
|
case datasource_type(service, use_direct_extractor)
|
327
370
|
when "mysql"
|
data/lib/tungsten/script.rb
CHANGED
@@ -212,6 +212,11 @@ module TungstenScript
|
|
212
212
|
end
|
213
213
|
|
214
214
|
def load_ini_files
|
215
|
+
# If there is no script name then we cannot load INI files
|
216
|
+
if script_name().to_s() == ""
|
217
|
+
return
|
218
|
+
end
|
219
|
+
|
215
220
|
# Calculate the INI section name to use
|
216
221
|
section_names = [script_name()]
|
217
222
|
matches = script_name().to_s().match("tungsten_(.*)")
|
@@ -219,7 +224,8 @@ module TungstenScript
|
|
219
224
|
script_ini_file = "#{matches[1]}.ini"
|
220
225
|
section_names << matches[1]
|
221
226
|
else
|
222
|
-
script_ini_file =
|
227
|
+
script_ini_file = File.basename(script_name(), File.extname(script_name())) + ".ini"
|
228
|
+
section_names << File.basename(script_name(), File.extname(script_name()))
|
223
229
|
end
|
224
230
|
|
225
231
|
load_ini_parameters("/etc/tungsten/scripts.ini",
|
@@ -529,11 +535,7 @@ module TungstenScript
|
|
529
535
|
end
|
530
536
|
|
531
537
|
def sudo_prefix
|
532
|
-
|
533
|
-
return ""
|
534
|
-
else
|
535
|
-
return "sudo -n "
|
536
|
-
end
|
538
|
+
TI.sudo_prefix()
|
537
539
|
end
|
538
540
|
end
|
539
541
|
|
metadata
CHANGED
@@ -1,14 +1,14 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: continuent-tools-core
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.
|
4
|
+
version: 0.7.0
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Continuent
|
8
8
|
autorequire:
|
9
9
|
bindir: bin
|
10
10
|
cert_chain: []
|
11
|
-
date: 2014-
|
11
|
+
date: 2014-12-01 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: json_pure
|
@@ -126,6 +126,8 @@ files:
|
|
126
126
|
- lib/iniparse.rb
|
127
127
|
- lib/tungsten/api.rb
|
128
128
|
- lib/tungsten/common.rb
|
129
|
+
- lib/tungsten/datasource.rb
|
130
|
+
- lib/tungsten/datasources/mysql.rb
|
129
131
|
- lib/tungsten/exec.rb
|
130
132
|
- lib/tungsten/iniparse.rb
|
131
133
|
- lib/tungsten/install.rb
|