continuent-tools-core 0.6.0 → 0.7.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.
- 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
|