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.
Files changed (6) hide show
  1. data/Rakefile +1 -1
  2. data/lib/etchclient.rb +127 -108
  3. metadata +3 -6
  4. data/etc/ca.pem +0 -1
  5. data/etc/dhparams +0 -9
  6. 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.13'
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.13'
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/etch'
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
- # Now remove the backed-up original so that future runs
581
- # don't do anything
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
- histpath = File.join(@historybase, "#{file}.HISTORY")
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
- histdir = File.dirname(histpath)
1707
- if !File.directory?(histdir)
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
- # Make sure the corresponding RCS directory exists as well.
1712
- histrcsdir = File.join(histdir, 'RCS')
1713
- if !File.directory?(histrcsdir)
1714
- puts "Making directory tree #{histrcsdir}"
1715
- FileUtils.mkpath(histrcsdir) if (!@dryrun)
1716
- end
1717
-
1718
- # If the history log doesn't exist and we didn't just create the
1719
- # original backup, that indicates that the original backup was made
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
- "#{origpath} -> #{histpath}"
1732
- FileUtils.copy(origpath, histpath) if (!@dryrun)
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
- "saved original file: #{origpath} -> #{histpath}"
1736
- system("ls -ld #{origpath} > #{histpath} 2>&1") if (!@dryrun)
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
- # Copy current file
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} -> #{histpath}"
1772
- FileUtils.copy(file, histpath) if (!@dryrun)
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
- "#{histpath}"
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
- # Check the history file into RCS
1780
- puts "Checking history log update into RCS: #{histpath}"
1781
- if !@dryrun
1782
- # We only need one of the -t or -m flags depending on whether
1783
- # the history log already exists or not, rather than try to
1784
- # keep track of which one we need just specify both and let RCS
1785
- # pick the one it needs.
1786
- system(
1787
- "cd #{histdir} && " +
1788
- "ci -q -t-'Original of an etch modified file' " +
1789
- "-m'Update of an etch modified file' #{histbase} && " +
1790
- "co -q -r -kb #{histbase}")
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
- histpath = File.join(@historybase, "#{file}.HISTORY")
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.chmod(histperms, histpath) if (!@dryrun)
1820
-
1821
- # Set the permissions on the RCS file too
1822
- histbase = File.basename(histpath)
1823
- histdir = File.dirname(histpath)
1824
- histrcsdir = "#{histdir}/RCS"
1825
- histrcspath = "#{histrcsdir}/#{histbase},v"
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 "Copy #{sourcedir}/#{sourcefile} to #{destdir} failed"
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: "3.13"
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: 2009-11-14 00:00:00 -08:00
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.4
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