etch 3.20.1 → 4.0.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.
- data/Rakefile +1 -1
- data/lib/etch/client.rb +46 -29
- data/lib/etch.rb +17 -5
- 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 = '
|
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 = '
|
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(
|
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 #{
|
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
|
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
|
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
|
2318
|
-
|
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
|
2321
|
-
@last_response = response
|
2331
|
+
elsif response =~ /s/i
|
2332
|
+
@last_response = response
|
2322
2333
|
return CONFIRM_SKIP
|
2323
|
-
elsif response =~ /q/i
|
2324
|
-
@last_response = response
|
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 =
|
2398
|
+
fd = File.sysopen(lockpath, Fcntl::O_WRONLY|Fcntl::O_CREAT|Fcntl::O_EXCL)
|
2388
2399
|
puts "Lock acquired for #{file}" if (@debug)
|
2389
|
-
|
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
|
2463
|
-
|
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
|
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
|
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
|
-
#
|
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
|
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
|
-
|
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:
|
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-
|
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:
|
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:
|
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.
|
67
|
+
rubygems_version: 1.8.23
|
63
68
|
signing_key:
|
64
69
|
specification_version: 3
|
65
70
|
summary: Etch system configuration management client
|