etch 3.20.1 → 4.0.0

Sign up to get free protection for your applications and to get access to all the features.
Files changed (4) hide show
  1. data/Rakefile +1 -1
  2. data/lib/etch/client.rb +46 -29
  3. data/lib/etch.rb +17 -5
  4. metadata +10 -5
data/Rakefile CHANGED
@@ -3,7 +3,7 @@ spec = Gem::Specification.new do |s|
3
3
  s.name = 'etch'
4
4
  s.summary = 'Etch system configuration management client'
5
5
  s.add_dependency('facter')
6
- s.version = '3.20.1'
6
+ s.version = '4.0.0'
7
7
  s.author = 'Jason Heiss'
8
8
  s.email = 'etch-users@lists.sourceforge.net'
9
9
  s.homepage = 'http://etch.sourceforge.net'
data/lib/etch/client.rb CHANGED
@@ -42,7 +42,7 @@ end
42
42
  require 'etch'
43
43
 
44
44
  class Etch::Client
45
- VERSION = '3.20.1'
45
+ VERSION = '4.0.0'
46
46
 
47
47
  CONFIRM_PROCEED = 1
48
48
  CONFIRM_SKIP = 2
@@ -204,7 +204,7 @@ class Etch::Client
204
204
  @already_processed = {}
205
205
  @exec_already_processed = {}
206
206
  @exec_once_per_run = {}
207
- @results = []
207
+ @results = {}
208
208
  # See start/stop_output_capture for these
209
209
  @output_pipes = []
210
210
 
@@ -521,11 +521,11 @@ class Etch::Client
521
521
  rails_results << "status=#{CGI.escape(status.to_s)}"
522
522
  rails_results << "message=#{CGI.escape(message)}"
523
523
  if @detailed_results.include?('SERVER')
524
- @results.each do |result|
524
+ @results.each do |file, result|
525
525
  # Strangely enough this works. Even though the key is not unique to
526
526
  # each result the Rails parameter parsing code keeps track of keys it
527
527
  # has seen, and if it sees a duplicate it starts a new hash.
528
- rails_results << "results[][file]=#{CGI.escape(result['file'])}"
528
+ rails_results << "results[][file]=#{CGI.escape(file)}"
529
529
  rails_results << "results[][success]=#{CGI.escape(result['success'].to_s)}"
530
530
  rails_results << "results[][message]=#{CGI.escape(result['message'])}"
531
531
  end
@@ -563,8 +563,8 @@ class Etch::Client
563
563
  file.puts "Message:\n#{message}\n"
564
564
  end
565
565
  # Then the detailed results
566
- @results.each do |result|
567
- file.puts "File #{result['file']}, result #{result['success']}:\n"
566
+ @results.each do |resultfile, result|
567
+ file.puts "File #{resultfile}, result #{result['success']}:\n"
568
568
  file.puts result['message']
569
569
  end
570
570
  end
@@ -621,7 +621,6 @@ class Etch::Client
621
621
 
622
622
  # Prep the results capturing for this file
623
623
  result = {}
624
- result['file'] = file
625
624
  result['success'] = true
626
625
  result['message'] = ''
627
626
 
@@ -654,13 +653,19 @@ class Etch::Client
654
653
  # Process any other files that this file depends on
655
654
  config.elements.each('/config/depend') do |depend|
656
655
  puts "Processing dependency #{depend.text}" if (@debug)
657
- process_file(depend.text, responsedata)
656
+ continue_processing = process_file(depend.text, responsedata)
657
+ if !continue_processing
658
+ throw :process_done
659
+ end
658
660
  end
659
661
 
660
662
  # Process any commands that this file depends on
661
663
  config.elements.each('/config/dependcommand') do |dependcommand|
662
664
  puts "Processing command dependency #{dependcommand.text}" if (@debug)
663
- process_commands(dependcommand.text, responsedata)
665
+ continue_processing = process_commands(dependcommand.text, responsedata)
666
+ if !continue_processing
667
+ throw :process_done
668
+ end
664
669
  end
665
670
 
666
671
  # See what type of action the user has requested
@@ -834,7 +839,6 @@ class Etch::Client
834
839
  save_results = false
835
840
  throw :process_done
836
841
  when CONFIRM_QUIT
837
- unlock_all_files
838
842
  continue_processing = false
839
843
  save_results = false
840
844
  throw :process_done
@@ -1099,7 +1103,6 @@ class Etch::Client
1099
1103
  save_results = false
1100
1104
  throw :process_done
1101
1105
  when CONFIRM_QUIT
1102
- unlock_all_files
1103
1106
  continue_processing = false
1104
1107
  save_results = false
1105
1108
  throw :process_done
@@ -1279,7 +1282,6 @@ class Etch::Client
1279
1282
  save_results = false
1280
1283
  throw :process_done
1281
1284
  when CONFIRM_QUIT
1282
- unlock_all_files
1283
1285
  continue_processing = false
1284
1286
  save_results = false
1285
1287
  throw :process_done
@@ -1404,7 +1406,6 @@ class Etch::Client
1404
1406
  save_results = false
1405
1407
  throw :process_done
1406
1408
  when CONFIRM_QUIT
1407
- unlock_all_files
1408
1409
  continue_processing = false
1409
1410
  save_results = false
1410
1411
  throw :process_done
@@ -1504,7 +1505,7 @@ class Etch::Client
1504
1505
  end
1505
1506
  result['message'] << output
1506
1507
  if save_results
1507
- @results << result
1508
+ @results[file] = result
1508
1509
  end
1509
1510
 
1510
1511
  if exception
@@ -1542,7 +1543,6 @@ class Etch::Client
1542
1543
 
1543
1544
  # Prep the results capturing for this command
1544
1545
  result = {}
1545
- result['file'] = commandname
1546
1546
  result['success'] = true
1547
1547
  result['message'] = ''
1548
1548
 
@@ -1575,13 +1575,19 @@ class Etch::Client
1575
1575
  # Process any other commands that this command depends on
1576
1576
  command.elements.each('/commands/depend') do |depend|
1577
1577
  puts "Processing command dependency #{depend.text}" if (@debug)
1578
- process_commands(depend.text, responsedata)
1578
+ continue_processing = process_commands(depend.text, responsedata)
1579
+ if !continue_processing
1580
+ throw :process_done
1581
+ end
1579
1582
  end
1580
1583
 
1581
1584
  # Process any files that this command depends on
1582
1585
  command.elements.each('/commands/dependfile') do |dependfile|
1583
1586
  puts "Processing file dependency #{dependfile.text}" if (@debug)
1584
- process_file(dependfile.text, responsedata)
1587
+ continue_processing = process_file(dependfile.text, responsedata)
1588
+ if !continue_processing
1589
+ throw :process_done
1590
+ end
1585
1591
  end
1586
1592
 
1587
1593
  # Perform each step
@@ -1593,6 +1599,9 @@ class Etch::Client
1593
1599
  guard_result = process_guard(guard, commandname)
1594
1600
 
1595
1601
  if !guard_result
1602
+ # Tell the user what we're going to do
1603
+ puts "Will run command '#{command}'"
1604
+
1596
1605
  # If the user requested interactive mode ask them for
1597
1606
  # confirmation to proceed.
1598
1607
  if @interactive
@@ -1603,7 +1612,6 @@ class Etch::Client
1603
1612
  save_results = false
1604
1613
  throw :process_done
1605
1614
  when CONFIRM_QUIT
1606
- unlock_all_files
1607
1615
  continue_processing = false
1608
1616
  save_results = false
1609
1617
  throw :process_done
@@ -1637,7 +1645,7 @@ class Etch::Client
1637
1645
  end
1638
1646
  result['message'] << output
1639
1647
  if save_results
1640
- @results << result
1648
+ @results[commandname] = result
1641
1649
  end
1642
1650
 
1643
1651
  if exception
@@ -2314,14 +2322,17 @@ class Etch::Client
2314
2322
  else print "[p|s|q] "
2315
2323
  end
2316
2324
  response = $stdin.gets.chomp
2317
- if response =~ /p/i || @last_response =~ /p/i
2318
- @last_response = response if !response.strip.empty?
2325
+ if response.empty?
2326
+ response = @last_response
2327
+ end
2328
+ if response =~ /p/i
2329
+ @last_response = response
2319
2330
  return CONFIRM_PROCEED
2320
- elsif response =~ /s/i || @last_response =~ /s/i
2321
- @last_response = response if !response.strip.empty?
2331
+ elsif response =~ /s/i
2332
+ @last_response = response
2322
2333
  return CONFIRM_SKIP
2323
- elsif response =~ /q/i || @last_response =~ /q/i
2324
- @last_response = response if !response.strip.empty?
2334
+ elsif response =~ /q/i
2335
+ @last_response = response
2325
2336
  return CONFIRM_QUIT
2326
2337
  end
2327
2338
  end
@@ -2384,9 +2395,9 @@ class Etch::Client
2384
2395
  # Make 30 attempts (1s sleep after each attempt)
2385
2396
  30.times do |i|
2386
2397
  begin
2387
- fd = IO::sysopen(lockpath, Fcntl::O_WRONLY|Fcntl::O_CREAT|Fcntl::O_EXCL)
2398
+ fd = File.sysopen(lockpath, Fcntl::O_WRONLY|Fcntl::O_CREAT|Fcntl::O_EXCL)
2388
2399
  puts "Lock acquired for #{file}" if (@debug)
2389
- f = IO.open(fd) { |lockfile| lockfile.puts $$ }
2400
+ File.open(fd) { |lockfile| lockfile.puts $$ }
2390
2401
  @locked_files[file] = true
2391
2402
  return
2392
2403
  rescue Errno::EEXIST
@@ -2459,8 +2470,14 @@ class Etch::Client
2459
2470
  # to the pipe. The child gathers up anything sent over the pipe and
2460
2471
  # when we close the pipe later it sends the captured output back to us
2461
2472
  # over a second pipe.
2462
- pread, pwrite = IO.pipe
2463
- oread, owrite = IO.pipe
2473
+ pread = pwrite = oread = owrite = nil
2474
+ if RUBY_VERSION.split('.')[0..1].join('.').to_f >= 1.9
2475
+ pread, pwrite = IO.pipe(Encoding.default_external, 'UTF-8', :invalid => :replace, :undef => :replace)
2476
+ oread, owrite = IO.pipe(Encoding.default_external, 'UTF-8', :invalid => :replace, :undef => :replace)
2477
+ else
2478
+ pread, pwrite = IO.pipe
2479
+ oread, owrite = IO.pipe
2480
+ end
2464
2481
  if fork
2465
2482
  # Parent
2466
2483
  pread.close
data/lib/etch.rb CHANGED
@@ -51,16 +51,16 @@ end
51
51
  class Etch
52
52
  # FIXME: I'm not really proud of this, it seems like there ought to be a way
53
53
  # to just use one logger. The problem is that on the server we'd like to
54
- # use RAILS_DEFAULT_LOGGER for general logging (which is logging to
54
+ # use Rails.logger for general logging (which is logging to
55
55
  # log/production.log), but be able to turn on debug-level logging for
56
56
  # individual connections (via the debug parameter sent in the HTTP
57
- # requests). If we twiddle the log level of RAILS_DEFAULT_LOGGER then all
57
+ # requests). If we twiddle the log level of Rails.logger then all
58
58
  # connections coming in at the same time as the debug connection will also
59
59
  # get logged as debug, making the logs confusing. And if the debug
60
60
  # connection aborts for some reason we also risk leaving
61
- # RAILS_DEFAULT_LOGGER set to debug, flooding the logs. So it seems like we
61
+ # Rails.logger set to debug, flooding the logs. So it seems like we
62
62
  # need a seperate logger for debugging. But that just seems wrong somehow.
63
- # We don't want to just dup RAILS_DEFAULT_LOGGER for each connection, even
63
+ # We don't want to just dup Rails.logger for each connection, even
64
64
  # if Logger didn't immediately blow up we'd probably end up with scrambled
65
65
  # logs as simultaneous connections tried to write at the same time. Or
66
66
  # maybe that would work, depending on how Ruby and the OS buffer writes to
@@ -285,7 +285,11 @@ class Etch
285
285
  end
286
286
 
287
287
  # Load the config.xml file
288
- config_xml = Etch.xmlload(config_xml_file)
288
+ begin
289
+ config_xml = Etch.xmlload(config_xml_file)
290
+ rescue Exception => e
291
+ raise Etch.wrap_exception(e, "Error loading config.xml for #{file}:\n" + e.message)
292
+ end
289
293
 
290
294
  # Filter the config.xml file by looking for attributes
291
295
  begin
@@ -822,6 +826,10 @@ class Etch
822
826
  end
823
827
  end
824
828
 
829
+ # Earlier we chdir'd into the file's directory in the repository. It
830
+ # seems best not to leave this process with that as the cwd.
831
+ Dir.chdir('/')
832
+
825
833
  # In addition to successful configs return configs for files that need
826
834
  # orig data (generation_status==false) because any setup commands might be
827
835
  # needed to create the original file.
@@ -961,6 +969,10 @@ class Etch
961
969
  generation_status = :success
962
970
  end
963
971
 
972
+ # Earlier we chdir'd into the command's directory in the repository. It
973
+ # seems best not to leave this process with that as the cwd.
974
+ Dir.chdir('/')
975
+
964
976
  # If filtering didn't remove all the content then add this to the list of
965
977
  # commands to be returned to the client.
966
978
  if generation_status && generation_status != :unknown &&
metadata CHANGED
@@ -1,7 +1,7 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: etch
3
3
  version: !ruby/object:Gem::Version
4
- version: 3.20.1
4
+ version: 4.0.0
5
5
  prerelease:
6
6
  platform: ruby
7
7
  authors:
@@ -9,11 +9,11 @@ authors:
9
9
  autorequire:
10
10
  bindir: bin
11
11
  cert_chain: []
12
- date: 2012-03-21 00:00:00.000000000 Z
12
+ date: 2012-04-30 00:00:00.000000000 Z
13
13
  dependencies:
14
14
  - !ruby/object:Gem::Dependency
15
15
  name: facter
16
- requirement: &70164344222100 !ruby/object:Gem::Requirement
16
+ requirement: !ruby/object:Gem::Requirement
17
17
  none: false
18
18
  requirements:
19
19
  - - ! '>='
@@ -21,7 +21,12 @@ dependencies:
21
21
  version: '0'
22
22
  type: :runtime
23
23
  prerelease: false
24
- version_requirements: *70164344222100
24
+ version_requirements: !ruby/object:Gem::Requirement
25
+ none: false
26
+ requirements:
27
+ - - ! '>='
28
+ - !ruby/object:Gem::Version
29
+ version: '0'
25
30
  description:
26
31
  email: etch-users@lists.sourceforge.net
27
32
  executables:
@@ -59,7 +64,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
59
64
  version: '0'
60
65
  requirements: []
61
66
  rubyforge_project: etchsyscm
62
- rubygems_version: 1.8.15
67
+ rubygems_version: 1.8.23
63
68
  signing_key:
64
69
  specification_version: 3
65
70
  summary: Etch system configuration management client