etch 3.16.0 → 3.17.0

Sign up to get free protection for your applications and to get access to all the features.
Files changed (5) hide show
  1. data/Rakefile +1 -1
  2. data/bin/etch +5 -2
  3. data/bin/etch_to_trunk +31 -7
  4. data/lib/etchclient.rb +75 -16
  5. metadata +26 -9
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.16.0'
6
+ s.version = '3.17.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/bin/etch CHANGED
@@ -16,6 +16,9 @@ require 'etchclient'
16
16
  options = {}
17
17
  @generateall = nil
18
18
 
19
+ # Extra options to OptionParser reduce the amount of whitespace it introduces
20
+ # into the help message, making it easier to make the help message fit in a
21
+ # 80x24 window.
19
22
  opts = OptionParser.new(nil, 24, ' ')
20
23
  opts.banner = 'Usage: etch [options] [/path/to/config/file | command] [otherfile ...]'
21
24
  opts.on('--generate-all', 'Request all configuration.') do |opt|
@@ -59,8 +62,8 @@ end
59
62
  opts.on('--key PRIVATE_KEY', 'Use this private key for signing messages to server.') do |opt|
60
63
  options[:key] = opt
61
64
  end
62
- opts.on('--test-base TESTDIR', 'Use an alternate local working directory.') do |opt|
63
- options[:varbase] = opt
65
+ opts.on('--test-root TESTDIR', 'For use by the test suite only.') do |opt|
66
+ options[:file_system_root] = opt
64
67
  end
65
68
  opts.on('--debug', 'Print lots of messages about what etch is doing.') do |opt|
66
69
  options[:debug] = opt
data/bin/etch_to_trunk CHANGED
@@ -1,21 +1,45 @@
1
1
  #!/usr/bin/ruby -w
2
2
 
3
3
  require 'nventory'
4
+ require 'time'
5
+ require 'optparse'
4
6
 
5
- @username = ENV['LOGNAME']
7
+ ETCH_SERVER_TZ = 'UTC' # The etch servers run in UTC
8
+
9
+ options = {}
10
+ opts = OptionParser.new
11
+ opts.banner = 'Usage: etch_to_trunk [options] <server1> [<server2> <server3>]'
12
+ opts.on('-u', '--username USERNAME', 'Username for connecting to nventory server.') do |opt|
13
+ options[:username] = opt
14
+ end
15
+ opts.on('-t', '--timezone TIMEZONE', 'Time zone of etch server.') do |opt|
16
+ options[:timezone] = opt
17
+ end
18
+ opts.on_tail('-h', '--help', 'Show this message.') do
19
+ puts opts
20
+ exit
21
+ end
22
+
23
+ nodes = opts.parse(ARGV)
6
24
 
7
25
  if ARGV.length == 0
8
- abort "Usage: #{File.basename($0)} <server1> [<server2> <server3>]"
26
+ puts opts
27
+ exit
9
28
  end
10
29
 
11
- # The etch servers run in UTC
12
- ENV['TZ'] = 'UTC'
13
- currentheadtag = Time.now.strftime('trunk-%Y%m%d-%H00')
30
+ @username = options[:username] || ENV['LOGNAME']
31
+ etch_server_tz = options[:timezone] || ETCH_SERVER_TZ
32
+
33
+ if etch_server_tz
34
+ currentheadtag = Time.at(Time.now.utc + Time.zone_offset(etch_server_tz)).strftime('trunk-%Y%m%d-%H00')
35
+ else # if no timezone is specified then just use local time for the tag
36
+ currentheadtag = Time.now.strftime('trunk-%Y%m%d-%H00')
37
+ end
14
38
 
15
39
  # Find the requested clients
16
40
  nvclient = NVentory::Client.new
17
- results = nvclient.get_objects('nodes', {}, { 'name' => ARGV }, {}, {})
18
- ARGV.each do |name|
41
+ results = nvclient.get_objects('nodes', {}, { 'name' => nodes }, {}, {})
42
+ nodes.each do |name|
19
43
  if results.empty? && results[name].nil?
20
44
  abort "No entry found for #{name}"
21
45
  else
data/lib/etchclient.rb CHANGED
@@ -35,13 +35,14 @@ require 'logger'
35
35
  require 'etch'
36
36
 
37
37
  class Etch::Client
38
- VERSION = '3.16.0'
38
+ VERSION = '3.17.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
+ DEFAULT_CONFIGDIR = '/etc'
45
+ DEFAULT_VARBASE = '/var/etch'
45
46
 
46
47
  # We need these in relation to the output capturing
47
48
  ORIG_STDOUT = STDOUT.dup
@@ -52,7 +53,6 @@ class Etch::Client
52
53
  def initialize(options)
53
54
  @server = options[:server] ? options[:server] : 'https://etch'
54
55
  @tag = options[:tag]
55
- @varbase = options[:varbase] ? options[:varbase] : '/var/etch'
56
56
  @local = options[:local] ? File.expand_path(options[:local]) : nil
57
57
  @debug = options[:debug]
58
58
  @dryrun = options[:dryrun]
@@ -63,10 +63,72 @@ class Etch::Client
63
63
  @disableforce = options[:disableforce]
64
64
  @lockforce = options[:lockforce]
65
65
 
66
- # Ensure we have a sane path, particularly since we are often run from
67
- # cron.
68
- # FIXME: Read from config file
69
- ENV['PATH'] = '/bin:/usr/bin:/sbin:/usr/sbin:/opt/csw/bin:/opt/csw/sbin'
66
+ @configdir = DEFAULT_CONFIGDIR
67
+ @varbase = DEFAULT_VARBASE
68
+
69
+ @file_system_root = '/' # Not sure if this needs to be more portable
70
+ # This option is only intended for use by the test suite
71
+ if options[:file_system_root]
72
+ @file_system_root = options[:file_system_root]
73
+ @varbase = File.join(@file_system_root, @varbase)
74
+ @configdir = File.join(@file_system_root, @configdir)
75
+ end
76
+
77
+ @configfile = File.join(@configdir, 'etch.conf')
78
+
79
+ if File.exist?(@configfile)
80
+ IO.foreach(@configfile) do |line|
81
+ line.chomp!
82
+ next if (line =~ /^\s*$/); # Skip blank lines
83
+ next if (line =~ /^\s*#/); # Skip comments
84
+ line.strip! # Remove leading/trailing whitespace
85
+ key, value = line.split(/\s*=\s*/, 2)
86
+ if key == 'server'
87
+ # A setting for the server to use which comes from upstream
88
+ # (generally from a command line option) takes precedence
89
+ # over the config file
90
+ if !options[:server]
91
+ @server = value
92
+ # Warn the user, as this could potentially be confusing
93
+ # if they don't realize there's a config file lying
94
+ # around
95
+ warn "Using server #{@server} from #{@configfile}" if @debug
96
+ else
97
+ # "command line override" isn't necessarily accurate, we don't
98
+ # know why the caller passed us an option to override the config
99
+ # file, but most of the time it will be due to a command line
100
+ # option and I want the message to be easily understood by users.
101
+ # If someone can come up with some better wording without turning
102
+ # the message into something as long as this comment that would be
103
+ # welcome.
104
+ warn "Ignoring 'server' option in #{@configfile} due to command line override" if @debug
105
+ end
106
+ elsif key == 'local'
107
+ if !options[:local] && !options[:server]
108
+ @local = value
109
+ warn "Using local directory #{@local} from #{@configfile}" if @debug
110
+ else
111
+ warn "Ignoring 'local' option in #{@configfile} due to command line override" if @debug
112
+ end
113
+ elsif key == 'key'
114
+ if !options[:key]
115
+ @key = value
116
+ warn "Using key #{@key} from #{@configfile}" if @debug
117
+ else
118
+ warn "Ignoring 'key' option in #{@configfile} due to command line override" if @debug
119
+ end
120
+ elsif key == 'path'
121
+ ENV['PATH'] = value
122
+ end
123
+ end
124
+ end
125
+
126
+ if @key && !File.readable?(@key)
127
+ @key = nil
128
+ end
129
+ if !@key
130
+ warn "No readable private key found, messages to server will not be signed and may be rejected depending on server configuration"
131
+ end
70
132
 
71
133
  @origbase = File.join(@varbase, 'orig')
72
134
  @historybase = File.join(@varbase, 'history')
@@ -141,17 +203,17 @@ class Etch::Client
141
203
  http = Net::HTTP.new(@filesuri.host, @filesuri.port)
142
204
  if @filesuri.scheme == "https"
143
205
  # Eliminate the OpenSSL "using default DH parameters" warning
144
- if File.exist?(File.join(CONFIGDIR, 'etch', 'dhparams'))
145
- dh = OpenSSL::PKey::DH.new(IO.read(File.join(CONFIGDIR, 'etch', 'dhparams')))
206
+ if File.exist?(File.join(@configdir, 'etch', 'dhparams'))
207
+ dh = OpenSSL::PKey::DH.new(IO.read(File.join(@configdir, 'etch', 'dhparams')))
146
208
  Net::HTTP.ssl_context_accessor(:tmp_dh_callback)
147
209
  http.tmp_dh_callback = proc { dh }
148
210
  end
149
211
  http.use_ssl = true
150
- if File.exist?(File.join(CONFIGDIR, 'etch', 'ca.pem'))
151
- http.ca_file = File.join(CONFIGDIR, 'etch', 'ca.pem')
212
+ if File.exist?(File.join(@configdir, 'etch', 'ca.pem'))
213
+ http.ca_file = File.join(@configdir, 'etch', 'ca.pem')
152
214
  http.verify_mode = OpenSSL::SSL::VERIFY_PEER
153
- elsif File.directory?(File.join(CONFIGDIR, 'etch', 'ca'))
154
- http.ca_path = File.join(CONFIGDIR, 'etch', 'ca')
215
+ elsif File.directory?(File.join(@configdir, 'etch', 'ca'))
216
+ http.ca_path = File.join(@configdir, 'etch', 'ca')
155
217
  http.verify_mode = OpenSSL::SSL::VERIFY_PEER
156
218
  end
157
219
  end
@@ -2409,9 +2471,6 @@ class Etch::Client
2409
2471
  break
2410
2472
  end
2411
2473
  end
2412
- if !key
2413
- warn "No readable private key found, messages to server will not be signed and may be rejected depending on server configuration"
2414
- end
2415
2474
  key
2416
2475
  end
2417
2476
 
metadata CHANGED
@@ -1,7 +1,13 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: etch
3
3
  version: !ruby/object:Gem::Version
4
- version: 3.16.0
4
+ hash: 67
5
+ prerelease: false
6
+ segments:
7
+ - 3
8
+ - 17
9
+ - 0
10
+ version: 3.17.0
5
11
  platform: ruby
6
12
  authors:
7
13
  - Jason Heiss
@@ -9,19 +15,23 @@ autorequire:
9
15
  bindir: bin
10
16
  cert_chain: []
11
17
 
12
- date: 2010-08-12 00:00:00 -07:00
18
+ date: 2010-12-22 00:00:00 -08:00
13
19
  default_executable:
14
20
  dependencies:
15
21
  - !ruby/object:Gem::Dependency
16
22
  name: facter
17
- type: :runtime
18
- version_requirement:
19
- version_requirements: !ruby/object:Gem::Requirement
23
+ prerelease: false
24
+ requirement: &id001 !ruby/object:Gem::Requirement
25
+ none: false
20
26
  requirements:
21
27
  - - ">="
22
28
  - !ruby/object:Gem::Version
29
+ hash: 3
30
+ segments:
31
+ - 0
23
32
  version: "0"
24
- version:
33
+ type: :runtime
34
+ version_requirements: *id001
25
35
  description:
26
36
  email: etch-users@lists.sourceforge.net
27
37
  executables:
@@ -50,21 +60,28 @@ rdoc_options: []
50
60
  require_paths:
51
61
  - lib
52
62
  required_ruby_version: !ruby/object:Gem::Requirement
63
+ none: false
53
64
  requirements:
54
65
  - - ">="
55
66
  - !ruby/object:Gem::Version
67
+ hash: 31
68
+ segments:
69
+ - 1
70
+ - 8
56
71
  version: "1.8"
57
- version:
58
72
  required_rubygems_version: !ruby/object:Gem::Requirement
73
+ none: false
59
74
  requirements:
60
75
  - - ">="
61
76
  - !ruby/object:Gem::Version
77
+ hash: 3
78
+ segments:
79
+ - 0
62
80
  version: "0"
63
- version:
64
81
  requirements: []
65
82
 
66
83
  rubyforge_project: etchsyscm
67
- rubygems_version: 1.3.5
84
+ rubygems_version: 1.3.7
68
85
  signing_key:
69
86
  specification_version: 3
70
87
  summary: Etch system configuration management client