etch 3.16.0 → 3.17.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/bin/etch +5 -2
 - data/bin/etch_to_trunk +31 -7
 - data/lib/etchclient.rb +75 -16
 - 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. 
     | 
| 
      
 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- 
     | 
| 
       63 
     | 
    
         
            -
              options[: 
     | 
| 
      
 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 
     | 
    
         
            -
             
     | 
| 
      
 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 
     | 
    
         
            -
               
     | 
| 
      
 26 
     | 
    
         
            +
              puts opts
         
     | 
| 
      
 27 
     | 
    
         
            +
              exit
         
     | 
| 
       9 
28 
     | 
    
         
             
            end
         
     | 
| 
       10 
29 
     | 
    
         | 
| 
       11 
     | 
    
         
            -
             
     | 
| 
       12 
     | 
    
         
            -
             
     | 
| 
       13 
     | 
    
         
            -
             
     | 
| 
      
 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' =>  
     | 
| 
       18 
     | 
    
         
            -
             
     | 
| 
      
 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. 
     | 
| 
      
 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 
     | 
    
         
            -
               
     | 
| 
      
 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 
     | 
    
         
            -
                 
     | 
| 
       67 
     | 
    
         
            -
                 
     | 
| 
       68 
     | 
    
         
            -
                 
     | 
| 
       69 
     | 
    
         
            -
                 
     | 
| 
      
 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( 
     | 
| 
       145 
     | 
    
         
            -
                      dh = OpenSSL::PKey::DH.new(IO.read(File.join( 
     | 
| 
      
 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( 
     | 
| 
       151 
     | 
    
         
            -
                      http.ca_file = File.join( 
     | 
| 
      
 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( 
     | 
| 
       154 
     | 
    
         
            -
                      http.ca_path = File.join( 
     | 
| 
      
 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 
     | 
    
         
            -
               
     | 
| 
      
 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- 
     | 
| 
      
 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 
     | 
    
         
            -
               
     | 
| 
       18 
     | 
    
         
            -
               
     | 
| 
       19 
     | 
    
         
            -
             
     | 
| 
      
 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 
     | 
    
         
            -
             
     | 
| 
      
 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. 
     | 
| 
      
 84 
     | 
    
         
            +
            rubygems_version: 1.3.7
         
     | 
| 
       68 
85 
     | 
    
         
             
            signing_key: 
         
     | 
| 
       69 
86 
     | 
    
         
             
            specification_version: 3
         
     | 
| 
       70 
87 
     | 
    
         
             
            summary: Etch system configuration management client
         
     |