continuent-tools-core 0.8.0 → 0.9.0

Sign up to get free protection for your applications and to get access to all the features.
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