continuent-tools-core 0.11.0 → 0.12.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: 066d8434e623f609bba0d8b314fb6fa388968013
4
- data.tar.gz: a86daaa05f7ce16f95f050b34bc6a70c9d310eaf
3
+ metadata.gz: f43c9a9d090fbde883cdc8805505da41d06e63ef
4
+ data.tar.gz: 7fe7ba956951f4e6eb3704fdd946550efac0fc8c
5
5
  SHA512:
6
- metadata.gz: ca7e9ca391f2b1d6be6981fdbe2b41816c9a3feda3b14fb8dd665ce0921be3e546fbeab34bbdb9f83183e97f2221e0f063b2e1cff93623fab8d0b5b820a386db
7
- data.tar.gz: 29747f8be2ffed8945eeaacbd8906afe27fdee95fb4971470e4422d6011788820fd5ec064acfa01deca801041f4b470584405e849148e81bf13c460d6259104f
6
+ metadata.gz: 239f531642feb97d8512c03e09cf0628e8cc89b2bfd475825f8cddb96e3bf7c023d5d1c31f0388b16e165a20fcb5fa36a19c05172446164c1663d23bbd2fc119
7
+ data.tar.gz: 37f6e77d3e75cc0470ff79bacc1451668c87c9d86e96abcde3dcc34e83f01df978c308fe467432a8247109f577e18d3bfc5018c5986e68d12dd326d0cf4f7c13
@@ -164,7 +164,7 @@ class TungstenDirectory
164
164
  entry["id"] = id
165
165
  entry["tags"].each{
166
166
  |k,v|
167
- v = v.split(",")
167
+ v = v.to_s().split(",")
168
168
  if v.size() > 1
169
169
  entry["tags"][k] = v
170
170
  end
data/bin/tungsten_policy CHANGED
@@ -31,18 +31,18 @@ class TungstenMigrateSchema
31
31
 
32
32
  def main
33
33
  if opt(:set) != nil
34
- cmd = nil
35
- case opt(:set).downcase()
36
- when "maintenance"
37
- cmd = "setmaintenance"
38
- when "automatic"
39
- cmd = "setautomatic"
40
- when "manual"
41
- cmd = "setmanual"
34
+ commands = []
35
+ if opt(:service).to_s() != ""
36
+ commands << "use #{opt(:service)}"
42
37
  end
38
+ commands << "set policy #{opt(:set)}"
43
39
 
44
- mgr = TungstenDataserviceManager.new(TI.mgr_api_uri())
45
- mgr.call(opt(:service), cmd)
40
+ cmd = "echo '#{commands.join(';')}' | #{TI.cctrl()}"
41
+ result = TU.cmd_result(cmd, true)
42
+
43
+ unless result =~ /policy mode is now #{opt(:set).upcase()}/
44
+ raise MessageError.new("There was an error setting the policy")
45
+ end
46
46
  end
47
47
 
48
48
  status = TungstenStatus.new(TI, opt(:service))
@@ -69,6 +69,32 @@ class TungstenMigrateSchema
69
69
  unless TU.is_valid?()
70
70
  return TU.is_valid?()
71
71
  end
72
+
73
+ if opt(:set) != nil
74
+ opt(:set, opt(:set).downcase())
75
+ case opt(:set)
76
+ when "maintenance"
77
+ # Do nothing
78
+ when "automatic"
79
+ # Do nothing
80
+ when "manual"
81
+ # Do nothing
82
+ else
83
+ TU.error("Unable to set policy to #{opt(:set)}")
84
+ end
85
+ end
86
+
87
+ if TI.dataservices().size() > 1
88
+ if opt(:service).to_s() == ""
89
+ TU.error("The --service argument is required because multiple dataservices are availble.")
90
+ end
91
+ end
92
+
93
+ if opt(:service) != nil
94
+ unless TI.dataservices().include?(opt(:service))
95
+ TU.error("The #{opt(:service)} dataservice is not valid")
96
+ end
97
+ end
72
98
  end
73
99
 
74
100
  def script_name
@@ -0,0 +1,106 @@
1
+ # VMware Continuent Tungsten Replicator
2
+ # Copyright (C) 2015 VMware, Inc. All rights reserved.
3
+ #
4
+ # Licensed under the Apache License, Version 2.0 (the "License");
5
+ # you may not use this file except in compliance with the License.
6
+ # You may obtain 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,
12
+ # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13
+ # See the License for the specific language governing permissions and
14
+ # limitations under the License.
15
+ #
16
+ # Initial developer(s): Jeff Mace
17
+
18
+ class DarwinIPParsePlatform < IPParsePlatform
19
+ def self.supports_platform?(platform)
20
+ if platform.downcase() =~ /darwin/
21
+ true
22
+ else
23
+ false
24
+ end
25
+ end
26
+
27
+ def get_raw_ip_configuration
28
+ path = `which ifconfig 2>/dev/null`.chomp()
29
+ if path == ""
30
+ path = "/sbin/ifconfig"
31
+ end
32
+
33
+ results = `export LANG=en_US; #{path} -a`
34
+ if results == false
35
+ raise "Unable to collect IP configuration from ifconfig"
36
+ else
37
+ return results
38
+ end
39
+ end
40
+
41
+ def parse(raw)
42
+ name_regex = Regexp.compile(/^([a-zA-Z0-9]+):/)
43
+ ether_regex = Regexp.compile(/ether (a-f0-9:)*/)
44
+ flags_regex = Regexp.compile(/flags=([0-9]+)\<([A-Z,]+)\>/)
45
+ inet4_regex1 = Regexp.compile(/inet ([0-9\.]+)[ ]+netmask 0x([a-f0-9]{8})[ ]+(broadcast [0-9\.]+)?/)
46
+ inet6_regex1 = Regexp.compile(/inet6 ([a-f0-9:]+)%[a-z0-9]*[ ]*prefixlen ([0-9]+)/)
47
+
48
+ all_interfaces = []
49
+ interface = []
50
+
51
+ raw.split("\n").each{
52
+ |line|
53
+ if name_regex.match(line)
54
+ if interface.size() > 0
55
+ all_interfaces << interface.join("\n")
56
+ end
57
+ interface = [line]
58
+ else
59
+ interface << line
60
+ end
61
+ }
62
+ if interface.size() > 0
63
+ all_interfaces << interface.join("\n")
64
+ end
65
+
66
+ all_interfaces.each{
67
+ |ifconfig|
68
+ include_interface = false
69
+
70
+ begin
71
+ if ether_regex.match(ifconfig)
72
+ include_interface = true
73
+ end
74
+ rescue
75
+ # Catch the exception and move on
76
+ end
77
+
78
+ if include_interface == false
79
+ next
80
+ end
81
+
82
+ name = name_regex.match(ifconfig)[1]
83
+ if name == nil
84
+ raise "Unable to parse IP configuration because a valid name does not exist"
85
+ end
86
+
87
+ m1 = inet4_regex1.match(ifconfig)
88
+ if m1
89
+ netmask = [
90
+ m1[2][0,2].to_i(16),
91
+ m1[2][2,2].to_i(16),
92
+ m1[2][4,2].to_i(16),
93
+ m1[2][6,2].to_i(16),
94
+ ]
95
+ add_ipv4(name, m1[1], netmask.join('.'))
96
+ end
97
+
98
+ m1 = inet6_regex1.match(ifconfig)
99
+ if m1
100
+ add_ipv6(name, m1[1], m1[2])
101
+ end
102
+ }
103
+
104
+ return @interfaces
105
+ end
106
+ end
@@ -5,6 +5,10 @@ class TungstenScriptDatasource
5
5
  @is_direct = is_direct
6
6
  end
7
7
 
8
+ def title
9
+ raise "Undefined function: #{self.class.name()}.title"
10
+ end
11
+
8
12
  def can_manage_service?
9
13
  false
10
14
  end
@@ -26,7 +30,7 @@ class TungstenScriptDatasource
26
30
  return
27
31
  end
28
32
 
29
- TU.notice("Stop the #{self.class.name()} service")
33
+ TU.notice("Stop the #{self.title()} service")
30
34
  _stop_server()
31
35
  end
32
36
 
@@ -47,7 +51,7 @@ class TungstenScriptDatasource
47
51
  return
48
52
  end
49
53
 
50
- TU.notice("Start the #{self.class.name()} service")
54
+ TU.notice("Start the #{self.title()} service")
51
55
  _start_server()
52
56
  end
53
57
 
@@ -82,4 +86,70 @@ class TungstenScriptDatasource
82
86
  def sql_result(sql)
83
87
  @ti.sql_result(@service, sql, @is_direct)
84
88
  end
89
+
90
+ def url
91
+ begin
92
+ TU.log_cmd_results?(false)
93
+ if @is_direct == true
94
+ return @ti.setting(@ti.setting_key(REPL_SERVICES, @service, "repl_direct_datasource_jdbcqueryurl"))
95
+ else
96
+ return @ti.setting(@ti.setting_key(REPL_SERVICES, @service, "repl_datasource_jdbcqueryurl"))
97
+ end
98
+ ensure
99
+ TU.log_cmd_results?(true)
100
+ end
101
+ end
102
+
103
+ def host
104
+ begin
105
+ TU.log_cmd_results?(false)
106
+ if @is_direct == true
107
+ return @ti.setting(@ti.setting_key(REPL_SERVICES, @service, "repl_direct_datasource_host"))
108
+ else
109
+ return @ti.setting(@ti.setting_key(REPL_SERVICES, @service, "repl_datasource_host"))
110
+ end
111
+ ensure
112
+ TU.log_cmd_results?(true)
113
+ end
114
+ end
115
+
116
+ def port
117
+ begin
118
+ TU.log_cmd_results?(false)
119
+ if @is_direct == true
120
+ return @ti.setting(@ti.setting_key(REPL_SERVICES, @service, "repl_direct_datasource_port"))
121
+ else
122
+ return @ti.setting(@ti.setting_key(REPL_SERVICES, @service, "repl_datasource_port"))
123
+ end
124
+ ensure
125
+ TU.log_cmd_results?(true)
126
+ end
127
+ end
128
+
129
+ def user
130
+ begin
131
+ TU.log_cmd_results?(false)
132
+ if @is_direct == true
133
+ return @ti.setting(@ti.setting_key(REPL_SERVICES, @service, "repl_direct_datasource_user"))
134
+ else
135
+ return @ti.setting(@ti.setting_key(REPL_SERVICES, @service, "repl_datasource_user"))
136
+ end
137
+ ensure
138
+ TU.log_cmd_results?(true)
139
+ end
140
+ end
141
+
142
+ def password
143
+ begin
144
+ # Disable logging of command results so the password doesn't end up in a log file
145
+ TU.log_cmd_results?(false)
146
+ if @is_direct == true
147
+ return @ti.setting(@ti.setting_key(REPL_SERVICES, @service, "repl_direct_datasource_password"))
148
+ else
149
+ return @ti.setting(@ti.setting_key(REPL_SERVICES, @service, "repl_datasource_password"))
150
+ end
151
+ ensure
152
+ TU.log_cmd_results?(true)
153
+ end
154
+ end
85
155
  end
@@ -8,6 +8,10 @@ class TungstenScriptMySQLDatasource < TungstenScriptDatasource
8
8
  end
9
9
  end
10
10
 
11
+ def title
12
+ "MySQL"
13
+ end
14
+
11
15
  def _stop_server
12
16
  begin
13
17
  pid_file = get_variable("pid_file")
data/lib/tungsten/exec.rb CHANGED
@@ -445,46 +445,51 @@ class TungstenUtil
445
445
  end
446
446
 
447
447
  def is_localhost?(hostname)
448
- if hostname == DEFAULTS
449
- return false
450
- end
451
-
452
448
  @_is_localhost_cache ||= {}
453
449
  unless @_is_localhost_cache.has_key?(hostname)
454
450
  @_is_localhost_cache[hostname] = _is_localhost?(hostname)
455
451
  end
456
-
452
+
457
453
  return @_is_localhost_cache[hostname]
458
454
  end
459
455
 
460
456
  def _is_localhost?(hostname)
461
- if hostname == hostname()
462
- return true
463
- end
464
-
465
- ip_addresses = get_ip_addresses(hostname)
466
- if ip_addresses == false
457
+ case hostname
458
+ when DEFAULTS
467
459
  return false
468
- end
460
+ when hostname()
461
+ return true
462
+ when "localhost"
463
+ return true
464
+ when "127.0.0.1"
465
+ return true
466
+ when "::1"
467
+ return true
468
+ else
469
+ ip_addresses = get_ip_addresses(hostname)
470
+ if ip_addresses == false
471
+ return false
472
+ end
469
473
 
470
- debug("Search ifconfig for #{ip_addresses.join(', ')}")
471
- ipparsed = IPParse.new().get_interfaces()
472
- ipparsed.each{
473
- |iface, addresses|
474
+ debug("Search ifconfig for #{ip_addresses.join(', ')}")
475
+ ipparsed = IPParse.new().get_interfaces()
476
+ ipparsed.each{
477
+ |iface, addresses|
474
478
 
475
- begin
476
- # Do a string comparison so that we only match the address portion
477
- addresses.each{
478
- |type, details|
479
- if ip_addresses.include?(details[:address])
480
- return true
481
- end
482
- }
483
- rescue ArgumentError
484
- end
485
- }
479
+ begin
480
+ # Do a string comparison so that we only match the address portion
481
+ addresses.each{
482
+ |type, details|
483
+ if ip_addresses.include?(details[:address])
484
+ return true
485
+ end
486
+ }
487
+ rescue ArgumentError
488
+ end
489
+ }
486
490
 
487
- false
491
+ return false
492
+ end
488
493
  end
489
494
 
490
495
  def get_ip_addresses(hostname)
@@ -381,22 +381,14 @@ class TungstenInstall
381
381
  raise "Unable to run SQL command for the #{service} dataservice. The datasource type does not support SQL commands."
382
382
  end
383
383
 
384
+ ds = datasource(service, use_direct_extractor)
385
+ sql_results_from_url(sql, ds.url(), ds.user(), ds.password())
386
+ end
387
+
388
+ def sql_results_from_url(sql, url, user, password)
384
389
  cfg = nil
385
390
  command = nil
386
391
  begin
387
- # Disable logging of command results so the password doesn't end up in a log file
388
- TU.log_cmd_results?(false)
389
- if use_direct_extractor == true
390
- url= setting(setting_key(REPL_SERVICES, service, "repl_direct_datasource_jdbcqueryurl"))
391
- user = setting(setting_key(REPL_SERVICES, service, "repl_direct_datasource_user"))
392
- password = setting(setting_key(REPL_SERVICES, service, "repl_direct_datasource_password"))
393
- else
394
- url = setting(setting_key(REPL_SERVICES, service, "repl_datasource_jdbcqueryurl"))
395
- user = setting(setting_key(REPL_SERVICES, service, "repl_datasource_user"))
396
- password = setting(setting_key(REPL_SERVICES, service, "repl_datasource_password"))
397
- end
398
- TU.log_cmd_results?(true)
399
-
400
392
  cfg = Tempfile.new("cnf")
401
393
  cfg.puts("url=#{url}")
402
394
  cfg.puts("user=#{user}")
@@ -443,6 +435,16 @@ class TungstenInstall
443
435
  def sql_result(service, sql, use_direct_extractor = false)
444
436
  results = sql_results(service, sql, use_direct_extractor)
445
437
 
438
+ return_first_result(results)
439
+ end
440
+
441
+ def sql_result_from_url(sql, url, user, password)
442
+ results = sql_results_from_url(sql, url, user, password)
443
+
444
+ return_first_result(results)
445
+ end
446
+
447
+ def return_first_result(results)
446
448
  if results.size() == 0
447
449
  raise "No results were returned by #{sql}"
448
450
  end
@@ -53,6 +53,7 @@ module TungstenScript
53
53
  TU.debug("Begin #{$0} #{ARGV.join(' ')}")
54
54
 
55
55
  begin
56
+ prepare_environment()
56
57
  configure()
57
58
  @option_definitions.each{
58
59
  |option_key,definition|
@@ -134,6 +135,24 @@ module TungstenScript
134
135
  })
135
136
  end
136
137
 
138
+ def prepare_environment
139
+ target_umask = nil
140
+ if TI != nil
141
+ install_umask = TI.setting(TI.setting_key(HOSTS, "file_protection_umask"))
142
+ if install_umask.to_s() != ""
143
+ target_umask = install_umask.to_i(8)
144
+ end
145
+ else
146
+ library_mode = sprintf("%o", File.stat(File.dirname(__FILE__)).mode)
147
+ library_umask = 777 - library_mode[-3,3].to_i()
148
+ target_umask = sprintf("%04d", library_umask).to_i(8)
149
+ end
150
+
151
+ if target_umask != nil
152
+ File.umask(target_umask)
153
+ end
154
+ end
155
+
137
156
  def opt(option_key, value = nil)
138
157
  if value != nil
139
158
  @options[option_key] = value
@@ -614,7 +633,7 @@ module OfflineServicesScript
614
633
  })
615
634
 
616
635
  add_option(:offline, {
617
- :on => "--offline String",
636
+ :on => "--offline [String]",
618
637
  :help => "Put required replication services offline before processing",
619
638
  :default => false,
620
639
  :parse => method(:parse_boolean_option_blank_is_true)
@@ -628,7 +647,7 @@ module OfflineServicesScript
628
647
  })
629
648
 
630
649
  add_option(:online, {
631
- :on => "--online String",
650
+ :on => "--online [String]",
632
651
  :help => "Put required replication services online after successful processing",
633
652
  :default => false,
634
653
  :parse => method(:parse_boolean_option_blank_is_true)
@@ -690,7 +709,7 @@ module OfflineServicesScript
690
709
 
691
710
  begin
692
711
  if use_manager == true
693
- get_manager_api.call("#{ds}/#{TI.hostname()}", 'shun')
712
+ TU.cmd_result("echo 'datasource #{TI.hostname()} shun' | #{TI.cctrl()}")
694
713
  end
695
714
 
696
715
  # The trepctl offline command is required even when using
@@ -708,8 +727,20 @@ module OfflineServicesScript
708
727
  raise("The replication #{TU.pluralize(ds_list, "service", "services")} #{TU.pluralize(ds_list, "is", "are")} taking too long to go offline. Check the status for more information or use the --offline-timeout argument.")
709
728
  end
710
729
  end
730
+ end
731
+
732
+ begin
733
+ clear_logs = opt(:clear_logs)
734
+ if clear_logs_during_prepare() == false
735
+ clear_logs = false
736
+ end
737
+
738
+ if clear_logs == true
739
+ cleanup_services(false, clear_logs)
740
+ end
711
741
  rescue => e
712
742
  TU.exception(e)
743
+ code = 1
713
744
  end
714
745
  end
715
746
  end
@@ -717,10 +748,15 @@ module OfflineServicesScript
717
748
  def cleanup(code = 0)
718
749
  if initialized?() == true && TI != nil && code == 0
719
750
  begin
751
+ clear_logs = opt(:clear_logs)
752
+ if clear_logs_during_prepare() == true
753
+ clear_logs = false
754
+ end
755
+
720
756
  if allow_service_state_change?() == true && @options[:online] == true
721
- cleanup_services(true, @options[:clear_logs])
722
- elsif @options[:clear_logs] == true
723
- cleanup_services(false, @options[:clear_logs])
757
+ cleanup_services(true, clear_logs)
758
+ elsif clear_logs == true
759
+ cleanup_services(false, clear_logs)
724
760
  end
725
761
  rescue => e
726
762
  TU.exception(e)
@@ -840,6 +876,10 @@ module OfflineServicesScript
840
876
 
841
877
  @api
842
878
  end
879
+
880
+ def clear_logs_during_prepare
881
+ false
882
+ end
843
883
  end
844
884
 
845
885
  # Only require a single replication service to be OFFLINE
@@ -975,7 +1015,7 @@ module MySQLServiceScript
975
1015
  # Read the configured value for a mysql variable
976
1016
  def get_mysql_option(opt)
977
1017
  begin
978
- val = TU.cmd_result("my_print_defaults --config-file=#{@options[:my_cnf]} mysqld | grep -e'^--#{opt.gsub(/[\-\_]/, "[-_]")}'")
1018
+ val = TU.cmd_result("my_print_defaults --config-file=#{@options[:my_cnf]} mysqld | grep -e'^--#{opt.gsub(/[\-\_]/, "[-_]")}='")
979
1019
  rescue CommandError => ce
980
1020
  return nil
981
1021
  end
data/lib/tungsten/util.rb CHANGED
@@ -154,6 +154,17 @@ class TungstenUtil
154
154
  @log.puts(old_log.read())
155
155
  end
156
156
 
157
+ def limit_file_permissions(path)
158
+ if File.exists?(path)
159
+ # Get values like 0660 or 0700 for the log and umask
160
+ log_perms = sprintf("%o", File.stat(path).mode)[-4,4].to_i(8)
161
+ max_perms = sprintf("%04d", 777-sprintf("%o", File.umask()).to_i()).to_i(8)
162
+ # Calculate the target permissions for @log and set them
163
+ set_to_perms = log_perms & max_perms
164
+ File.chmod(sprintf("%o", set_to_perms).to_i(8), path)
165
+ end
166
+ end
167
+
157
168
  def reset_errors
158
169
  @num_errors = 0
159
170
  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.11.0
4
+ version: 0.12.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-10-06 00:00:00.000000000 Z
11
+ date: 2015-12-04 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: json_pure
@@ -134,6 +134,7 @@ files:
134
134
  - lib/iniparse/lines.rb
135
135
  - lib/iniparse/parser.rb
136
136
  - lib/iniparse.rb
137
+ - lib/ipparse/platforms/darwin.rb
137
138
  - lib/ipparse/platforms/linux.rb
138
139
  - lib/ipparse/README
139
140
  - lib/ipparse.rb