etch 3.13 → 3.15.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/etchclient.rb +127 -108
- metadata +3 -6
- data/etc/ca.pem +0 -1
- data/etc/dhparams +0 -9
- data/man/man8/etch.8 +0 -204
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.
|
6
|
+
s.version = '3.15.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/etchclient.rb
CHANGED
@@ -35,13 +35,13 @@ require 'logger'
|
|
35
35
|
require 'etch'
|
36
36
|
|
37
37
|
class Etch::Client
|
38
|
-
VERSION = '3.
|
38
|
+
VERSION = '3.15.0'
|
39
39
|
|
40
40
|
CONFIRM_PROCEED = 1
|
41
41
|
CONFIRM_SKIP = 2
|
42
42
|
CONFIRM_QUIT = 3
|
43
43
|
PRIVATE_KEY_PATHS = ["/etc/ssh/ssh_host_rsa_key", "/etc/ssh_host_rsa_key"]
|
44
|
-
CONFIGDIR = '/etc
|
44
|
+
CONFIGDIR = '/etc'
|
45
45
|
|
46
46
|
# We need these in relation to the output capturing
|
47
47
|
ORIG_STDOUT = STDOUT.dup
|
@@ -141,17 +141,17 @@ class Etch::Client
|
|
141
141
|
http = Net::HTTP.new(@filesuri.host, @filesuri.port)
|
142
142
|
if @filesuri.scheme == "https"
|
143
143
|
# Eliminate the OpenSSL "using default DH parameters" warning
|
144
|
-
if File.exist?(File.join(CONFIGDIR, 'dhparams'))
|
145
|
-
dh = OpenSSL::PKey::DH.new(IO.read(File.join(CONFIGDIR, 'dhparams')))
|
144
|
+
if File.exist?(File.join(CONFIGDIR, 'etch', 'dhparams'))
|
145
|
+
dh = OpenSSL::PKey::DH.new(IO.read(File.join(CONFIGDIR, 'etch', 'dhparams')))
|
146
146
|
Net::HTTP.ssl_context_accessor(:tmp_dh_callback)
|
147
147
|
http.tmp_dh_callback = proc { dh }
|
148
148
|
end
|
149
149
|
http.use_ssl = true
|
150
|
-
if File.exist?(File.join(CONFIGDIR, 'ca.pem'))
|
151
|
-
http.ca_file = File.join(CONFIGDIR, 'ca.pem')
|
150
|
+
if File.exist?(File.join(CONFIGDIR, 'etch', 'ca.pem'))
|
151
|
+
http.ca_file = File.join(CONFIGDIR, 'etch', 'ca.pem')
|
152
152
|
http.verify_mode = OpenSSL::SSL::VERIFY_PEER
|
153
|
-
elsif File.directory?(File.join(CONFIGDIR, 'ca'))
|
154
|
-
http.ca_path = File.join(CONFIGDIR, 'ca')
|
153
|
+
elsif File.directory?(File.join(CONFIGDIR, 'etch', 'ca'))
|
154
|
+
http.ca_path = File.join(CONFIGDIR, 'etch', 'ca')
|
155
155
|
http.verify_mode = OpenSSL::SSL::VERIFY_PEER
|
156
156
|
end
|
157
157
|
end
|
@@ -403,7 +403,9 @@ class Etch::Client
|
|
403
403
|
rescue Exception => e
|
404
404
|
status = 1
|
405
405
|
$stderr.puts e.message
|
406
|
+
message << e.message
|
406
407
|
$stderr.puts e.backtrace.join("\n") if @debug
|
408
|
+
message << e.backtrace.join("\n") if @debug
|
407
409
|
end # begin/rescue
|
408
410
|
end # catch
|
409
411
|
|
@@ -540,8 +542,10 @@ class Etch::Client
|
|
540
542
|
# original file.
|
541
543
|
if config.elements['/config/revert']
|
542
544
|
origpathbase = File.join(@origbase, file)
|
545
|
+
origpath = nil
|
543
546
|
|
544
547
|
# Restore the original file if it is around
|
548
|
+
revert_occurred = false
|
545
549
|
if File.exist?("#{origpathbase}.ORIG")
|
546
550
|
origpath = "#{origpathbase}.ORIG"
|
547
551
|
origdir = File.dirname(origpath)
|
@@ -553,10 +557,7 @@ class Etch::Client
|
|
553
557
|
|
554
558
|
puts "Restoring #{origpath} to #{file}"
|
555
559
|
recursive_copy_and_rename(origdir, origbase, file) if (!@dryrun)
|
556
|
-
|
557
|
-
# Now remove the backed-up original so that future runs
|
558
|
-
# don't do anything
|
559
|
-
remove_file(origpath) if (!@dryrun)
|
560
|
+
revert_occurred = true
|
560
561
|
elsif File.exist?("#{origpathbase}.TAR")
|
561
562
|
origpath = "#{origpathbase}.TAR"
|
562
563
|
filedir = File.dirname(file)
|
@@ -566,19 +567,24 @@ class Etch::Client
|
|
566
567
|
|
567
568
|
puts "Restoring #{file} from #{origpath}"
|
568
569
|
system("cd #{filedir} && tar xf #{origpath}") if (!@dryrun)
|
569
|
-
|
570
|
-
# Now remove the backed-up original so that future runs
|
571
|
-
# don't do anything
|
572
|
-
remove_file(origpath) if (!@dryrun)
|
570
|
+
revert_occurred = true
|
573
571
|
elsif File.exist?("#{origpathbase}.NOORIG")
|
574
572
|
origpath = "#{origpathbase}.NOORIG"
|
575
573
|
puts "Original #{file} didn't exist, restoring that state"
|
576
574
|
|
577
575
|
# Remove anything we might have written out for this file
|
578
576
|
remove_file(file) if (!@dryrun)
|
577
|
+
revert_occurred = true
|
578
|
+
end
|
579
|
+
|
580
|
+
# Update the history log
|
581
|
+
if revert_occurred
|
582
|
+
save_history(file)
|
583
|
+
end
|
579
584
|
|
580
|
-
|
581
|
-
|
585
|
+
# Now remove the backed-up original so that future runs
|
586
|
+
# don't do anything
|
587
|
+
if origpath
|
582
588
|
remove_file(origpath) if (!@dryrun)
|
583
589
|
end
|
584
590
|
|
@@ -1696,109 +1702,112 @@ class Etch::Client
|
|
1696
1702
|
|
1697
1703
|
origpath
|
1698
1704
|
end
|
1699
|
-
|
1705
|
+
|
1700
1706
|
# This subroutine maintains a revision history for the file in @historybase
|
1701
1707
|
def save_history(file)
|
1702
|
-
|
1708
|
+
histdir = File.join(@historybase, "#{file}.HISTORY")
|
1709
|
+
current = File.join(histdir, 'current')
|
1710
|
+
|
1711
|
+
# Migrate old RCS history
|
1712
|
+
if File.file?(histdir) && File.directory?(File.join(File.dirname(histdir), 'RCS'))
|
1713
|
+
if !@dryrun
|
1714
|
+
puts "Migrating old RCS history to new format"
|
1715
|
+
rcsmax = nil
|
1716
|
+
IO.popen("rlog #{histdir}") do |pipe|
|
1717
|
+
pipe.each do |line|
|
1718
|
+
if line =~ /^head: 1.(.*)/
|
1719
|
+
rcsmax = $1.to_i
|
1720
|
+
break
|
1721
|
+
end
|
1722
|
+
end
|
1723
|
+
end
|
1724
|
+
if !rcsmax
|
1725
|
+
raise "Failed to parse RCS history rlog output"
|
1726
|
+
end
|
1727
|
+
tmphistdir = tempdir(histdir)
|
1728
|
+
1.upto(rcsmax) do |rcsrev|
|
1729
|
+
rcsrevcontents = `co -q -p1.#{rcsrev} #{histdir}`
|
1730
|
+
# rcsrev-1 because RCS starts revisions at 1.1 and we start files
|
1731
|
+
# at 0000
|
1732
|
+
File.open(File.join(tmphistdir, sprintf('%04d', rcsrev-1)), 'w') do |rcsrevfile|
|
1733
|
+
rcsrevfile.write(rcsrevcontents)
|
1734
|
+
end
|
1735
|
+
end
|
1736
|
+
FileUtils.copy(histdir, File.join(tmphistdir, 'current'))
|
1737
|
+
File.delete(histdir)
|
1738
|
+
File.rename(tmphistdir, histdir)
|
1739
|
+
end
|
1740
|
+
end
|
1703
1741
|
|
1704
1742
|
# Make sure the directory tree for this file exists in the
|
1705
1743
|
# directory we save history in.
|
1706
|
-
|
1707
|
-
|
1708
|
-
puts "Making directory tree #{histdir}"
|
1744
|
+
if !File.exist?(histdir)
|
1745
|
+
puts "Making history directory #{histdir}"
|
1709
1746
|
FileUtils.mkpath(histdir) if (!@dryrun)
|
1710
1747
|
end
|
1711
|
-
|
1712
|
-
|
1713
|
-
|
1714
|
-
|
1715
|
-
|
1716
|
-
|
1717
|
-
|
1718
|
-
#
|
1719
|
-
|
1720
|
-
# previously but the history log was not started at the same time.
|
1721
|
-
# There are a variety of reasons why this might be the case (the
|
1722
|
-
# original was saved by a previous version of etch that didn't have
|
1723
|
-
# the history log feature, or the original was saved manually by
|
1724
|
-
# someone) but whatever the reason is we want to use the original
|
1725
|
-
# backup to start the history log before updating the history log
|
1726
|
-
# with the current file.
|
1727
|
-
if !File.exist?(histpath) && !@first_update[file]
|
1748
|
+
|
1749
|
+
# If the history log doesn't exist and we didn't just create the original
|
1750
|
+
# backup then that indicates that the original backup was made previously
|
1751
|
+
# but the history log was not started at the same time. There are a
|
1752
|
+
# variety of reasons why this might be the case (the most likely is that
|
1753
|
+
# the original was saved manually by someone) but whatever the reason is
|
1754
|
+
# we want to use the original backup to start the history log before
|
1755
|
+
# updating the history log with the current file.
|
1756
|
+
if !File.exist?(File.join(histdir, 'current')) && !@first_update[file]
|
1728
1757
|
origpath = save_orig(file)
|
1729
1758
|
if File.file?(origpath) && !File.symlink?(origpath)
|
1730
1759
|
puts "Starting history log with saved original file: " +
|
1731
|
-
|
1732
|
-
FileUtils.copy(origpath,
|
1760
|
+
"#{origpath} -> #{current}"
|
1761
|
+
FileUtils.copy(origpath, current) if (!@dryrun)
|
1733
1762
|
else
|
1734
1763
|
puts "Starting history log with 'ls -ld' output for " +
|
1735
|
-
|
1736
|
-
system("ls -ld #{origpath} > #{
|
1737
|
-
end
|
1738
|
-
# Check the newly created history file into RCS
|
1739
|
-
histbase = File.basename(histpath)
|
1740
|
-
puts "Checking initial history log into RCS: #{histpath}"
|
1741
|
-
if !@dryrun
|
1742
|
-
# The -m flag shouldn't be needed, but it won't hurt
|
1743
|
-
# anything and if something is out of sync and an RCS file
|
1744
|
-
# already exists it will prevent ci from going interactive.
|
1745
|
-
system(
|
1746
|
-
"cd #{histdir} && " +
|
1747
|
-
"ci -q -t-'Original of an etch modified file' " +
|
1748
|
-
"-m'Update of an etch modified file' #{histbase} && " +
|
1749
|
-
"co -q -r -kb #{histbase}")
|
1764
|
+
"saved original file: #{origpath} -> #{current}"
|
1765
|
+
system("ls -ld #{origpath} > #{current} 2>&1") if (!@dryrun)
|
1750
1766
|
end
|
1751
1767
|
set_history_permissions(file)
|
1752
1768
|
end
|
1753
|
-
|
1754
|
-
#
|
1755
|
-
|
1756
|
-
# If the file already exists in RCS we need to check out a locked
|
1757
|
-
# copy before updating it
|
1758
|
-
histbase = File.basename(histpath)
|
1759
|
-
rcsstatus = false
|
1760
|
-
if !@dryrun
|
1761
|
-
rcsstatus = system("cd #{histdir} && rlog -R #{histbase} > /dev/null 2>&1")
|
1762
|
-
end
|
1763
|
-
if rcsstatus
|
1764
|
-
# set_history_permissions may set the checked-out file
|
1765
|
-
# writeable, which normally causes co to abort. Thus the -f
|
1766
|
-
# flag.
|
1767
|
-
system("cd #{histdir} && co -q -l -f #{histbase}") if !@dryrun
|
1768
|
-
end
|
1769
|
-
|
1769
|
+
|
1770
|
+
# Make temporary copy of file
|
1771
|
+
newcurrent = current+'.new'
|
1770
1772
|
if File.file?(file) && !File.symlink?(file)
|
1771
|
-
puts "Updating history log: #{file} -> #{
|
1772
|
-
|
1773
|
+
puts "Updating history log: #{file} -> #{current}"
|
1774
|
+
if File.exist?(newcurrent)
|
1775
|
+
remove_file(newcurrent)
|
1776
|
+
end
|
1777
|
+
FileUtils.copy(file, newcurrent) if (!@dryrun)
|
1773
1778
|
else
|
1774
|
-
puts "Updating history log with 'ls -ld' output: "
|
1775
|
-
|
1776
|
-
system("ls -ld #{file} > #{histpath} 2>&1") if (!@dryrun)
|
1779
|
+
puts "Updating history log with 'ls -ld' output: #{file} -> #{current}"
|
1780
|
+
system("ls -ld #{file} > #{newcurrent} 2>&1") if (!@dryrun)
|
1777
1781
|
end
|
1778
|
-
|
1779
|
-
#
|
1780
|
-
|
1781
|
-
|
1782
|
-
|
1783
|
-
|
1784
|
-
|
1785
|
-
|
1786
|
-
|
1787
|
-
|
1788
|
-
|
1789
|
-
|
1790
|
-
|
1782
|
+
|
1783
|
+
# Roll current to next XXXX if current != XXXX
|
1784
|
+
if File.exist?(current)
|
1785
|
+
nextfile = '0000'
|
1786
|
+
maxfile = Dir.entries(histdir).select{|e|e=~/^\d+/}.max
|
1787
|
+
if maxfile
|
1788
|
+
if compare_file_contents(File.join(histdir, maxfile), File.read(current))
|
1789
|
+
nextfile = nil
|
1790
|
+
else
|
1791
|
+
nextfile = sprintf('%04d', maxfile.to_i + 1)
|
1792
|
+
end
|
1793
|
+
end
|
1794
|
+
if nextfile
|
1795
|
+
File.rename(current, File.join(histdir, nextfile)) if (!@dryrun)
|
1796
|
+
end
|
1791
1797
|
end
|
1792
|
-
|
1798
|
+
|
1799
|
+
# Move temporary copy to current
|
1800
|
+
File.rename(current+'.new', current) if (!@dryrun)
|
1801
|
+
|
1793
1802
|
set_history_permissions(file)
|
1794
1803
|
end
|
1795
|
-
|
1804
|
+
|
1796
1805
|
# Ensures that the history log file has appropriate permissions to avoid
|
1797
1806
|
# leaking information.
|
1798
1807
|
def set_history_permissions(file)
|
1799
1808
|
origpath = File.join(@origbase, "#{file}.ORIG")
|
1800
|
-
|
1801
|
-
|
1809
|
+
histdir = File.join(@historybase, "#{file}.HISTORY")
|
1810
|
+
|
1802
1811
|
# We set the permissions to the more restrictive of the original
|
1803
1812
|
# file permissions and the current file permissions.
|
1804
1813
|
origperms = 0777
|
@@ -1813,17 +1822,15 @@ class Etch::Client
|
|
1813
1822
|
# Mask off the file type
|
1814
1823
|
fileperms = st.mode & 07777
|
1815
1824
|
end
|
1816
|
-
|
1817
1825
|
histperms = origperms & fileperms
|
1818
|
-
|
1819
|
-
File.
|
1820
|
-
|
1821
|
-
|
1822
|
-
|
1823
|
-
|
1824
|
-
|
1825
|
-
|
1826
|
-
File.chmod(histperms, histrcspath) if (!@dryrun)
|
1826
|
+
|
1827
|
+
if File.directory?(histdir)
|
1828
|
+
Dir.foreach(histdir) do |histfile|
|
1829
|
+
next if histfile == '.'
|
1830
|
+
next if histfile == '..'
|
1831
|
+
File.chmod(histperms, File.join(histdir, histfile)) if (!@dryrun)
|
1832
|
+
end
|
1833
|
+
end
|
1827
1834
|
end
|
1828
1835
|
|
1829
1836
|
def get_local_requests(file)
|
@@ -2202,8 +2209,10 @@ class Etch::Client
|
|
2202
2209
|
# Note that cp -p will follow symlinks. GNU cp has a -d option to
|
2203
2210
|
# prevent that, but Solaris cp does not, so we resort to cpio.
|
2204
2211
|
# GNU cpio has a --quiet option, but Solaris cpio does not. Sigh.
|
2212
|
+
# GNU find and cpio also have -print0/--null to handle filenames with
|
2213
|
+
# spaces or special characters, but that's not standard either.
|
2205
2214
|
system("cd #{sourcedir} && find #{sourcefile} | cpio -pdum #{destdir}") or
|
2206
|
-
raise "
|
2215
|
+
raise "Recursive copy #{sourcedir}/#{sourcefile} to #{destdir} failed"
|
2207
2216
|
end
|
2208
2217
|
def recursive_copy_and_rename(sourcedir, sourcefile, destname)
|
2209
2218
|
tmpdir = tempdir(destname)
|
@@ -2211,7 +2220,17 @@ class Etch::Client
|
|
2211
2220
|
File.rename(File.join(tmpdir, sourcefile), destname)
|
2212
2221
|
Dir.delete(tmpdir)
|
2213
2222
|
end
|
2214
|
-
|
2223
|
+
def nonrecursive_copy(sourcedir, sourcefile, destdir)
|
2224
|
+
system("cd #{sourcedir} && echo #{sourcefile} | cpio -pdum #{destdir}") or
|
2225
|
+
raise "Non-recursive copy #{sourcedir}/#{sourcefile} to #{destdir} failed"
|
2226
|
+
end
|
2227
|
+
def nonrecursive_copy_and_rename(sourcedir, sourcefile, destname)
|
2228
|
+
tmpdir = tempdir(destname)
|
2229
|
+
nonrecursive_copy(sourcedir, sourcefile, tmpdir)
|
2230
|
+
File.rename(File.join(tmpdir, sourcefile), destname)
|
2231
|
+
Dir.delete(tmpdir)
|
2232
|
+
end
|
2233
|
+
|
2215
2234
|
def lock_file(file)
|
2216
2235
|
lockpath = File.join(@lockbase, "#{file}.LOCK")
|
2217
2236
|
|
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: 3.15.0
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Jason Heiss
|
@@ -9,7 +9,7 @@ autorequire:
|
|
9
9
|
bindir: bin
|
10
10
|
cert_chain: []
|
11
11
|
|
12
|
-
date:
|
12
|
+
date: 2010-01-20 00:00:00 -08:00
|
13
13
|
default_executable:
|
14
14
|
dependencies:
|
15
15
|
- !ruby/object:Gem::Dependency
|
@@ -36,12 +36,9 @@ files:
|
|
36
36
|
- bin/etch
|
37
37
|
- bin/etch_cron_wrapper
|
38
38
|
- bin/etch_to_trunk
|
39
|
-
- etc/ca.pem
|
40
|
-
- etc/dhparams
|
41
39
|
- lib/etch.rb
|
42
40
|
- lib/etchclient.rb
|
43
41
|
- lib/versiontype.rb
|
44
|
-
- man/man8/etch.8
|
45
42
|
- Rakefile
|
46
43
|
has_rdoc: true
|
47
44
|
homepage: http://etch.sourceforge.net
|
@@ -67,7 +64,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
|
|
67
64
|
requirements: []
|
68
65
|
|
69
66
|
rubyforge_project: etchsyscm
|
70
|
-
rubygems_version: 1.3.
|
67
|
+
rubygems_version: 1.3.5
|
71
68
|
signing_key:
|
72
69
|
specification_version: 3
|
73
70
|
summary: Etch system configuration management client
|
data/etc/ca.pem
DELETED
@@ -1 +0,0 @@
|
|
1
|
-
# Add your SSL certificate authority's cert(s) to this file
|
data/etc/dhparams
DELETED
@@ -1,9 +0,0 @@
|
|
1
|
-
-----BEGIN DH PARAMETERS-----
|
2
|
-
MIIBCAKCAQEA3HySq1WdL67BCSRCJCZYMUIojAWAsvK63D3cOGk0wI9UeM/yeVhz
|
3
|
-
jTswvHOVPZFKIBg1Aeo2eAEdPryDnmjVTgvLbuWkCPouQhBCVsQ1El9ZcXPix1rC
|
4
|
-
tYsg4Kll1jgnwFoHf4xvjPnD/SqsASAiDxYlh4CFVyT1gLgSiUU0rIdudgO3agI5
|
5
|
-
NgiyGOKwyHmNOOQSKA62M/JnoxcBDC7Nou3lqtHpR5yWsUz+csyk+hXZeUba97bm
|
6
|
-
M8OB0PmfK4Vo6JpdO+yc8hjeYBoMsH7g/l3Gm1JqUxxctcY/OuJ+2nkXwsD66E3D
|
7
|
-
yZCoiVd3u4OqAxNO/GG0iUmskjIvokMhUwIBAg==
|
8
|
-
-----END DH PARAMETERS-----
|
9
|
-
|
data/man/man8/etch.8
DELETED
@@ -1,204 +0,0 @@
|
|
1
|
-
.TH etch 8 "October 2009"
|
2
|
-
|
3
|
-
.SH NAME
|
4
|
-
|
5
|
-
.B etch
|
6
|
-
\- Configuration management for Unix systems
|
7
|
-
|
8
|
-
.SH SYNOPSIS
|
9
|
-
|
10
|
-
.B etch
|
11
|
-
.RB [ --generate-all ]
|
12
|
-
.RB [ --dry-run | \-n ]
|
13
|
-
.RB [ --damp-run ]
|
14
|
-
.RB [ --interactive ]
|
15
|
-
.RB [ --full-file ]
|
16
|
-
.RB [ --filename-only ]
|
17
|
-
.RB [ --disable-force ]
|
18
|
-
.RB [ --lock-force ]
|
19
|
-
.RB [ --debug ]
|
20
|
-
.RB [ --local
|
21
|
-
.IR DIR ]
|
22
|
-
.RB [ --server
|
23
|
-
.IR SERVER ]
|
24
|
-
.RB [ --tag
|
25
|
-
.IR TAG ]
|
26
|
-
.RB [ --test-base
|
27
|
-
.IR TESTDIR ]
|
28
|
-
.RB [ --key
|
29
|
-
.IR PRIVATE_KEY ]
|
30
|
-
.RB [ --version ]
|
31
|
-
.RB [ --help | \-h ]
|
32
|
-
.RI [ "file ..." ]
|
33
|
-
|
34
|
-
.SH DESCRIPTION
|
35
|
-
|
36
|
-
Etch is a tool for managing the configuration of Unix systems. Etch can manage
|
37
|
-
text or binary files, links and directories. The contents of files can be
|
38
|
-
supplied from static files or generated on the fly by scripts or templates.
|
39
|
-
Permissions and ownership as well as any pre or post commands to run when
|
40
|
-
updating the file are configured in simple XML files.
|
41
|
-
|
42
|
-
.SH OPTIONS
|
43
|
-
.TP
|
44
|
-
.B --generate-all
|
45
|
-
Request that the server generate and send over all available configuration.
|
46
|
-
Can be used instead of specifying specific files to request.
|
47
|
-
.TP
|
48
|
-
.B --dry-run | \-n
|
49
|
-
.B etch
|
50
|
-
will not make any changes to the system. Contents of generated config
|
51
|
-
files are displayed instead of being written to disk.
|
52
|
-
.TP
|
53
|
-
.B --damp-run
|
54
|
-
Perform an almost dry run, except that 'setup' entries for files are run.
|
55
|
-
Normally all setup/pre/post entries are ignored for a dry run. However, files
|
56
|
-
with setup entries will generally fail to build properly if the setup entry
|
57
|
-
hasn't been run. This allows you to preview the full and correct
|
58
|
-
configuration while making minimal changes to the system.
|
59
|
-
.TP
|
60
|
-
.B --interactive
|
61
|
-
Causes
|
62
|
-
.B etch
|
63
|
-
to pause before making each change and prompt the user for
|
64
|
-
confirmation.
|
65
|
-
.TP
|
66
|
-
.B --full-file
|
67
|
-
Normally
|
68
|
-
.B etch
|
69
|
-
will print a diff to show what changes it will make to a file. This will cause
|
70
|
-
.B etch
|
71
|
-
to display the full new file contents instead. Useful if the diff is hard to
|
72
|
-
read for a particular file.
|
73
|
-
.TP
|
74
|
-
.B --filename-only
|
75
|
-
Normally
|
76
|
-
.B etch
|
77
|
-
will print a diff to show what changes it will make to a file. This will cause
|
78
|
-
etch to display only the name of file to be changed. Useful on the initial
|
79
|
-
run during your system build process or other times when you want less output.
|
80
|
-
.TP
|
81
|
-
.B --disable-force
|
82
|
-
Ignore the disable_etch file. Use with caution. Typically used with
|
83
|
-
--interactive or --dry-run to evaluate what would happen if etch were
|
84
|
-
re-enabled.
|
85
|
-
.TP
|
86
|
-
.B --lock-force
|
87
|
-
.B Etch
|
88
|
-
does per-file internal locking as it runs to prevent problems with
|
89
|
-
simultaneous instances of the
|
90
|
-
.B etch
|
91
|
-
client stepping on each other.
|
92
|
-
.B Etch
|
93
|
-
automatically cleans up lockfiles over two hours old on the assumption that
|
94
|
-
any lockfiles that old were left behind by a previous instance that failed for
|
95
|
-
some (hopefully transient) reason. In a large environment you don't want to
|
96
|
-
have to run around manually cleaning up lockfiles every time a full disk or
|
97
|
-
unavailable package server or other transient failure causes
|
98
|
-
.B etch
|
99
|
-
to fail
|
100
|
-
temporarily. This option forces the removal of any existing lockfiles no
|
101
|
-
matter how old. Useful if a buggy configuration or local environmental issue
|
102
|
-
caused
|
103
|
-
.B etch
|
104
|
-
to abort and you want to immediately retry.
|
105
|
-
.TP
|
106
|
-
.BI --local " DIR"
|
107
|
-
Read configuration from a local directory rather than requesting it from
|
108
|
-
a server.
|
109
|
-
.TP
|
110
|
-
.BI --server " SERVER"
|
111
|
-
Point
|
112
|
-
.B etch
|
113
|
-
to an alternate server, specified in the form of a URL.
|
114
|
-
.TP
|
115
|
-
.BI --tag " TAG"
|
116
|
-
Request a specific repository tag from the server. Tags are directory paths
|
117
|
-
relative to /etc/etchserver by default. Thus examples might be
|
118
|
-
.I trunk
|
119
|
-
for /etc/etchserver/trunk, or
|
120
|
-
.I branches/mytestbranch
|
121
|
-
for /etc/etchserver/branches/mytestbranch.
|
122
|
-
.TP
|
123
|
-
.BI --key " PRIVATE_KEY"
|
124
|
-
Use an alternate SSH private key file for signing messages that are sent to
|
125
|
-
the server.
|
126
|
-
.TP
|
127
|
-
.BI --test-base " TESTDIR"
|
128
|
-
Use an alternate local working directory instead of /var/etch. Generally only
|
129
|
-
used for allowing the etch test suite to be run as a non-root user.
|
130
|
-
.TP
|
131
|
-
.B --debug
|
132
|
-
Print lots of messages about what etch is doing.
|
133
|
-
.TP
|
134
|
-
.B --version
|
135
|
-
Show the etch client version and exit.
|
136
|
-
.TP
|
137
|
-
.B --help | \-h
|
138
|
-
Display the etch usage message and exit.
|
139
|
-
|
140
|
-
.SH FILES
|
141
|
-
|
142
|
-
.TP
|
143
|
-
.B /etc/etch/ca.pem
|
144
|
-
SSL certificate(s) needed to verify the
|
145
|
-
.B etch
|
146
|
-
server's identity. If
|
147
|
-
.B etch
|
148
|
-
is using a server with an https:// URL and if this file exists then
|
149
|
-
.B etch
|
150
|
-
will not proceed if the server's SSL certificate can't be verified against the
|
151
|
-
certs in this file.
|
152
|
-
.TP
|
153
|
-
.B /etc/etch/dhparams
|
154
|
-
The Diffie-Hellman parameters used as part of the SSL connection process. Etch
|
155
|
-
comes with a set and there's no need to generate your own, but a new set can
|
156
|
-
be generated via "openssl dhparam" if desired. If this file is not present the
|
157
|
-
Ruby SSL library will warn that it is using its internal default set of
|
158
|
-
parameters.
|
159
|
-
.TP
|
160
|
-
.B /var/etch/disable_etch
|
161
|
-
If this file is present
|
162
|
-
.B etch
|
163
|
-
will do nothing other than send a message to the
|
164
|
-
.B etch
|
165
|
-
server that it is disabled. Any text in this file will be included in
|
166
|
-
that message to the server and displayed locally. If you are disabling
|
167
|
-
.B etch
|
168
|
-
always put a note in this file indicating who you are, today's date, and why
|
169
|
-
you are disabling
|
170
|
-
.B etch
|
171
|
-
so that fellow administrators won't have to guess later why
|
172
|
-
.B etch
|
173
|
-
was disabled. Re-enabling
|
174
|
-
.B etch
|
175
|
-
after it has been disabled for a long
|
176
|
-
time can be time-consuming, as the person doing so must review any potential
|
177
|
-
changes that have been queued up and ensure that they won't interfere with the
|
178
|
-
current usage of the system. As such be thoughtful about whether disabling
|
179
|
-
.B etch
|
180
|
-
is necessary, and re-enable it as soon as possible.
|
181
|
-
.TP
|
182
|
-
.B /var/etch/history
|
183
|
-
A revision history of each
|
184
|
-
.B etch
|
185
|
-
managed file, stored using the RCS revision control system.
|
186
|
-
.TP
|
187
|
-
.B /var/etch/locks
|
188
|
-
Directory used by the
|
189
|
-
.B etch
|
190
|
-
internal locking mechanism. See the --lock-force option for more details.
|
191
|
-
.TP
|
192
|
-
.B /var/etch/orig
|
193
|
-
A backup of the original contents of each
|
194
|
-
.B etch
|
195
|
-
managed file as it was before etch first touched it.
|
196
|
-
|
197
|
-
.SH DIAGNOSTICS
|
198
|
-
|
199
|
-
See the --debug option and the server logs.
|
200
|
-
|
201
|
-
.SH AUTHOR
|
202
|
-
|
203
|
-
.B Etch
|
204
|
-
is designed and maintained by Jason Heiss
|