continuent-tools-core 0.8.0 → 0.9.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 CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA1:
3
- metadata.gz: aee78c998a93c367e0607691f4714d4fb6e0116b
4
- data.tar.gz: ce61842a26720937f41fb0e1e3938c7bbe5ac9af
3
+ metadata.gz: e7f7d7c19ce143f710bec3d7b7c0548c76e2cc4b
4
+ data.tar.gz: c8fc19d558b5e084195527b21737623a8d56dc3d
5
5
  SHA512:
6
- metadata.gz: f6dcf8857a4403ac9cd96d8a8ef6b6a2d27750b92026c3043f02af9d61522dbf5eedcabbcecc103efdc1c5d271e1f6c828785222746e999325204f3e8f84931c
7
- data.tar.gz: c741cdf86e994a172cd3219b6187ec7e0b5d4e010b5f2b45e3418ca24541b910fece157a73c121e0a4c314c2f7bb88fe17a0511b1a60b7d276b254b534dae67f
6
+ metadata.gz: 28857957400e927922005705c025814245cf72d3a8118ba0afedd4ab136c150701baba607aea3b3e245876dd82ffc68b6823f0be43b359d685d80e86c3ed7e71
7
+ data.tar.gz: daa48a69f3a8c21c627add56e9ecd9a187386c45031bef2d8582b9e855fc6b0b0620f94ac678df4f2dbb467f9c0bd4f01c2282fda386559f4e6d740d1e8830bd
@@ -0,0 +1,127 @@
1
+ #!/usr/bin/env ruby
2
+ # Copyright (C) 2015 VMware, Inc.
3
+ #
4
+ # Licensed under the Apache License, Version 2.0 (the "License"); you may
5
+ # not use this file except in compliance with the License. You may obtain
6
+ # a copy of the License at
7
+ #
8
+ # http://www.apache.org/licenses/LICENSE-2.0
9
+ #
10
+ # Unless required by applicable law or agreed to in writing, software
11
+ # distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
12
+ # WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
13
+ # License for the specific language governing permissions and limitations
14
+ # under the License.
15
+ #
16
+ # Initial developer(s): Jeff Mace
17
+ # Contributor(s):
18
+
19
+ begin
20
+ require 'rubygems'
21
+ gem 'continuent-tools-core'
22
+ rescue LoadError
23
+ end
24
+
25
+ require 'continuent-tools-core'
26
+
27
+ class TungstenParseTHLIndex
28
+ include TungstenScript
29
+ include SingleServiceScript
30
+ private
31
+
32
+ def main
33
+ case command()
34
+ when "count"
35
+ output_thl_index_count()
36
+ when "find"
37
+ find_thl_record()
38
+ end
39
+ end
40
+
41
+ def output_thl_index_count
42
+ each_thl_index_line() {
43
+ |line|
44
+ match = parse_thl_index_line(line)
45
+ if match != nil
46
+ records = match[:end] - match[:start].to_i() + 1;
47
+ TU.output("#{match[:file]} - #{records}")
48
+ end
49
+ }
50
+ end
51
+
52
+ def find_thl_record
53
+ each_thl_index_line() {
54
+ |line|
55
+ match = parse_thl_index_line(line)
56
+ if match != nil
57
+ if match[:start] <= opt(:seqno) && match[:end] >= opt(:seqno)
58
+ TU.output(match[:file])
59
+ end
60
+ end
61
+ }
62
+ end
63
+
64
+ def parse_thl_index_line(line)
65
+ match = line.strip().match(/^LogIndexEntry (thl\.data\.[0-9]+)\(([0-9]+):([0-9]+)\)$/)
66
+
67
+ if match == nil
68
+ return nil
69
+ end
70
+
71
+ return {
72
+ :file => match[1],
73
+ :start => match[2].to_i(),
74
+ :end => match[3].to_i()
75
+ }
76
+ end
77
+
78
+ def each_thl_index_line(&block)
79
+ TU.cmd_stdout("cat /Users/jmace/Downloads/thl.txt") {
80
+ |line|
81
+ block.call(line.strip())
82
+ }
83
+ end
84
+
85
+ def get_thl_index
86
+ return TU.cmd_result("cat /Users/jmace/Downloads/thl.txt").split("\n")
87
+ end
88
+
89
+ def configure
90
+ super()
91
+
92
+ add_command(:count, {
93
+ :help => "Create the stack",
94
+ :default => true
95
+ })
96
+
97
+ add_command(:find, {
98
+ :help => "Find the THL file containing --seqno"
99
+ })
100
+
101
+ add_option(:seqno, {
102
+ :on => "--seqno String",
103
+ :parse => method(:parse_integer_option),
104
+ })
105
+ end
106
+
107
+ def validate
108
+ super()
109
+
110
+ unless TU.is_valid?()
111
+ return TU.is_valid?()
112
+ end
113
+
114
+ case command()
115
+ when "find"
116
+ if opt(:seqno) == nil
117
+ TU.error("The --seqno option is required for the find command")
118
+ end
119
+ end
120
+ end
121
+
122
+ def script_name
123
+ "tungsten_analyze_thl_index"
124
+ end
125
+
126
+ self.new().run()
127
+ end
@@ -43,6 +43,12 @@ class TungstenUtil
43
43
  # automatically forward messages to the console and add any TungstenScript
44
44
  # options to the command.
45
45
  def tungsten_ssh_result(command, host, user)
46
+ # Run the command outside of SSH if possible
47
+ if is_localhost?(host) &&
48
+ user == whoami()
49
+ return tungsten_cmd_result(command)
50
+ end
51
+
46
52
  original_fwd_state = forward_cmd_results?()
47
53
  begin
48
54
  if TI
@@ -55,6 +55,18 @@ class TungstenScriptDatasource
55
55
  raise "Undefined function: #{self.class.name()}._start_server"
56
56
  end
57
57
 
58
+ def can_lock_tables?
59
+ false
60
+ end
61
+
62
+ def lock_tables
63
+ raise "Undefined function: #{self.class.name()}.lock_tables"
64
+ end
65
+
66
+ def unlock_tables
67
+ raise "Undefined function: #{self.class.name()}.unlock_tables"
68
+ end
69
+
58
70
  def snapshot_paths
59
71
  raise "Undefined function: #{self.class.name()}.snapshot_paths"
60
72
  end
@@ -139,6 +139,44 @@ class TungstenScriptMySQLDatasource < TungstenScriptDatasource
139
139
  @mysql_user
140
140
  end
141
141
 
142
+ def can_lock_tables?
143
+ true
144
+ end
145
+
146
+ def lock_tables
147
+ if @lock_thread != nil
148
+ TU.debug("Unable to lock tables because they are already locked")
149
+ return
150
+ end
151
+
152
+ TU.debug("Run FLUSH TABLES WITH READ LOCK")
153
+ @lock_thread = Thread.new(get_mysql_command()) {
154
+ |mysql_command|
155
+ status = Open4::popen4("export LANG=en_US; #{mysql_command}") do |pid, stdin, stdout, stderr|
156
+ stdin.puts("SET wait_timeout=30;\n")
157
+ stdin.puts("SET lock_wait_timeout=30;\n")
158
+ stdin.puts("FLUSH TABLES WITH READ LOCK;\n")
159
+
160
+ # Infinite loop to keep this thread alive until it is killed by the
161
+ # unlock_tables method
162
+ while true
163
+ sleep 60
164
+ end
165
+ end
166
+ }
167
+ end
168
+
169
+ def unlock_tables
170
+ if @lock_thread != nil
171
+ begin
172
+ Thread.kill(@lock_thread)
173
+ rescue TypeError
174
+ end
175
+
176
+ @lock_thread = nil
177
+ end
178
+ end
179
+
142
180
  def snapshot_paths
143
181
  paths = []
144
182
 
@@ -167,4 +205,12 @@ class TungstenScriptMySQLDatasource < TungstenScriptDatasource
167
205
  def can_manage_service?
168
206
  true
169
207
  end
208
+
209
+ def get_mysql_command
210
+ host = @ti.setting(@ti.setting_key(REPL_SERVICES, @service, "repl_datasource_host"))
211
+ port = @ti.setting(@ti.setting_key(REPL_SERVICES, @service, "repl_datasource_port"))
212
+ my_cnf = @ti.setting(@ti.setting_key(REPL_SERVICES, @service, "repl_datasource_mysql_service_conf"))
213
+
214
+ "mysql --defaults-file=#{my_cnf} -h#{host} --port=#{port}"
215
+ end
170
216
  end
@@ -283,14 +283,16 @@ class TungstenUtil
283
283
  return cmd_result(command)
284
284
  end
285
285
 
286
- unless defined?(Net::SSH)
287
- begin
288
- require "openssl"
289
- rescue LoadError
290
- raise("Unable to find the Ruby openssl library. Try installing the openssl package for your version of Ruby (libopenssl-ruby#{RUBY_VERSION[0,3]}).")
286
+ self.synchronize() {
287
+ unless defined?(Net::SSH)
288
+ begin
289
+ require "openssl"
290
+ rescue LoadError
291
+ raise("Unable to find the Ruby openssl library. Try installing the openssl package for your version of Ruby (libopenssl-ruby#{RUBY_VERSION[0,3]}).")
292
+ end
293
+ require 'net/ssh'
291
294
  end
292
- require 'net/ssh'
293
- end
295
+ }
294
296
 
295
297
  ssh_user = get_ssh_user(user)
296
298
  if user != ssh_user
@@ -347,6 +347,30 @@ module TungstenScript
347
347
  end
348
348
  end
349
349
 
350
+ def parse_boolean_option_blank_is_true(val)
351
+ if val == "true"
352
+ true
353
+ elsif val == "false"
354
+ false
355
+ elsif val.to_s() == ""
356
+ true
357
+ else
358
+ raise MessageError.new("Unable to parse value '#{val}' as a boolean")
359
+ end
360
+ end
361
+
362
+ def parse_boolean_option_blank_is_false(val)
363
+ if val == "true"
364
+ true
365
+ elsif val == "false"
366
+ false
367
+ elsif val.to_s() == ""
368
+ false
369
+ else
370
+ raise MessageError.new("Unable to parse value '#{val}' as a boolean")
371
+ end
372
+ end
373
+
350
374
  def validate
351
375
  if require_installed_directory?()
352
376
  if TI == nil
@@ -14,6 +14,7 @@ class TungstenUtil
14
14
  @force = false
15
15
  @json_interface = false
16
16
  @json_message_cache = []
17
+ @mutex = Mutex.new
17
18
 
18
19
  # Create a temporary file to hold log contents
19
20
  @log = Tempfile.new("tlog")
@@ -64,6 +65,8 @@ class TungstenUtil
64
65
 
65
66
  if val_parts[0] == "timeout"
66
67
  val_parts[1] = val_parts[1].to_i
68
+ elsif val_parts[0] == "verbose"
69
+ val_parts[1] = val_parts[1].to_sym
67
70
  end
68
71
 
69
72
  @ssh_options[val_parts[0].to_sym] = val_parts[1]
@@ -626,4 +629,10 @@ class TungstenUtil
626
629
 
627
630
  return hash
628
631
  end
632
+
633
+ def synchronize(&block)
634
+ @mutex.synchronize do
635
+ block.call()
636
+ end
637
+ end
629
638
  end
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.8.0
4
+ version: 0.9.0
5
5
  platform: ruby
6
6
  authors:
7
7
  - Continuent
8
8
  autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
- date: 2015-04-09 00:00:00.000000000 Z
11
+ date: 2015-06-09 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: json_pure
@@ -111,11 +111,13 @@ dependencies:
111
111
  description:
112
112
  email: info@continuent.com
113
113
  executables:
114
+ - tungsten_analyze_thl_index
114
115
  - tungsten_create_load
115
116
  - tungsten_policy
116
117
  extensions: []
117
118
  extra_rdoc_files: []
118
119
  files:
120
+ - bin/tungsten_analyze_thl_index
119
121
  - bin/tungsten_create_load
120
122
  - bin/tungsten_policy
121
123
  - lib/continuent-tools-core.rb