You can subscribe to this list here.
2008 |
Jan
|
Feb
|
Mar
|
Apr
|
May
|
Jun
|
Jul
|
Aug
|
Sep
|
Oct
|
Nov
(2) |
Dec
|
---|---|---|---|---|---|---|---|---|---|---|---|---|
2009 |
Jan
(3) |
Feb
(15) |
Mar
|
Apr
(9) |
May
|
Jun
(6) |
Jul
|
Aug
|
Sep
(23) |
Oct
(25) |
Nov
(44) |
Dec
(9) |
2010 |
Jan
(14) |
Feb
|
Mar
(4) |
Apr
(1) |
May
|
Jun
(3) |
Jul
|
Aug
(4) |
Sep
|
Oct
(10) |
Nov
(4) |
Dec
(22) |
2011 |
Jan
(14) |
Feb
|
Mar
(3) |
Apr
(7) |
May
(16) |
Jun
(4) |
Jul
(6) |
Aug
(3) |
Sep
|
Oct
(4) |
Nov
|
Dec
|
2012 |
Jan
|
Feb
|
Mar
(10) |
Apr
(24) |
May
|
Jun
|
Jul
(2) |
Aug
(2) |
Sep
|
Oct
|
Nov
|
Dec
|
From: <th...@us...> - 2011-07-07 22:52:48
|
Revision: 293 http://etch.svn.sourceforge.net/etch/?rev=293&view=rev Author: thepob Date: 2011-07-07 22:52:42 +0000 (Thu, 07 Jul 2011) Log Message: ----------- updating client so fact values are converted to strings as they are done in client/server mode - ticket 16 Modified Paths: -------------- trunk/client/lib/etch/client.rb Modified: trunk/client/lib/etch/client.rb =================================================================== --- trunk/client/lib/etch/client.rb 2011-06-01 16:39:39 UTC (rev 292) +++ trunk/client/lib/etch/client.rb 2011-07-07 22:52:42 UTC (rev 293) @@ -169,6 +169,10 @@ else dlogger.level = Logger::INFO end + blankrequest = {} + @facts.each_pair { |key, value| blankrequest[key] = value.to_s } + blankrequest['fqdn'] = @facts['fqdn'] + @facts = blankrequest @etch = Etch.new(logger, dlogger) else # Make sure the server URL ends in a / so that we can append paths This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site. |
From: <jh...@us...> - 2011-06-01 16:39:45
|
Revision: 292 http://etch.svn.sourceforge.net/etch/?rev=292&view=rev Author: jheiss Date: 2011-06-01 16:39:39 +0000 (Wed, 01 Jun 2011) Log Message: ----------- Make nokogiri the default XML library instead of libxml Modified Paths: -------------- trunk/server/lib/etch.rb Modified: trunk/server/lib/etch.rb =================================================================== --- trunk/server/lib/etch.rb 2011-06-01 16:39:16 UTC (rev 291) +++ trunk/server/lib/etch.rb 2011-06-01 16:39:39 UTC (rev 292) @@ -27,14 +27,14 @@ # or the other, mostly for testing purposes. Silently.silently do begin - if !ENV['xmllib'] || ENV['xmllib'] == 'libxml' + if !ENV['xmllib'] || ENV['xmllib'] == 'nokogiri' + require 'rubygems' # nokogiri is a gem + require 'nokogiri' + Etch.xmllib = :nokogiri + elsif ENV['xmllib'] == 'libxml' require 'rubygems' # libxml is a gem require 'libxml' Etch.xmllib = :libxml - elsif ENV['xmllib'] == 'nokogiri' - require 'rubygems' # nokogiri is a gem - require 'nokogiri' - Etch.xmllib = :nokogiri else raise LoadError end This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site. |
From: <jh...@us...> - 2011-06-01 16:39:22
|
Revision: 291 http://etch.svn.sourceforge.net/etch/?rev=291&view=rev Author: jheiss Date: 2011-06-01 16:39:16 +0000 (Wed, 01 Jun 2011) Log Message: ----------- Document the new --configdir and --vardir options. Update the --test-root (formerly --test-base) option documentation. Modified Paths: -------------- trunk/client/man/man8/etch.8 Modified: trunk/client/man/man8/etch.8 =================================================================== --- trunk/client/man/man8/etch.8 2011-06-01 16:38:06 UTC (rev 290) +++ trunk/client/man/man8/etch.8 2011-06-01 16:39:16 UTC (rev 291) @@ -23,6 +23,10 @@ .IR SERVER ] .RB [ --tag .IR TAG ] +.RB [ --configdir +.IR CONFIGDIR ] +.RB [ --vardir +.IR VARDIR ] .RB [ --test-base .IR TESTDIR ] .RB [ --key @@ -124,10 +128,18 @@ Use an alternate SSH private key file for signing messages that are sent to the server. .TP -.BI --test-base " TESTDIR" -Use an alternate local working directory instead of /var/etch. Generally only -used for allowing the etch test suite to be run as a non-root user. +.BI --configdir " CONFIGDIR" +Use an alternate configuration directory instead of /etc. This is the +location of etch.conf and other configuration files. See FILES. .TP +.BI --vardir " VARDIR" +Use an alternate local working directory instead of /var/etch. See FILES. +.TP +.BI --test-root " TESTDIR" +Places the config and var directories relative to a test root directory. +Generally only used for allowing the etch test suite to be run as a non-root +user. +.TP .B --debug Print lots of messages about what etch is doing. .TP This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site. |
From: <jh...@us...> - 2011-06-01 16:38:13
|
Revision: 290 http://etch.svn.sourceforge.net/etch/?rev=290&view=rev Author: jheiss Date: 2011-06-01 16:38:06 +0000 (Wed, 01 Jun 2011) Log Message: ----------- Mentioned the defaults for the config and var directories in the help message. Modified Paths: -------------- trunk/client/bin/etch Modified: trunk/client/bin/etch =================================================================== --- trunk/client/bin/etch 2011-06-01 01:04:21 UTC (rev 289) +++ trunk/client/bin/etch 2011-06-01 16:38:06 UTC (rev 290) @@ -69,10 +69,10 @@ opts.on('--key PRIVATE_KEY', 'Use this private key for signing messages to server.') do |opt| options[:key] = opt end -opts.on('--configdir DIR', 'Directory containing etch.conf.') do |opt| +opts.on('--configdir DIR', 'Directory containing etch.conf, defaults to /etc') do |opt| options[:configdir] = opt end -opts.on('--vardir DIR', 'Directory for etch state and logs.') do |opt| +opts.on('--vardir DIR', 'Directory for etch state, defaults to /var/etch') do |opt| options[:vardir] = opt end opts.on('--test-root TESTDIR', 'For use by the test suite only.') do |opt| This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site. |
From: <jh...@us...> - 2011-06-01 01:04:27
|
Revision: 289 http://etch.svn.sourceforge.net/etch/?rev=289&view=rev Author: jheiss Date: 2011-06-01 01:04:21 +0000 (Wed, 01 Jun 2011) Log Message: ----------- Change varbase to vardir, to match configdir. Having configdir and varbase seemed odd in retrospect. Make configdir and vardir configurable via command-line options. Suggestion from Nate Johnston. Add additional debugging statement about the server URL in use. Suggestion from Nate Johnston. Modified Paths: -------------- trunk/client/bin/etch trunk/client/lib/etch/client.rb Modified: trunk/client/bin/etch =================================================================== --- trunk/client/bin/etch 2011-05-19 17:55:25 UTC (rev 288) +++ trunk/client/bin/etch 2011-06-01 01:04:21 UTC (rev 289) @@ -69,6 +69,12 @@ opts.on('--key PRIVATE_KEY', 'Use this private key for signing messages to server.') do |opt| options[:key] = opt end +opts.on('--configdir DIR', 'Directory containing etch.conf.') do |opt| + options[:configdir] = opt +end +opts.on('--vardir DIR', 'Directory for etch state and logs.') do |opt| + options[:vardir] = opt +end opts.on('--test-root TESTDIR', 'For use by the test suite only.') do |opt| options[:file_system_root] = opt end Modified: trunk/client/lib/etch/client.rb =================================================================== --- trunk/client/lib/etch/client.rb 2011-05-19 17:55:25 UTC (rev 288) +++ trunk/client/lib/etch/client.rb 2011-06-01 01:04:21 UTC (rev 289) @@ -49,7 +49,7 @@ CONFIRM_QUIT = 3 PRIVATE_KEY_PATHS = ["/etc/ssh/ssh_host_rsa_key", "/etc/ssh_host_rsa_key"] DEFAULT_CONFIGDIR = '/etc' - DEFAULT_VARBASE = '/var/etch' + DEFAULT_VARDIR = '/var/etch' DEFAULT_DETAILED_RESULTS = ['SERVER'] # We need these in relation to the output capturing @@ -60,6 +60,8 @@ def initialize(options) @server = options[:server] ? options[:server] : 'https://etch' + @configdir = options[:configdir] ? options[:configdir] : DEFAULT_CONFIGDIR + @vardir = options[:vardir] ? options[:vardir] : DEFAULT_VARDIR @tag = options[:tag] @local = options[:local] ? File.expand_path(options[:local]) : nil @debug = options[:debug] @@ -71,17 +73,14 @@ @key = options[:key] ? options[:key] : get_private_key_path @disableforce = options[:disableforce] @lockforce = options[:lockforce] - + @last_response = "" - @configdir = DEFAULT_CONFIGDIR - @varbase = DEFAULT_VARBASE - @file_system_root = '/' # Not sure if this needs to be more portable # This option is only intended for use by the test suite if options[:file_system_root] @file_system_root = options[:file_system_root] - @varbase = File.join(@file_system_root, @varbase) + @vardir = File.join(@file_system_root, @vardir) @configdir = File.join(@file_system_root, @configdir) end @@ -149,10 +148,10 @@ @detailed_results = DEFAULT_DETAILED_RESULTS end - @origbase = File.join(@varbase, 'orig') - @historybase = File.join(@varbase, 'history') - @lockbase = File.join(@varbase, 'locks') - @requestbase = File.join(@varbase, 'requests') + @origbase = File.join(@vardir, 'orig') + @historybase = File.join(@vardir, 'history') + @lockbase = File.join(@vardir, 'locks') + @requestbase = File.join(@vardir, 'requests') @facts = Facter.to_hash if @facts['operatingsystemrelease'] @@ -222,6 +221,7 @@ # Prep http instance http = nil if !@local + puts "Connecting to #{@filesuri}" if (@debug) http = Net::HTTP.new(@filesuri.host, @filesuri.port) if @filesuri.scheme == "https" # Eliminate the OpenSSL "using default DH parameters" warning @@ -572,7 +572,7 @@ end def check_for_disable_etch_file - disable_etch = File.join(@varbase, 'disable_etch') + disable_etch = File.join(@vardir, 'disable_etch') message = '' if File.exist?(disable_etch) if !@disableforce This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site. |
From: <jh...@us...> - 2011-05-19 17:55:31
|
Revision: 288 http://etch.svn.sourceforge.net/etch/?rev=288&view=rev Author: jheiss Date: 2011-05-19 17:55:25 +0000 (Thu, 19 May 2011) Log Message: ----------- Add cpio as a dependency Modified Paths: -------------- trunk/client/packages/deb/control trunk/client/packages/rpm/etch-client.spec trunk/client/packages/rpm/etch.spec Modified: trunk/client/packages/deb/control =================================================================== --- trunk/client/packages/deb/control 2011-05-19 17:31:15 UTC (rev 287) +++ trunk/client/packages/deb/control 2011-05-19 17:55:25 UTC (rev 288) @@ -2,6 +2,6 @@ Version: %VER%-1 Maintainer: etc...@li... Architecture: all -Depends: ruby, libopenssl-ruby1.8, facter, lsb-release, lsb-base +Depends: ruby, libopenssl-ruby1.8, facter, lsb-release, lsb-base, cpio Description: Etch client Modified: trunk/client/packages/rpm/etch-client.spec =================================================================== --- trunk/client/packages/rpm/etch-client.spec 2011-05-19 17:31:15 UTC (rev 287) +++ trunk/client/packages/rpm/etch-client.spec 2011-05-19 17:55:25 UTC (rev 288) @@ -5,7 +5,7 @@ Group: Applications/System License: MIT buildarch: noarch -Requires: ruby, facter, crontabs +Requires: ruby, facter, crontabs, cpio BuildRoot: %{_builddir}/%{name}-buildroot %description Etch client Modified: trunk/client/packages/rpm/etch.spec =================================================================== --- trunk/client/packages/rpm/etch.spec 2011-05-19 17:31:15 UTC (rev 287) +++ trunk/client/packages/rpm/etch.spec 2011-05-19 17:55:25 UTC (rev 288) @@ -10,7 +10,7 @@ BuildRoot: %{_tmppath}/%{name}-%{version}-%{release}-root-%(%{__id_u} -n) BuildRequires: rubygem-rake -Requires: ruby(abi) = 1.8, facter +Requires: ruby(abi) = 1.8, facter, cpio # Per http://fedoraproject.org/wiki/Packaging:Ruby %{!?ruby_sitelib: %global ruby_sitelib %(ruby -rrbconfig -e 'puts Config::CONFIG["sitelibdir"] ')} This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site. |
From: <jh...@us...> - 2011-05-19 17:31:21
|
Revision: 287 http://etch.svn.sourceforge.net/etch/?rev=287&view=rev Author: jheiss Date: 2011-05-19 17:31:15 +0000 (Thu, 19 May 2011) Log Message: ----------- Update the DTD files in these directories with some changes made to the testrepo DTD files a while back. Modified Paths: -------------- trunk/etchserver-demo/commands.dtd trunk/etchserver-demo/config.dtd trunk/etchserver-samples/commands.dtd trunk/etchserver-samples/config.dtd Modified: trunk/etchserver-demo/commands.dtd =================================================================== --- trunk/etchserver-demo/commands.dtd 2011-05-05 00:28:08 UTC (rev 286) +++ trunk/etchserver-demo/commands.dtd 2011-05-19 17:31:15 UTC (rev 287) @@ -1,6 +1,7 @@ -<!ELEMENT commands (depend*, step*)> +<!ELEMENT commands (depend*, dependfile*, step*)> <!ELEMENT depend (#PCDATA)> +<!ELEMENT dependfile (#PCDATA)> <!ELEMENT step (guard, command)> <!ELEMENT guard (exec*)> Modified: trunk/etchserver-demo/config.dtd =================================================================== --- trunk/etchserver-demo/config.dtd 2011-05-05 00:28:08 UTC (rev 286) +++ trunk/etchserver-demo/config.dtd 2011-05-19 17:31:15 UTC (rev 287) @@ -1,8 +1,9 @@ -<!ELEMENT config (revert?, depend*, server_setup?, setup?, pre?, (file|link|directory|delete)+, test_before_post?, post?, test?)> +<!ELEMENT config (revert?, depend*, dependcommand*, server_setup?, setup?, pre?, (file|link|directory|delete)+, test_before_post?, post?, test?)> <!ELEMENT revert EMPTY> <!ELEMENT depend (#PCDATA)> +<!ELEMENT dependcommand (#PCDATA)> <!ELEMENT server_setup (exec*)> <!ELEMENT setup (exec*)> Modified: trunk/etchserver-samples/commands.dtd =================================================================== --- trunk/etchserver-samples/commands.dtd 2011-05-05 00:28:08 UTC (rev 286) +++ trunk/etchserver-samples/commands.dtd 2011-05-19 17:31:15 UTC (rev 287) @@ -1,6 +1,7 @@ -<!ELEMENT commands (depend*, step*)> +<!ELEMENT commands (depend*, dependfile*, step*)> <!ELEMENT depend (#PCDATA)> +<!ELEMENT dependfile (#PCDATA)> <!ELEMENT step (guard, command)> <!ELEMENT guard (exec*)> Modified: trunk/etchserver-samples/config.dtd =================================================================== --- trunk/etchserver-samples/config.dtd 2011-05-05 00:28:08 UTC (rev 286) +++ trunk/etchserver-samples/config.dtd 2011-05-19 17:31:15 UTC (rev 287) @@ -1,8 +1,9 @@ -<!ELEMENT config (revert?, depend*, server_setup?, setup?, pre?, (file|link|directory|delete)+, test_before_post?, post?, test?)> +<!ELEMENT config (revert?, depend*, dependcommand*, server_setup?, setup?, pre?, (file|link|directory|delete)+, test_before_post?, post?, test?)> <!ELEMENT revert EMPTY> <!ELEMENT depend (#PCDATA)> +<!ELEMENT dependcommand (#PCDATA)> <!ELEMENT server_setup (exec*)> <!ELEMENT setup (exec*)> This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site. |
From: <jh...@us...> - 2011-05-05 00:28:14
|
Revision: 286 http://etch.svn.sourceforge.net/etch/?rev=286&view=rev Author: jheiss Date: 2011-05-05 00:28:08 +0000 (Thu, 05 May 2011) Log Message: ----------- Update to reflect client directory structure changes Modified Paths: -------------- trunk/client/bin/etch Modified: trunk/client/bin/etch =================================================================== --- trunk/client/bin/etch 2011-05-05 00:27:45 UTC (rev 285) +++ trunk/client/bin/etch 2011-05-05 00:28:08 UTC (rev 286) @@ -4,7 +4,7 @@ ############################################################################## # Ensure we can find etch/client.rb when run within the development repository -$:.unshift(File.join(File.dirname(__FILE__), 'lib')) +$:.unshift(File.join(File.dirname(File.dirname(__FILE__)), 'lib')) require 'optparse' require 'etch/client' This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site. |
From: <jh...@us...> - 2011-05-05 00:27:51
|
Revision: 285 http://etch.svn.sourceforge.net/etch/?rev=285&view=rev Author: jheiss Date: 2011-05-05 00:27:45 +0000 (Thu, 05 May 2011) Log Message: ----------- Ensure that the client and server are invoked with the same ruby the user used to invoke the test suite. This allows us to test etch under various ruby versions, etc. Update to reflect client directory structure changes Modified Paths: -------------- trunk/test/test_options.rb trunk/test/test_outputcapture.rb Modified: trunk/test/test_options.rb =================================================================== --- trunk/test/test_options.rb 2011-05-04 22:22:48 UTC (rev 284) +++ trunk/test/test_options.rb 2011-05-05 00:27:45 UTC (rev 285) @@ -105,7 +105,7 @@ def test_help output = nil - IO.popen("ruby #{CLIENTDIR}/etch --help") do |pipe| + IO.popen("#{RUBY} #{CLIENTDIR}/bin/etch --help") do |pipe| output = pipe.readlines end # Make sure at least something resembling help output is there @@ -529,7 +529,7 @@ # Test that output from etch is appropriate #run_etch(@server, @testroot, :extra_args => '--list-files', :testname => testname) - output = `ruby #{CLIENTDIR}/etch --generate-all --test-root=#{@testroot} --key=#{File.dirname(__FILE__)}/keys/testkey --server=http://localhost:#{@server[:port]} --list-files` + output = `#{RUBY} #{CLIENTDIR}/bin/etch --generate-all --test-root=#{@testroot} --key=#{File.dirname(__FILE__)}/keys/testkey --server=http://localhost:#{@server[:port]} --list-files` assert(output.include?("Files under management:\n#{@targetfile}\n")) # Ensure that the target file wasn't touched Modified: trunk/test/test_outputcapture.rb =================================================================== --- trunk/test/test_outputcapture.rb 2011-05-04 22:22:48 UTC (rev 284) +++ trunk/test/test_outputcapture.rb 2011-05-05 00:27:45 UTC (rev 285) @@ -6,9 +6,9 @@ require "./#{File.dirname(__FILE__)}/etchtest" require 'timeout' -$: << EtchTests::CLIENTDIR +$: << File.join(EtchTests::CLIENTDIR, 'lib') $: << File.join(EtchTests::SERVERDIR, 'lib') -require 'etchclient' +require 'etch/client' class EtchOutputCaptureTests < Test::Unit::TestCase include EtchTests @@ -86,7 +86,7 @@ </source> </file> <post> - <exec>ruby -e 'sleep #{Etch::Client::OUTPUT_CAPTURE_TIMEOUT + 30}' &</exec> + <exec>#{RUBY} -e 'sleep #{Etch::Client::OUTPUT_CAPTURE_TIMEOUT + 30}' &</exec> </post> </config> EOF This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site. |
From: <jh...@us...> - 2011-05-04 22:22:54
|
Revision: 284 http://etch.svn.sourceforge.net/etch/?rev=284&view=rev Author: jheiss Date: 2011-05-04 22:22:48 +0000 (Wed, 04 May 2011) Log Message: ----------- Update parsing of authentication key to be compatible with ruby 1.9. In 1.8 "\0"[0] == 0. In 1.9 "\0"[0] == "\0" Modified Paths: -------------- trunk/server/lib/etch/server.rb Modified: trunk/server/lib/etch/server.rb =================================================================== --- trunk/server/lib/etch/server.rb 2011-05-04 22:13:07 UTC (rev 283) +++ trunk/server/lib/etch/server.rb 2011-05-04 22:22:48 UTC (rev 284) @@ -78,9 +78,10 @@ # str = Base64.decode64(key) - # check header + + # check header (this is actually the length of the key type field) hdr = str.slice!(0..3) - unless hdr[0] == 0 && hdr[1] == 0 && hdr[2] == 0 && hdr[3] == 7 + if hdr.bytes.to_a != [0, 0, 0, 7] raise "Bad key format #{hdr}" end This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site. |
From: <jh...@us...> - 2011-05-04 22:13:13
|
Revision: 283 http://etch.svn.sourceforge.net/etch/?rev=283&view=rev Author: jheiss Date: 2011-05-04 22:13:07 +0000 (Wed, 04 May 2011) Log Message: ----------- Update to reflect server directory structure changes Modified Paths: -------------- trunk/client/lib/etch/client.rb Modified: trunk/client/lib/etch/client.rb =================================================================== --- trunk/client/lib/etch/client.rb 2011-05-04 22:11:29 UTC (rev 282) +++ trunk/client/lib/etch/client.rb 2011-05-04 22:13:07 UTC (rev 283) @@ -3,8 +3,8 @@ ############################################################################## # Ensure we can find etch.rb if run within the development directory structure -# This is roughly equivalent to "../server/lib" -serverlibdir = File.join(File.dirname(File.dirname(File.expand_path(__FILE__))), 'server', 'lib') +# This is roughly equivalent to "../../../server/lib" +serverlibdir = File.join(File.dirname(File.dirname(File.dirname(File.dirname(File.expand_path(__FILE__))))), 'server', 'lib') if File.exist?(serverlibdir) $:.unshift(serverlibdir) end This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site. |
From: <jh...@us...> - 2011-05-04 22:11:34
|
Revision: 282 http://etch.svn.sourceforge.net/etch/?rev=282&view=rev Author: jheiss Date: 2011-05-04 22:11:29 +0000 (Wed, 04 May 2011) Log Message: ----------- Update to reflect client directory structure changes Modified Paths: -------------- trunk/test/etchtest.rb Modified: trunk/test/etchtest.rb =================================================================== --- trunk/test/etchtest.rb 2011-05-04 22:07:14 UTC (rev 281) +++ trunk/test/etchtest.rb 2011-05-04 22:11:29 UTC (rev 282) @@ -175,7 +175,7 @@ puts "#" #sleep 3 end - result = system("#{RUBY} #{CLIENTDIR}/etch --generate-all --test-root=#{testroot} #{server} #{key} #{extra_args}") + result = system("#{RUBY} -I #{CLIENTDIR}/lib #{CLIENTDIR}/bin/etch --generate-all --test-root=#{testroot} #{server} #{key} #{extra_args}") if options[:errors_expected] assert(!result, options[:testname]) else This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site. |
From: <jh...@us...> - 2011-05-04 22:07:20
|
Revision: 281 http://etch.svn.sourceforge.net/etch/?rev=281&view=rev Author: jheiss Date: 2011-05-04 22:07:14 +0000 (Wed, 04 May 2011) Log Message: ----------- Rename etchserver.rb to etch/server.rb to match class structure and keep things cleaner. Modified Paths: -------------- trunk/server/app/controllers/application_controller.rb Added Paths: ----------- trunk/server/lib/etch/ trunk/server/lib/etch/server.rb Removed Paths: ------------- trunk/server/lib/etchserver.rb Modified: trunk/server/app/controllers/application_controller.rb =================================================================== --- trunk/server/app/controllers/application_controller.rb 2011-05-04 22:01:45 UTC (rev 280) +++ trunk/server/app/controllers/application_controller.rb 2011-05-04 22:07:14 UTC (rev 281) @@ -1,4 +1,4 @@ -require 'etchserver' +require 'etch/server' # Filters added to this controller apply to all controllers in the application. # Likewise, all the methods added will be available for all controllers. Copied: trunk/server/lib/etch/server.rb (from rev 272, trunk/server/lib/etchserver.rb) =================================================================== --- trunk/server/lib/etch/server.rb (rev 0) +++ trunk/server/lib/etch/server.rb 2011-05-04 22:07:14 UTC (rev 281) @@ -0,0 +1,460 @@ +require 'digest/sha1' # hexdigest +require 'base64' # decode64, encode64 +require 'openssl' +require 'time' # Time.parse +require 'fileutils' # mkdir_p +require 'logger' +require 'etch' + +class Etch::Server + DEFAULT_CONFIGBASE = '/etc/etchserver' + + # + # Class methods + # + + @@configbase = nil + def self.configbase + if !@@configbase + if ENV['etchserverbase'] && !ENV['etchserverbase'].empty? + @@configbase = ENV['etchserverbase'] + else + @@configbase = DEFAULT_CONFIGBASE + end + end + @@configbase + end + + @@auth_enabled = nil + @@auth_deny_new_clients = nil + def self.read_config_file + config_file = File.join(configbase, 'etchserver.conf') + if File.exist?(config_file) + auth_enabled = false + auth_deny_new_clients = false + IO.foreach(config_file) do |line| + # Skip blank lines and comments + next if line =~ /^\s*$/ + next if line =~ /^\s*#/ + line.chomp + if line =~ /^\s*auth_enabled\s*=\s*(.*)/ + if $1 == 'true' + auth_enabled = true + end + end + if line =~ /^\s*auth_deny_new_clients\s*=\s*(.*)/ + if $1 == 'true' + auth_deny_new_clients = true + end + end + end + @@auth_enabled = auth_enabled + @@auth_deny_new_clients = auth_deny_new_clients + end + end + def self.auth_enabled? + if @@auth_enabled.nil? + read_config_file + end + @@auth_enabled + end + # How to handle new clients (allow or deny) + def self.auth_deny_new_clients? + if @@auth_deny_new_clients.nil? + read_config_file + end + @@auth_deny_new_clients + end + + # This method verifies signatures from etch clients. + # message - the message to be verify + # signature - the signature of the message + # key - public key (in openssh format) + # Currently, this only supports RSA keys. + # Returns true if the signature is valid, false otherwise + def self.verify_signature(message, signature, key) + # + # Parse through the public key to get e and m + # + + str = Base64.decode64(key) + # check header + hdr = str.slice!(0..3) + unless hdr[0] == 0 && hdr[1] == 0 && hdr[2] == 0 && hdr[3] == 7 + raise "Bad key format #{hdr}" + end + + # check key type + keytype = str.slice!(0..6) + unless keytype == "ssh-rsa" + raise "Unsupported key type #{keytype}. Only support ssh-rsa right now" + end + + # get exponent + elength = str.slice!(0..3) + num = 0 + elength.each_byte { |x| + num = (num << 8) + x.to_i + } + elength_i = num + + num = 0 + e = str.slice!(0..elength_i-1) + e.each_byte { |x| + num = (num << 8) + x.to_i + } + e_i = num + + # get modulus + num = 0 + nlength = str.slice!(0..3) + nlength.each_byte { |x| + num = (num << 8) + x.to_i + } + nlength_i = num + + num = 0 + n = str.slice!(0..nlength_i-1) + n.each_byte { |x| + num = (num << 8) + x.to_i + } + + # + # Create key based on e and m + # + + key = OpenSSL::PKey::RSA.new + exponent = OpenSSL::BN.new e_i.to_s + modulus = OpenSSL::BN.new num.to_s + key.e = exponent + key.n = modulus + + # + # Check signature + # + + hash_from_sig = key.public_decrypt(Base64.decode64(signature)) + hash_from_msg = Digest::SHA1.hexdigest(message) + if hash_from_sig == hash_from_msg + return true # good signature + else + return false # bad signature + end + end + + def self.verify_message(message, signature, params) + timestamp = params[:timestamp] + # Don't accept if any of the required bits are missing + if message.nil? + raise "message is missing" + end + if signature.nil? + raise "signature is missing" + end + if timestamp.nil? + raise "timestamp param is missing" + end + + # Check timestamp, narrows the window of vulnerability to replay attack + # Window is set to 5 minutes + now = Time.new.to_i + parsed_timestamp = Time.parse(timestamp).to_i + timediff = now - parsed_timestamp + if timediff.abs >= (60 * 5) + raise "timestamp too far off (now:#{now}, timestamp:#{parsed_timestamp})" + end + + # Try to find the public key + public_key = nil + client = Client.find_by_name(params[:fqdn]) + if client + sshrsakey_fact = Fact.find_by_key_and_client_id('sshrsakey', client.id) + if sshrsakey_fact + public_key = sshrsakey_fact.value + end + end + if !public_key + if !auth_deny_new_clients? && + params[:facts] && params[:facts][:sshrsakey] + # If the user has configured the server to transparently accept + # new clients then do so, as long as the client is providing a + # key so that we won't consider them a new client on future + # connections. Otherwise a rogue client could continually + # impersonate any as-yet unregistered server by supplying some + # or all facts except the key fact. + return true + else + raise "Unknown client #{params[:fqdn]}, server configured to reject unknown clients" + end + end + + # Check signature + verify_signature(message, signature, public_key) + end + + # + # Instance methods + # + + # FIXME: Should some or all of this move to the controller? + + def initialize(facts, tag=nil, debug=false) + @facts = facts + @tag = tag + @debug = debug + @dlogger = Logger.new(File.join(Rails.configuration.root_path, 'log', 'etchdebug.log')) + if debug + @dlogger.level = Logger::DEBUG + else + @dlogger.level = Logger::INFO + end + @fqdn = @facts['fqdn'] + + if !@fqdn + raise "fqdn fact not supplied" + end + + # Update the stored facts for this client + @client = Client.find_or_create_by_name(@fqdn) + @facts.each do |key, value| + fact = Fact.find_or_create_by_client_id_and_key(:client_id => @client.id, :key => key, :value => value) + if fact.value != value + fact.update_attributes(:value => value) + end + end + Fact.find_all_by_client_id(@client.id).each do |fact| + if !@facts.has_key?(fact.key) + fact.destroy + end + end + + @configbase = Etch::Server.configbase + @dlogger.debug "Using #{@configbase} as config base for node #{@fqdn}" + if !File.directory?(@configbase) + raise "Config base #{@configbase} doesn't exist" + end + + # Check for killswitch + killswitch = File.join(@configbase, 'killswitch') + if File.exist?(killswitch) + contents = IO.read(killswitch) + raise "killswitch activated: #{contents}" + end + + # Run the external node tagger + # A client-supplied tag overrides the server-side node tagger + if !@tag.nil? && !@tag.empty? + # Don't allow the client to slip us a funky tag (i.e. '../../../etc' or something) + if @tag.include?('..') + raise "Client supplied tag #{@tag} contains '..'" + end + @dlogger.debug "Tag for node #{@fqdn} supplied by client: #{@tag}" + else + IO.popen(File.join(@configbase, 'nodetagger') + ' ' + @fqdn) do |pipe| + tmptag = pipe.gets + if tmptag.nil? + @tag = '' + else + @tag = tmptag.chomp + end + end + if !$?.success? + raise "External node tagger exited with error #{$?.exitstatus}" + end + @dlogger.debug "Tag for node #{@fqdn} from external node tagger: '#{@tag}'" + end + + @tagbase = File.join(@configbase, @tag) + @dlogger.debug "Using #{@tagbase} as tagged base for node #{@fqdn}" + if !File.directory?(@tagbase) + raise "Tagged base #{@tagbase} doesn't exist" + end + + @origbase = "#{@configbase}/orig" + end + + def generate(files, commands) + # + # Build up a list of files to generate, either from the request or from + # the source repository if the request is for all files + # + + request = {} + + # Store any original files and sums the client sent us + if !File.directory?(@origbase) + Dir.mkdir(@origbase, 0755) + end + files.each do |name, filehash| + next if name == 'GENERATEALL' + request[:files] = {} if !request[:files] + request[:files][name] = {} + if filehash['contents'] + contents = Base64.decode64(filehash['contents']) + + # Checksum the contents + sha1 = Digest::SHA1.hexdigest(contents) + + # Compare our checksum with the one generated on the client + if (sha1 != filehash['sha1sum']) + raise "Calculated SHA1 sum for #{name} doesn't match client's SHA1 sum" + end + + # Store the contents + @dlogger.debug "Storing original contents for #{name}" + origdir = "#{@origbase}/#{name}.ORIG" + if !File.directory?(origdir) + FileUtils.mkdir_p(origdir) + end + origpath = "#{origdir}/#{sha1}" + File.open(origpath, 'w', 0600) do |origfile| + origfile.write(contents) + end + request[:files][name][:orig] = origpath + # Update the stored record of the original + original = Original.find_or_create_by_client_id_and_file(:client_id => @client.id, :file => name, :sum => sha1) + if original.sum != sha1 + original.update_attributes(:sum => sha1) + end + end + if filehash['sha1sum'] + sha1 = filehash['sha1sum'] + # Update the stored record of the original + original = Original.find_or_create_by_client_id_and_file(:client_id => @client.id, :file => name, :sum => sha1) + if original.sum != sha1 + original.update_attributes(:sum => sha1) + end + origdir = "#{@origbase}/#{name}.ORIG" + origpath = "#{origdir}/#{sha1}" + if File.exist?(origpath) + request[:files][name][:orig] = origpath + end + end + if filehash['local_requests'] + request[:files][name][:local_requests] = filehash['local_requests'] + end + end + + commands.each_key do |commandname| + request[:commands] = {} if !request[:commands] + request[:commands][commandname] = {} + end + + # + # Process the user's request + # + + etch = Etch.new(RAILS_DEFAULT_LOGGER, @dlogger) + response = etch.generate(@tagbase, @facts, request) + + # + # Assemble our response to the client and return it + # + + # Generate the XML document to return to the client + response_xml = Etch.xmlnewdoc + responseroot = Etch.xmlnewelem('files', response_xml) + Etch.xmlsetroot(response_xml, responseroot) + # Add configs for files we generated + if response[:configs] + configs_xml = Etch.xmlnewelem('configs', response_xml) + response[:configs].each do |file, config_xml| + # Update the stored record of the config + # Exclude configs which correspond to files for which we're requesting + # an orig. In that case any config is just a partial config with + # setup and depend elements that we send to the client to ensure it + # supplies a proper orig file. + if !response[:need_orig][file] + config = EtchConfig.find_or_create_by_client_id_and_file(:client_id => @client.id, :file => file, :config => config_xml.to_s) + if config.config != config_xml.to_s + config.update_attributes(:config => config_xml.to_s) + end + end + # And add the config to the response to return to the client + Etch.xmlcopyelem(Etch.xmlroot(config_xml), configs_xml) + end + responseroot << configs_xml + end + # Add the files for which we need original sums or contents + if response[:need_orig] + need_sum = [] + need_orig = [] + response[:need_orig].each_key do |need| + # If the client already sent us the sum then we must be missing the + # orig contents, otherwise start by requesting the sum. + if files[need] && files[need]['sha1sum'] + need_orig << need + else + need_sum << need + end + end + if !need_sum.empty? + need_sums_xml = Etch.xmlnewelem('need_sums', response_xml) + need_sum.each do |need| + need_xml = Etch.xmlnewelem('need_sum', response_xml) + Etch.xmlsettext(need_xml, need) + need_sums_xml << need_xml + end + responseroot << need_sums_xml + end + if !need_orig.empty? + need_origs_xml = Etch.xmlnewelem('need_origs', response_xml) + need_orig.each do |need| + need_xml = Etch.xmlnewelem('need_orig', response_xml) + Etch.xmlsettext(need_xml, need) + need_origs_xml << need_xml + end + responseroot << need_origs_xml + end + end + # Add commands we generated + # The root XML element in each commands.xml is already the plural + # "commands", so we have to use something different here as the XML + # element we insert all of those into as part of the response. + if response[:allcommands] + commands_xml = Etch.xmlnewelem('allcommands', response_xml) + response[:allcommands].each do |commandname, command_xml| + # Update the stored record of the command + config = EtchConfig.find_or_create_by_client_id_and_file(:client_id => @client.id, :file => commandname, :config => command_xml.to_s) + if config.config != command_xml.to_s + config.update_attributes(:config => command_xml.to_s) + end + # Add the command to the response to return to the client + Etch.xmlcopyelem(Etch.xmlroot(command_xml), commands_xml) + end + responseroot << commands_xml + end + if response[:retrycommands] + retrycommands_xml = Etch.xmlnewelem('retrycommands', response_xml) + response[:retrycommands].each_key do |commandname| + retry_xml = Etch.xmlnewelem('retrycommand', response_xml) + Etch.xmlsettext(retry_xml, commandname) + retrycommands_xml << retry_xml + end + responseroot << retrycommands_xml + end + + # Clean up XML formatting + # But only if we're in debug mode, in regular mode nobody but the + # machines will see the XML and they don't care if it is pretty. + # FIXME: Tidy's formatting breaks things, it inserts leading/trailing whitespace into text nodes + if @debug && false + require 'tidy' + Tidy.path = '/sw/lib/libtidy.dylib' + Tidy.open(:show_warnings=>true) do |tidy| + tidy.options.input_xml = true + tidy.options.output_xml = true + # Screws up the Base64 contents data + #tidy.options.indent = true + tidy.options.hide_comments = true + response_xml = tidy.clean(response_xml.to_s) + puts tidy.errors + puts tidy.diagnostics if (@debug) + end + end + + @dlogger.debug "Returning #{response_xml}" + response_xml + end +end + Deleted: trunk/server/lib/etchserver.rb =================================================================== --- trunk/server/lib/etchserver.rb 2011-05-04 22:01:45 UTC (rev 280) +++ trunk/server/lib/etchserver.rb 2011-05-04 22:07:14 UTC (rev 281) @@ -1,460 +0,0 @@ -require 'digest/sha1' # hexdigest -require 'base64' # decode64, encode64 -require 'openssl' -require 'time' # Time.parse -require 'fileutils' # mkdir_p -require 'logger' -require 'etch' - -class Etch::Server - DEFAULT_CONFIGBASE = '/etc/etchserver' - - # - # Class methods - # - - @@configbase = nil - def self.configbase - if !@@configbase - if ENV['etchserverbase'] && !ENV['etchserverbase'].empty? - @@configbase = ENV['etchserverbase'] - else - @@configbase = DEFAULT_CONFIGBASE - end - end - @@configbase - end - - @@auth_enabled = nil - @@auth_deny_new_clients = nil - def self.read_config_file - config_file = File.join(configbase, 'etchserver.conf') - if File.exist?(config_file) - auth_enabled = false - auth_deny_new_clients = false - IO.foreach(config_file) do |line| - # Skip blank lines and comments - next if line =~ /^\s*$/ - next if line =~ /^\s*#/ - line.chomp - if line =~ /^\s*auth_enabled\s*=\s*(.*)/ - if $1 == 'true' - auth_enabled = true - end - end - if line =~ /^\s*auth_deny_new_clients\s*=\s*(.*)/ - if $1 == 'true' - auth_deny_new_clients = true - end - end - end - @@auth_enabled = auth_enabled - @@auth_deny_new_clients = auth_deny_new_clients - end - end - def self.auth_enabled? - if @@auth_enabled.nil? - read_config_file - end - @@auth_enabled - end - # How to handle new clients (allow or deny) - def self.auth_deny_new_clients? - if @@auth_deny_new_clients.nil? - read_config_file - end - @@auth_deny_new_clients - end - - # This method verifies signatures from etch clients. - # message - the message to be verify - # signature - the signature of the message - # key - public key (in openssh format) - # Currently, this only supports RSA keys. - # Returns true if the signature is valid, false otherwise - def self.verify_signature(message, signature, key) - # - # Parse through the public key to get e and m - # - - str = Base64.decode64(key) - # check header - hdr = str.slice!(0..3) - unless hdr[0] == 0 && hdr[1] == 0 && hdr[2] == 0 && hdr[3] == 7 - raise "Bad key format #{hdr}" - end - - # check key type - keytype = str.slice!(0..6) - unless keytype == "ssh-rsa" - raise "Unsupported key type #{keytype}. Only support ssh-rsa right now" - end - - # get exponent - elength = str.slice!(0..3) - num = 0 - elength.each_byte { |x| - num = (num << 8) + x.to_i - } - elength_i = num - - num = 0 - e = str.slice!(0..elength_i-1) - e.each_byte { |x| - num = (num << 8) + x.to_i - } - e_i = num - - # get modulus - num = 0 - nlength = str.slice!(0..3) - nlength.each_byte { |x| - num = (num << 8) + x.to_i - } - nlength_i = num - - num = 0 - n = str.slice!(0..nlength_i-1) - n.each_byte { |x| - num = (num << 8) + x.to_i - } - - # - # Create key based on e and m - # - - key = OpenSSL::PKey::RSA.new - exponent = OpenSSL::BN.new e_i.to_s - modulus = OpenSSL::BN.new num.to_s - key.e = exponent - key.n = modulus - - # - # Check signature - # - - hash_from_sig = key.public_decrypt(Base64.decode64(signature)) - hash_from_msg = Digest::SHA1.hexdigest(message) - if hash_from_sig == hash_from_msg - return true # good signature - else - return false # bad signature - end - end - - def self.verify_message(message, signature, params) - timestamp = params[:timestamp] - # Don't accept if any of the required bits are missing - if message.nil? - raise "message is missing" - end - if signature.nil? - raise "signature is missing" - end - if timestamp.nil? - raise "timestamp param is missing" - end - - # Check timestamp, narrows the window of vulnerability to replay attack - # Window is set to 5 minutes - now = Time.new.to_i - parsed_timestamp = Time.parse(timestamp).to_i - timediff = now - parsed_timestamp - if timediff.abs >= (60 * 5) - raise "timestamp too far off (now:#{now}, timestamp:#{parsed_timestamp})" - end - - # Try to find the public key - public_key = nil - client = Client.find_by_name(params[:fqdn]) - if client - sshrsakey_fact = Fact.find_by_key_and_client_id('sshrsakey', client.id) - if sshrsakey_fact - public_key = sshrsakey_fact.value - end - end - if !public_key - if !auth_deny_new_clients? && - params[:facts] && params[:facts][:sshrsakey] - # If the user has configured the server to transparently accept - # new clients then do so, as long as the client is providing a - # key so that we won't consider them a new client on future - # connections. Otherwise a rogue client could continually - # impersonate any as-yet unregistered server by supplying some - # or all facts except the key fact. - return true - else - raise "Unknown client #{params[:fqdn]}, server configured to reject unknown clients" - end - end - - # Check signature - verify_signature(message, signature, public_key) - end - - # - # Instance methods - # - - # FIXME: Should some or all of this move to the controller? - - def initialize(facts, tag=nil, debug=false) - @facts = facts - @tag = tag - @debug = debug - @dlogger = Logger.new(File.join(Rails.configuration.root_path, 'log', 'etchdebug.log')) - if debug - @dlogger.level = Logger::DEBUG - else - @dlogger.level = Logger::INFO - end - @fqdn = @facts['fqdn'] - - if !@fqdn - raise "fqdn fact not supplied" - end - - # Update the stored facts for this client - @client = Client.find_or_create_by_name(@fqdn) - @facts.each do |key, value| - fact = Fact.find_or_create_by_client_id_and_key(:client_id => @client.id, :key => key, :value => value) - if fact.value != value - fact.update_attributes(:value => value) - end - end - Fact.find_all_by_client_id(@client.id).each do |fact| - if !@facts.has_key?(fact.key) - fact.destroy - end - end - - @configbase = Etch::Server.configbase - @dlogger.debug "Using #{@configbase} as config base for node #{@fqdn}" - if !File.directory?(@configbase) - raise "Config base #{@configbase} doesn't exist" - end - - # Check for killswitch - killswitch = File.join(@configbase, 'killswitch') - if File.exist?(killswitch) - contents = IO.read(killswitch) - raise "killswitch activated: #{contents}" - end - - # Run the external node tagger - # A client-supplied tag overrides the server-side node tagger - if !@tag.nil? && !@tag.empty? - # Don't allow the client to slip us a funky tag (i.e. '../../../etc' or something) - if @tag.include?('..') - raise "Client supplied tag #{@tag} contains '..'" - end - @dlogger.debug "Tag for node #{@fqdn} supplied by client: #{@tag}" - else - IO.popen(File.join(@configbase, 'nodetagger') + ' ' + @fqdn) do |pipe| - tmptag = pipe.gets - if tmptag.nil? - @tag = '' - else - @tag = tmptag.chomp - end - end - if !$?.success? - raise "External node tagger exited with error #{$?.exitstatus}" - end - @dlogger.debug "Tag for node #{@fqdn} from external node tagger: '#{@tag}'" - end - - @tagbase = File.join(@configbase, @tag) - @dlogger.debug "Using #{@tagbase} as tagged base for node #{@fqdn}" - if !File.directory?(@tagbase) - raise "Tagged base #{@tagbase} doesn't exist" - end - - @origbase = "#{@configbase}/orig" - end - - def generate(files, commands) - # - # Build up a list of files to generate, either from the request or from - # the source repository if the request is for all files - # - - request = {} - - # Store any original files and sums the client sent us - if !File.directory?(@origbase) - Dir.mkdir(@origbase, 0755) - end - files.each do |name, filehash| - next if name == 'GENERATEALL' - request[:files] = {} if !request[:files] - request[:files][name] = {} - if filehash['contents'] - contents = Base64.decode64(filehash['contents']) - - # Checksum the contents - sha1 = Digest::SHA1.hexdigest(contents) - - # Compare our checksum with the one generated on the client - if (sha1 != filehash['sha1sum']) - raise "Calculated SHA1 sum for #{name} doesn't match client's SHA1 sum" - end - - # Store the contents - @dlogger.debug "Storing original contents for #{name}" - origdir = "#{@origbase}/#{name}.ORIG" - if !File.directory?(origdir) - FileUtils.mkdir_p(origdir) - end - origpath = "#{origdir}/#{sha1}" - File.open(origpath, 'w', 0600) do |origfile| - origfile.write(contents) - end - request[:files][name][:orig] = origpath - # Update the stored record of the original - original = Original.find_or_create_by_client_id_and_file(:client_id => @client.id, :file => name, :sum => sha1) - if original.sum != sha1 - original.update_attributes(:sum => sha1) - end - end - if filehash['sha1sum'] - sha1 = filehash['sha1sum'] - # Update the stored record of the original - original = Original.find_or_create_by_client_id_and_file(:client_id => @client.id, :file => name, :sum => sha1) - if original.sum != sha1 - original.update_attributes(:sum => sha1) - end - origdir = "#{@origbase}/#{name}.ORIG" - origpath = "#{origdir}/#{sha1}" - if File.exist?(origpath) - request[:files][name][:orig] = origpath - end - end - if filehash['local_requests'] - request[:files][name][:local_requests] = filehash['local_requests'] - end - end - - commands.each_key do |commandname| - request[:commands] = {} if !request[:commands] - request[:commands][commandname] = {} - end - - # - # Process the user's request - # - - etch = Etch.new(RAILS_DEFAULT_LOGGER, @dlogger) - response = etch.generate(@tagbase, @facts, request) - - # - # Assemble our response to the client and return it - # - - # Generate the XML document to return to the client - response_xml = Etch.xmlnewdoc - responseroot = Etch.xmlnewelem('files', response_xml) - Etch.xmlsetroot(response_xml, responseroot) - # Add configs for files we generated - if response[:configs] - configs_xml = Etch.xmlnewelem('configs', response_xml) - response[:configs].each do |file, config_xml| - # Update the stored record of the config - # Exclude configs which correspond to files for which we're requesting - # an orig. In that case any config is just a partial config with - # setup and depend elements that we send to the client to ensure it - # supplies a proper orig file. - if !response[:need_orig][file] - config = EtchConfig.find_or_create_by_client_id_and_file(:client_id => @client.id, :file => file, :config => config_xml.to_s) - if config.config != config_xml.to_s - config.update_attributes(:config => config_xml.to_s) - end - end - # And add the config to the response to return to the client - Etch.xmlcopyelem(Etch.xmlroot(config_xml), configs_xml) - end - responseroot << configs_xml - end - # Add the files for which we need original sums or contents - if response[:need_orig] - need_sum = [] - need_orig = [] - response[:need_orig].each_key do |need| - # If the client already sent us the sum then we must be missing the - # orig contents, otherwise start by requesting the sum. - if files[need] && files[need]['sha1sum'] - need_orig << need - else - need_sum << need - end - end - if !need_sum.empty? - need_sums_xml = Etch.xmlnewelem('need_sums', response_xml) - need_sum.each do |need| - need_xml = Etch.xmlnewelem('need_sum', response_xml) - Etch.xmlsettext(need_xml, need) - need_sums_xml << need_xml - end - responseroot << need_sums_xml - end - if !need_orig.empty? - need_origs_xml = Etch.xmlnewelem('need_origs', response_xml) - need_orig.each do |need| - need_xml = Etch.xmlnewelem('need_orig', response_xml) - Etch.xmlsettext(need_xml, need) - need_origs_xml << need_xml - end - responseroot << need_origs_xml - end - end - # Add commands we generated - # The root XML element in each commands.xml is already the plural - # "commands", so we have to use something different here as the XML - # element we insert all of those into as part of the response. - if response[:allcommands] - commands_xml = Etch.xmlnewelem('allcommands', response_xml) - response[:allcommands].each do |commandname, command_xml| - # Update the stored record of the command - config = EtchConfig.find_or_create_by_client_id_and_file(:client_id => @client.id, :file => commandname, :config => command_xml.to_s) - if config.config != command_xml.to_s - config.update_attributes(:config => command_xml.to_s) - end - # Add the command to the response to return to the client - Etch.xmlcopyelem(Etch.xmlroot(command_xml), commands_xml) - end - responseroot << commands_xml - end - if response[:retrycommands] - retrycommands_xml = Etch.xmlnewelem('retrycommands', response_xml) - response[:retrycommands].each_key do |commandname| - retry_xml = Etch.xmlnewelem('retrycommand', response_xml) - Etch.xmlsettext(retry_xml, commandname) - retrycommands_xml << retry_xml - end - responseroot << retrycommands_xml - end - - # Clean up XML formatting - # But only if we're in debug mode, in regular mode nobody but the - # machines will see the XML and they don't care if it is pretty. - # FIXME: Tidy's formatting breaks things, it inserts leading/trailing whitespace into text nodes - if @debug && false - require 'tidy' - Tidy.path = '/sw/lib/libtidy.dylib' - Tidy.open(:show_warnings=>true) do |tidy| - tidy.options.input_xml = true - tidy.options.output_xml = true - # Screws up the Base64 contents data - #tidy.options.indent = true - tidy.options.hide_comments = true - response_xml = tidy.clean(response_xml.to_s) - puts tidy.errors - puts tidy.diagnostics if (@debug) - end - end - - @dlogger.debug "Returning #{response_xml}" - response_xml - end -end - This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site. |
From: <jh...@us...> - 2011-05-04 22:01:51
|
Revision: 280 http://etch.svn.sourceforge.net/etch/?rev=280&view=rev Author: jheiss Date: 2011-05-04 22:01:45 +0000 (Wed, 04 May 2011) Log Message: ----------- Load 3rd party libraries inside Silently since several of them emit warnings under ruby 1.9 Modified Paths: -------------- trunk/server/lib/etch.rb Modified: trunk/server/lib/etch.rb =================================================================== --- trunk/server/lib/etch.rb 2011-05-04 21:57:20 UTC (rev 279) +++ trunk/server/lib/etch.rb 2011-05-04 22:01:45 UTC (rev 280) @@ -1,11 +1,17 @@ -require 'find' # Find.find -require 'pathname' # absolute? -require 'digest/sha1' # hexdigest -require 'base64' # decode64, encode64 -require 'fileutils' # mkdir_p -require 'erb' +# Exclude standard libraries and gems from the warnings induced by +# running ruby with the -w flag. Several of these have warnings under +# ruby 1.9 and there's nothing we can do to fix that. +require 'silently' +Silently.silently do + require 'find' # Find.find + require 'pathname' # absolute? + require 'digest/sha1' # hexdigest + require 'base64' # decode64, encode64 + require 'fileutils' # mkdir_p + require 'erb' + require 'logger' +end require 'versiontype' # Version -require 'logger' class Etch def self.xmllib @@ -19,25 +25,27 @@ # By default we try to use libxml, falling back to rexml if it is not # available. The xmllib environment variable can be used to force one library # or the other, mostly for testing purposes. -begin - if !ENV['xmllib'] || ENV['xmllib'] == 'libxml' - require 'rubygems' # libxml is a gem - require 'libxml' - Etch.xmllib = :libxml - elsif ENV['xmllib'] == 'nokogiri' - require 'rubygems' # nokogiri is a gem - require 'nokogiri' - Etch.xmllib = :nokogiri - else - raise LoadError +Silently.silently do + begin + if !ENV['xmllib'] || ENV['xmllib'] == 'libxml' + require 'rubygems' # libxml is a gem + require 'libxml' + Etch.xmllib = :libxml + elsif ENV['xmllib'] == 'nokogiri' + require 'rubygems' # nokogiri is a gem + require 'nokogiri' + Etch.xmllib = :nokogiri + else + raise LoadError + end + rescue LoadError + if !ENV['xmllib'] || ENV['xmllib'] == 'rexml' + require 'rexml/document' + Etch.xmllib = :rexml + else + raise + end end -rescue LoadError - if !ENV['xmllib'] || ENV['xmllib'] == 'rexml' - require 'rexml/document' - Etch.xmllib = :rexml - else - raise - end end class Etch This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site. |
From: <jh...@us...> - 2011-05-04 21:57:26
|
Revision: 279 http://etch.svn.sourceforge.net/etch/?rev=279&view=rev Author: jheiss Date: 2011-05-04 21:57:20 +0000 (Wed, 04 May 2011) Log Message: ----------- Add library for silencing warnings from 3rd party modules Added Paths: ----------- trunk/server/lib/silently.rb Added: trunk/server/lib/silently.rb =================================================================== --- trunk/server/lib/silently.rb (rev 0) +++ trunk/server/lib/silently.rb 2011-05-04 21:57:20 UTC (rev 279) @@ -0,0 +1,11 @@ +# http://www.caliban.org/ruby/rubyguide.shtml#warnings +class Silently + def self.silently(&block) + warn_level = $VERBOSE + $VERBOSE = nil + result = block.call + $VERBOSE = warn_level + result + end +end + This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site. |
From: <jh...@us...> - 2011-05-04 17:43:55
|
Revision: 278 http://etch.svn.sourceforge.net/etch/?rev=278&view=rev Author: jheiss Date: 2011-05-04 17:43:47 +0000 (Wed, 04 May 2011) Log Message: ----------- Clean up the client directory structure to look like a real ruby project Modified Paths: -------------- trunk/client/Rakefile Added Paths: ----------- trunk/client/bin/ trunk/client/bin/etch trunk/client/bin/etch_cron_wrapper trunk/client/bin/etch_to_trunk trunk/client/etc/ trunk/client/etc/cron.d/ trunk/client/etc/cron.d/etch trunk/client/etc/etch/ trunk/client/etc/etch/ca.pem trunk/client/etc/etch/dhparams trunk/client/etc/etch.conf trunk/client/lib/ trunk/client/lib/etch/ trunk/client/lib/etch/client.rb trunk/client/man/ trunk/client/man/man8/ trunk/client/man/man8/etch.8 trunk/client/packages/ trunk/client/packages/deb/ trunk/client/packages/deb/control trunk/client/packages/gem/ trunk/client/packages/gem/gemspec trunk/client/packages/macports/ trunk/client/packages/macports/Portfile trunk/client/packages/macports/Portfile.template trunk/client/packages/rpm/ trunk/client/packages/rpm/etch-client.spec trunk/client/packages/rpm/etch.spec trunk/client/packages/sysv/ trunk/client/packages/sysv/depend trunk/client/packages/sysv/pkginfo trunk/client/packages/sysv/postinstall.solaris trunk/client/packages/sysv/postremove.solaris Removed Paths: ------------- trunk/client/Portfile trunk/client/Portfile.template trunk/client/ca.pem trunk/client/control trunk/client/depend trunk/client/dhparams trunk/client/etch trunk/client/etch-client.spec trunk/client/etch.8 trunk/client/etch.conf trunk/client/etch.spec trunk/client/etch_cron trunk/client/etch_cron_wrapper trunk/client/etch_to_trunk trunk/client/etchclient.rb trunk/client/gemspec trunk/client/pkginfo trunk/client/postinstall.solaris trunk/client/postremove.solaris Deleted: trunk/client/Portfile =================================================================== --- trunk/client/Portfile 2011-05-04 14:34:24 UTC (rev 277) +++ trunk/client/Portfile 2011-05-04 17:43:47 UTC (rev 278) @@ -1,41 +0,0 @@ -# -*- coding: utf-8; mode: tcl; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- vim:fenc=utf-8:ft=tcl:et:sw=4:ts=4:sts=4 -# $Id$ - -PortSystem 1.0 -PortGroup ruby 1.0 - -name etch -version 3.17.0 -categories sysutils -maintainers aput.net:jheiss openmaintainer - -description Etch is a system configuration management tool. - -long_description Etch is a tool for managing the configuration of \ - Unix systems. Etch can manage text or binary \ - files, links and directories. The contents of \ - files can be supplied from static files or \ - generated on the fly by scripts or templates. \ - Permissions and ownership as well as any pre or \ - post commands to run when updating the file are \ - configured in simple XML files. - -homepage http://etch.sourceforge.net/ -platforms darwin - -master_sites sourceforge - -checksums md5 9b5216f62d4add225f50984cc07f630b \ - sha1 a4bc1c61f349464ca793d858abeca08760bde6e5 \ - rmd160 f827b360c69cceab1a864b11c7cf434b7c7a4a39 - -depends_build port:rb-rake -depends_run port:facter - -worksrcdir ${worksrcdir}/client -supported_archs noarch -use_configure no -build {} -destroot.cmd ${prefix}/bin/rake -destroot.target install\[${destroot}\] -destroot.destdir Deleted: trunk/client/Portfile.template =================================================================== --- trunk/client/Portfile.template 2011-05-04 14:34:24 UTC (rev 277) +++ trunk/client/Portfile.template 2011-05-04 17:43:47 UTC (rev 278) @@ -1,42 +0,0 @@ -# -*- coding: utf-8; mode: tcl; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- vim:fenc=utf-8:ft=tcl:et:sw=4:ts=4:sts=4 -# $Id$ - -PortSystem 1.0 -PortGroup ruby 1.0 - -name etch -version %VER% -categories sysutils -maintainers aput.net:jheiss openmaintainer -supported_archs noarch - -description Etch is a system configuration management tool. - -long_description Etch is a tool for managing the configuration of \ - Unix systems. Etch can manage text or binary \ - files, links and directories. The contents of \ - files can be supplied from static files or \ - generated on the fly by scripts or templates. \ - Permissions and ownership as well as any pre or \ - post commands to run when updating the file are \ - configured in simple XML files. - -homepage http://etch.sourceforge.net/ -platforms darwin - -master_sites sourceforge - -checksums md5 %MD5% \ - sha1 %SHA1% \ - rmd160 %RMD160% - -depends_build port:rb-rake -depends_run port:facter - -worksrcdir ${worksrcdir}/client -supported_archs noarch -use_configure no -build {} -destroot.cmd ${prefix}/bin/rake -destroot.target install\[${destroot}\] -destroot.destdir Modified: trunk/client/Rakefile =================================================================== --- trunk/client/Rakefile 2011-05-04 14:34:24 UTC (rev 277) +++ trunk/client/Rakefile 2011-05-04 17:43:47 UTC (rev 278) @@ -28,7 +28,7 @@ if options[:ruby] # Change #! line File.open(File.join(bindir, binapp), 'w') do |newfile| - File.open(binapp) do |oldfile| + File.open(File.join('bin', binapp)) do |oldfile| # Modify the first line firstline = oldfile.gets # Preserve any options. I.e. #!/usr/bin/ruby -w @@ -39,7 +39,7 @@ end end else - cp(binapp, bindir, :preserve => true) + cp(File.join('bin', binapp), bindir, :preserve => true) end chmod(0555, File.join(bindir, binapp)) end @@ -48,11 +48,12 @@ if options[:libdir] libdir = File.join(destdir, options[:libdir]) mkdir_p(libdir) + mkdir_p(File.join(libdir, 'etch')) - # Substitute ETCHVER into etchclient.rb - # Substitute proper path into CONFIGDIR in etchclient.rb if appropriate - File.open(File.join(libdir, 'etchclient.rb'), 'w') do |newfile| - IO.foreach('etchclient.rb') do |line| + # Substitute ETCHVER into etch/client.rb + # Substitute proper path into CONFIGDIR in etch/client.rb if appropriate + File.open(File.join(libdir, 'etch', 'client.rb'), 'w') do |newfile| + IO.foreach(File.join('etch', 'client.rb')) do |line| if line =~ /^\s*VERSION/ line.sub!(/=.*/, "= '#{ETCHVER}'") end @@ -62,9 +63,9 @@ newfile.write(line) end end - chmod(0444, File.join(libdir, 'etchclient.rb')) + chmod(0444, File.join(libdir, 'etch', 'client.rb')) - serverlibs = ['etch.rb', 'versiontype.rb'] + serverlibs = ['etch.rb', 'silently.rb', 'versiontype.rb'] serverlibs.each do |serverlib| cp(File.join('..', 'server', 'lib', serverlib), libdir, :preserve => true) chmod(0444, File.join(libdir, serverlib)) @@ -75,21 +76,21 @@ mandir = File.join(destdir, options[:mandir]) man8dir = File.join(mandir, 'man8') mkdir_p(man8dir) - cp('etch.8', man8dir, :preserve => true) + cp(File.join('man', 'man8', 'etch.8'), man8dir, :preserve => true) chmod(0444, File.join(man8dir, 'etch.8')) end if options[:etcdir] etcdir = File.join(destdir, options[:etcdir]) mkdir_p(etcdir) - cp('etch.conf', etcdir, :preserve => true) + cp(File.join('etc', 'etch.conf'), etcdir, :preserve => true) chmod(0644, File.join(etcdir, 'etch.conf')) # All of the supporting config files go into a subdirectory etcetchdir = File.join(etcdir, 'etch') mkdir_p(etcetchdir) etcetchfiles = ['ca.pem', 'dhparams'] etcetchfiles.each do |etcetchfile| - cp(etcetchfile, etcetchdir, :preserve => true) + cp(File.join('etc', 'etch', etcetchfile), etcetchdir, :preserve => true) chmod(0644, File.join(etcetchdir, etcetchfile)) end end @@ -97,9 +98,7 @@ if options[:crondir] crondir = File.join(destdir, options[:crondir]) mkdir_p(crondir) - # Note file renamed to 'etch' here. Filename is different in the repo for - # clarity and to avoid conflict with the main executable. - cp('etch_cron', File.join(crondir, 'etch'), :preserve => true) + cp(File.join('etc', 'cron.d', 'etch'), crondir, :preserve => true) chmod(0444, File.join(crondir, 'etch')) end end @@ -132,7 +131,7 @@ # spec = Tempfile.new('etchrpm') - IO.foreach('etch-client.spec') do |line| + IO.foreach(File.join('packages', 'rpm', 'etch-client.spec')) do |line| line.sub!('%VER%', ETCHVER) spec.puts(line) end @@ -161,7 +160,7 @@ mkdir_p(File.join(BUILDROOT, 'DEBIAN')) File.open(File.join(BUILDROOT, 'DEBIAN', 'control'), 'w') do |control| - IO.foreach('control') do |line| + IO.foreach(File.join('packages', 'deb', 'control')) do |line| next if line =~ /^\s*#/ # Remove comments line.sub!('%VER%', ETCHVER) control.puts(line) @@ -220,19 +219,19 @@ rm_rf('solbuild') mkdir('solbuild') File.open(File.join('solbuild', 'pkginfo'), 'w') do |pkginfo| - IO.foreach('pkginfo') do |line| + IO.foreach(File.join('packages', 'sysv', 'pkginfo')) do |line| line.sub!('%VER%', ETCHVER) pkginfo.puts(line) end end File.open(File.join('solbuild', 'prototype'), 'w') do |prototype| prototype.puts("i pkginfo=./pkginfo") - cp('depend', 'solbuild/depend') + cp(File.join('packages', 'sysv', 'depend'), 'solbuild/depend') prototype.puts("i depend=./depend") - cp('postinstall.solaris', 'solbuild/postinstall') + cp(File.join('packages', 'sysv', 'postinstall.solaris'), 'solbuild/postinstall') chmod(0555, 'solbuild/postinstall') prototype.puts("i postinstall=./postinstall") - cp('postremove.solaris', 'solbuild/postremove') + cp(File.join('packages', 'sysv', 'postremove.solaris'), 'solbuild/postremove') chmod(0555, 'solbuild/postremove') prototype.puts("i postremove=./postremove") # The tail +2 removes the first line, which is the base directory @@ -311,19 +310,19 @@ rm_rf('solbuild') mkdir('solbuild') File.open(File.join('solbuild', 'pkginfo'), 'w') do |pkginfo| - IO.foreach('pkginfo') do |line| + IO.foreach(File.join('packages', 'sysv', 'pkginfo')) do |line| line.sub!('%VER%', ETCHVER) pkginfo.puts(line) end end File.open(File.join('solbuild', 'prototype'), 'w') do |prototype| prototype.puts("i pkginfo=./pkginfo") - cp('depend', 'solbuild/depend') + cp(File.join('packages', 'sysv', 'depend'), 'solbuild/depend') prototype.puts("i depend=./depend") - cp('postinstall.solaris', 'solbuild/postinstall') + cp(File.join('packages', 'sysv', 'postinstall.solaris'), 'solbuild/postinstall') chmod(0555, 'solbuild/postinstall') prototype.puts("i postinstall=./postinstall") - cp('postremove.solaris', 'solbuild/postremove') + cp(File.join('packages', 'sysv', 'postremove.solaris'), 'solbuild/postremove') chmod(0555, 'solbuild/postremove') prototype.puts("i postremove=./postremove") # The tail +2 removes the first line, which is the base directory @@ -395,7 +394,7 @@ portfile = File.join(Dir.tmpdir, 'Portfile') rm_f(portfile) File.open(portfile, 'w') do |newfile| - IO.foreach('Portfile.template') do |line| + IO.foreach(File.join('packages', 'macports', 'Portfile.template')) do |line| line.sub!('%VER%', ETCHVER) line.sub!('%MD5%', md5) line.sub!('%SHA1%', sha1) @@ -421,7 +420,7 @@ # Prep gemspec (renaming to Rakefile in the process) # File.open(File.join(BUILDROOT, 'Rakefile'), 'w') do |gemspec| - IO.foreach('gemspec') do |line| + IO.foreach(File.join('packages', 'gem', 'gemspec')) do |line| line.sub!('%VER%', ETCHVER) gemspec.puts(line) end Copied: trunk/client/bin/etch (from rev 272, trunk/client/etch) =================================================================== --- trunk/client/bin/etch (rev 0) +++ trunk/client/bin/etch 2011-05-04 17:43:47 UTC (rev 278) @@ -0,0 +1,111 @@ +#!/usr/bin/ruby -w +############################################################################## +# Etch configuration file management tool +############################################################################## + +# Ensure we can find etch/client.rb when run within the development repository +$:.unshift(File.join(File.dirname(__FILE__), 'lib')) + +require 'optparse' +require 'etch/client' + +# +# Parse the command line options +# + +options = {} +@generateall = nil + +# Extra options to OptionParser reduce the amount of whitespace it introduces +# into the help message, making it easier to make the help message fit in a +# 80x24 window. +opts = OptionParser.new(nil, 24, ' ') +opts.banner = 'Usage: etch [options] [/path/to/config/file | command] [otherfile ...]' +opts.on('--generate-all', 'Request all configuration.') do |opt| + @generateall = opt +end +opts.on('--dry-run', '-n', 'Make no changes.') do |opt| + options[:dryrun] = opt +end +opts.on('--damp-run', "Perform a dry run but run 'setup' entries for files.") do |opt| + # Rather than sprinkle checks of two different variables throught the code, if + # we're asked to do a damp run then just set the dry run flag to a unique + # value. Then we can just check for that specific value at the one place where + # the two modes differ: enabling or disabling the execution of 'setup' + # entries. + options[:dryrun] = 'damp' +end +opts.on('--list-files', 'Just list the files that would be configured') do |opt| + options[:listfiles] = opt + # generate all is implied + @generateall = true + # Set :dryrun as a extra measure to make sure we don't change anything + options[:dryrun] = 'listfiles' +end +opts.on('--interactive', 'Prompt for confirmation before each change.') do |opt| + options[:interactive] = opt +end +opts.on('--full-file', 'Display full new file contents instead of a diff.') do |opt| + options[:fullfile] = opt +end +opts.on('--filename-only', 'Display filename of changed files instead of a diff.') do |opt| + options[:filenameonly] = opt +end +opts.on('--disable-force', 'Ignore the disable_etch file. Use with caution.') do |opt| + options[:disableforce] = opt +end +opts.on('--lock-force', 'Force the removal of any existing lockfiles.') do |opt| + options[:lockforce] = opt +end +opts.on('--local DIR', 'Read configuration from local directory, not server.') do |opt| + options[:local] = opt +end +opts.on('--server SERVER', 'Point etch to an alternate server.') do |opt| + options[:server] = opt +end +opts.on('--tag TAG', 'Request a specific repository tag from the server.') do |opt| + options[:tag] = opt +end +opts.on('--key PRIVATE_KEY', 'Use this private key for signing messages to server.') do |opt| + options[:key] = opt +end +opts.on('--test-root TESTDIR', 'For use by the test suite only.') do |opt| + options[:file_system_root] = opt +end +opts.on('--debug', 'Print lots of messages about what etch is doing.') do |opt| + options[:debug] = opt +end +opts.on('--version', 'Show etch client version.') do |opt| + puts Etch::Client::VERSION + exit +end +opts.on_tail('-h', '--help', 'Show this message.') do + puts opts + exit +end + +leftovers = opts.parse(ARGV) +files = [] +commands = [] +leftovers.each do |leftover| + if leftover[0,1] == File::SEPARATOR + files << leftover + else + commands << leftover + end +end + +# Display a usage message if the user did not specify a valid action to perform. +if files.empty? && commands.empty? && !@generateall + puts opts + exit +end + +# +# Do stuff +# + +etchclient = Etch::Client.new(options) +status = etchclient.process_until_done(files, commands) +exit status + Copied: trunk/client/bin/etch_cron_wrapper (from rev 272, trunk/client/etch_cron_wrapper) =================================================================== --- trunk/client/bin/etch_cron_wrapper (rev 0) +++ trunk/client/bin/etch_cron_wrapper 2011-05-04 17:43:47 UTC (rev 278) @@ -0,0 +1,18 @@ +#!/usr/bin/ruby -w + +require 'socket' +require 'digest/sha1' + +# Seed the random number generator with the hostname of this box so that +# we get a consistent random number. We want to run the registration at a +# consistent time on each individual box, but randomize the runs across +# the environment. +srand(Digest::SHA1.hexdigest(Socket.gethostname)[0,7].hex) + +# Cron job is set to run every hour +MAX_SLEEP = 60 * 60 + +sleep(rand(MAX_SLEEP)) + +exec('/usr/sbin/etch', '--generate-all') + Copied: trunk/client/bin/etch_to_trunk (from rev 272, trunk/client/etch_to_trunk) =================================================================== --- trunk/client/bin/etch_to_trunk (rev 0) +++ trunk/client/bin/etch_to_trunk 2011-05-04 17:43:47 UTC (rev 278) @@ -0,0 +1,77 @@ +#!/usr/bin/ruby -w + +require 'nventory' +require 'time' +require 'optparse' + +ETCH_SERVER_TZ = 'UTC' # The etch servers run in UTC + +options = {} +opts = OptionParser.new +opts.banner = 'Usage: etch_to_trunk [options] <server1> [<server2> <server3>]' +opts.on('-u', '--username USERNAME', 'Username for connecting to nventory server.') do |opt| + options[:username] = opt +end +opts.on('-t', '--timezone TIMEZONE', 'Time zone of etch server.') do |opt| + options[:timezone] = opt +end +opts.on('--nv SERVER', 'Where nVentory server is running.') do |opt| + options[:nv_server] = opt +end +opts.on_tail('-h', '--help', 'Show this message.') do + puts opts + exit +end + +nodes = opts.parse(ARGV) + +if ARGV.length == 0 + puts opts + exit +end + +@username = options[:username] || ENV['LOGNAME'] +etch_server_tz = options[:timezone] || ETCH_SERVER_TZ + +if etch_server_tz + currentheadtag = Time.at(Time.now.utc + Time.zone_offset(etch_server_tz)).strftime('trunk-%Y%m%d-%H00') +else # if no timezone is specified then just use local time for the tag + currentheadtag = Time.now.strftime('trunk-%Y%m%d-%H00') +end + +# Find the requested clients +nv_server = options[:nv_server] +if nv_server + nvclient = NVentory::Client.new(:server=>"http://#{nv_server}") +else + nvclient = NVentory::Client.new +end +results = nvclient.get_objects('nodes', {}, { 'name' => nodes }, {}, {}) +nodes.each do |name| + if results.empty? && results[name].nil? + abort "No entry found for #{name}" + else + if !results[name]['config_mgmt_tag'].nil? && + !results[name]['config_mgmt_tag'].empty? + puts "Changing #{name} from #{results[name]['config_mgmt_tag']} to #{currentheadtag}" + else + puts "Setting #{name} to #{currentheadtag}" + end + end +end + +while true + print "Proceed? [y|n] " + response = $stdin.gets.chomp + if response == 'y' + break + elsif response == 'n' + exit + end +end + +# Update the clients +successcount = nvclient.set_objects('nodes', results, {'config_mgmt_tag' => currentheadtag}, @username) + +puts "#{File.basename($0)} operation succeeded for #{successcount} of #{results.size} nodes" + Deleted: trunk/client/ca.pem =================================================================== --- trunk/client/ca.pem 2011-05-04 14:34:24 UTC (rev 277) +++ trunk/client/ca.pem 2011-05-04 17:43:47 UTC (rev 278) @@ -1 +0,0 @@ -# Add your SSL certificate authority's cert(s) to this file Deleted: trunk/client/control =================================================================== --- trunk/client/control 2011-05-04 14:34:24 UTC (rev 277) +++ trunk/client/control 2011-05-04 17:43:47 UTC (rev 278) @@ -1,7 +0,0 @@ -Package: etch-client -Version: %VER%-1 -Maintainer: etc...@li... -Architecture: all -Depends: ruby, libopenssl-ruby1.8, facter, lsb-release, lsb-base -Description: Etch client - Deleted: trunk/client/depend =================================================================== --- trunk/client/depend 2011-05-04 14:34:24 UTC (rev 277) +++ trunk/client/depend 2011-05-04 17:43:47 UTC (rev 278) @@ -1,3 +0,0 @@ -P CSWruby -P CSWfacter - Deleted: trunk/client/dhparams =================================================================== --- trunk/client/dhparams 2011-05-04 14:34:24 UTC (rev 277) +++ trunk/client/dhparams 2011-05-04 17:43:47 UTC (rev 278) @@ -1,9 +0,0 @@ ------BEGIN DH PARAMETERS----- -MIIBCAKCAQEA3HySq1WdL67BCSRCJCZYMUIojAWAsvK63D3cOGk0wI9UeM/yeVhz -jTswvHOVPZFKIBg1Aeo2eAEdPryDnmjVTgvLbuWkCPouQhBCVsQ1El9ZcXPix1rC -tYsg4Kll1jgnwFoHf4xvjPnD/SqsASAiDxYlh4CFVyT1gLgSiUU0rIdudgO3agI5 -NgiyGOKwyHmNOOQSKA62M/JnoxcBDC7Nou3lqtHpR5yWsUz+csyk+hXZeUba97bm -M8OB0PmfK4Vo6JpdO+yc8hjeYBoMsH7g/l3Gm1JqUxxctcY/OuJ+2nkXwsD66E3D -yZCoiVd3u4OqAxNO/GG0iUmskjIvokMhUwIBAg== ------END DH PARAMETERS----- - Copied: trunk/client/etc/cron.d/etch (from rev 272, trunk/client/etch_cron) =================================================================== --- trunk/client/etc/cron.d/etch (rev 0) +++ trunk/client/etc/cron.d/etch 2011-05-04 17:43:47 UTC (rev 278) @@ -0,0 +1,10 @@ +# Run the etch client every hour +# If you want to disable etch updates do NOT comment out this cron job. +# Our next client update will just put it back anyway. +# Instead create /var/etch/disable_etch and add a comment as to +# why this box shouldn't be getting updates. Etch will notice +# that file and abort. disable_etch files with no comment will be +# removed by the System Administration team without warning. +MAILTO="" +0 * * * * root /usr/sbin/etch_cron_wrapper + Copied: trunk/client/etc/etch/ca.pem (from rev 272, trunk/client/ca.pem) =================================================================== --- trunk/client/etc/etch/ca.pem (rev 0) +++ trunk/client/etc/etch/ca.pem 2011-05-04 17:43:47 UTC (rev 278) @@ -0,0 +1 @@ +# Add your SSL certificate authority's cert(s) to this file Copied: trunk/client/etc/etch/dhparams (from rev 272, trunk/client/dhparams) =================================================================== --- trunk/client/etc/etch/dhparams (rev 0) +++ trunk/client/etc/etch/dhparams 2011-05-04 17:43:47 UTC (rev 278) @@ -0,0 +1,9 @@ +-----BEGIN DH PARAMETERS----- +MIIBCAKCAQEA3HySq1WdL67BCSRCJCZYMUIojAWAsvK63D3cOGk0wI9UeM/yeVhz +jTswvHOVPZFKIBg1Aeo2eAEdPryDnmjVTgvLbuWkCPouQhBCVsQ1El9ZcXPix1rC +tYsg4Kll1jgnwFoHf4xvjPnD/SqsASAiDxYlh4CFVyT1gLgSiUU0rIdudgO3agI5 +NgiyGOKwyHmNOOQSKA62M/JnoxcBDC7Nou3lqtHpR5yWsUz+csyk+hXZeUba97bm +M8OB0PmfK4Vo6JpdO+yc8hjeYBoMsH7g/l3Gm1JqUxxctcY/OuJ+2nkXwsD66E3D +yZCoiVd3u4OqAxNO/GG0iUmskjIvokMhUwIBAg== +-----END DH PARAMETERS----- + Copied: trunk/client/etc/etch.conf (from rev 272, trunk/client/etch.conf) =================================================================== --- trunk/client/etc/etch.conf (rev 0) +++ trunk/client/etc/etch.conf 2011-05-04 17:43:47 UTC (rev 278) @@ -0,0 +1,25 @@ +# The default server url is https://etch +#server = https://etch + +# Etch is usually run from cron, and cron usually executes jobs with a very +# minimal PATH environment variable setting. You may want etch to have a more +# complete PATH setting so that pre and post commands are more readily found. +#path = /bin:/usr/bin:/sbin:/usr/sbin + +# Etch can read configuration from a local directory rather than from a +# server. If set this will override the server setting. +#local = /var/etch/configs + +# Etch will try to find an SSH host key and use it to sign all requests to the +# etch server. Several standard locations for host keys are searched by +# default. If your host key is not in a standard location then you can point +# etch to it. +# See http://sourceforge.net/apps/trac/etch/wiki/ClientAuthentication +#key = /etc/ssh/ssh_host_rsa_key + +# Etch can send detailed results back to the server for viewing in the web UI +# and/or to a local log file. They are sent to the server by default. +# Note that SERVER is ignored when etch is running in local mode. +#detailed_results = SERVER +#detailed_results = /var/etch/results.log + Deleted: trunk/client/etch =================================================================== --- trunk/client/etch 2011-05-04 14:34:24 UTC (rev 277) +++ trunk/client/etch 2011-05-04 17:43:47 UTC (rev 278) @@ -1,111 +0,0 @@ -#!/usr/bin/ruby -w -############################################################################## -# Etch configuration file management tool -############################################################################## - -# Ensure we can find etchclient.rb -$:.unshift(File.dirname(__FILE__)) - -require 'optparse' -require 'etchclient' - -# -# Parse the command line options -# - -options = {} -@generateall = nil - -# Extra options to OptionParser reduce the amount of whitespace it introduces -# into the help message, making it easier to make the help message fit in a -# 80x24 window. -opts = OptionParser.new(nil, 24, ' ') -opts.banner = 'Usage: etch [options] [/path/to/config/file | command] [otherfile ...]' -opts.on('--generate-all', 'Request all configuration.') do |opt| - @generateall = opt -end -opts.on('--dry-run', '-n', 'Make no changes.') do |opt| - options[:dryrun] = opt -end -opts.on('--damp-run', "Perform a dry run but run 'setup' entries for files.") do |opt| - # Rather than sprinkle checks of two different variables throught the code, if - # we're asked to do a damp run then just set the dry run flag to a unique - # value. Then we can just check for that specific value at the one place where - # the two modes differ: enabling or disabling the execution of 'setup' - # entries. - options[:dryrun] = 'damp' -end -opts.on('--list-files', 'Just list the files that would be configured') do |opt| - options[:listfiles] = opt - # generate all is implied - @generateall = true - # Set :dryrun as a extra measure to make sure we don't change anything - options[:dryrun] = 'listfiles' -end -opts.on('--interactive', 'Prompt for confirmation before each change.') do |opt| - options[:interactive] = opt -end -opts.on('--full-file', 'Display full new file contents instead of a diff.') do |opt| - options[:fullfile] = opt -end -opts.on('--filename-only', 'Display filename of changed files instead of a diff.') do |opt| - options[:filenameonly] = opt -end -opts.on('--disable-force', 'Ignore the disable_etch file. Use with caution.') do |opt| - options[:disableforce] = opt -end -opts.on('--lock-force', 'Force the removal of any existing lockfiles.') do |opt| - options[:lockforce] = opt -end -opts.on('--local DIR', 'Read configuration from local directory, not server.') do |opt| - options[:local] = opt -end -opts.on('--server SERVER', 'Point etch to an alternate server.') do |opt| - options[:server] = opt -end -opts.on('--tag TAG', 'Request a specific repository tag from the server.') do |opt| - options[:tag] = opt -end -opts.on('--key PRIVATE_KEY', 'Use this private key for signing messages to server.') do |opt| - options[:key] = opt -end -opts.on('--test-root TESTDIR', 'For use by the test suite only.') do |opt| - options[:file_system_root] = opt -end -opts.on('--debug', 'Print lots of messages about what etch is doing.') do |opt| - options[:debug] = opt -end -opts.on('--version', 'Show etch client version.') do |opt| - puts Etch::Client::VERSION - exit -end -opts.on_tail('-h', '--help', 'Show this message.') do - puts opts - exit -end - -leftovers = opts.parse(ARGV) -files = [] -commands = [] -leftovers.each do |leftover| - if leftover[0,1] == File::SEPARATOR - files << leftover - else - commands << leftover - end -end - -# Display a usage message if the user did not specify a valid action to perform. -if files.empty? && commands.empty? && !@generateall - puts opts - exit -end - -# -# Do stuff -# - -etchclient = Etch::Client.new(options) -status = etchclient.process_until_done(files, commands) -exit status - Deleted: trunk/client/etch-client.spec =================================================================== --- trunk/client/etch-client.spec 2011-05-04 14:34:24 UTC (rev 277) +++ trunk/client/etch-client.spec 2011-05-04 17:43:47 UTC (rev 278) @@ -1,25 +0,0 @@ -Name: etch-client -Summary: Etch client -Version: %VER% -Release: 1 -Group: Applications/System -License: MIT -buildarch: noarch -Requires: ruby, facter, crontabs -BuildRoot: %{_builddir}/%{name}-buildroot -%description -Etch client - -%files -%defattr(-,root,root) -/usr/sbin/etch -/usr/sbin/etch_to_trunk -/usr/lib/ruby/site_ruby/1.8/etchclient.rb -/usr/lib/ruby/site_ruby/1.8/etch.rb -/usr/lib/ruby/site_ruby/1.8/versiontype.rb -/usr/share/man/man8/etch.8 -/etc/etch.conf -/etc/etch -/usr/sbin/etch_cron_wrapper -/etc/cron.d/etch - Deleted: trunk/client/etch.8 =================================================================== --- trunk/client/etch.8 2011-05-04 14:34:24 UTC (rev 277) +++ trunk/client/etch.8 2011-05-04 17:43:47 UTC (rev 278) @@ -1,229 +0,0 @@ -.TH etch 8 "October 2009" - -.SH NAME - -.B etch -\- Configuration management for Unix systems - -.SH SYNOPSIS - -.B etch -.RB [ --generate-all ] -.RB [ --dry-run | \-n ] -.RB [ --damp-run ] -.RB [ --interactive ] -.RB [ --full-file ] -.RB [ --filename-only ] -.RB [ --disable-force ] -.RB [ --lock-force ] -.RB [ --debug ] -.RB [ --local -.IR DIR ] -.RB [ --server -.IR SERVER ] -.RB [ --tag -.IR TAG ] -.RB [ --test-base -.IR TESTDIR ] -.RB [ --key -.IR PRIVATE_KEY ] -.RB [ --version ] -.RB [ --help | \-h ] -.RI [ "file ..." ] - -.SH DESCRIPTION - -Etch is a tool for managing the configuration of Unix systems. Etch can manage -text or binary files, links and directories. The contents of files can be -supplied from static files or generated on the fly by scripts or templates. -Permissions and ownership as well as any pre or post commands to run when -updating the file are configured in simple XML files. - -.SH OPTIONS -.TP -.B --generate-all -Request that the server generate and send over all available configuration. -Can be used instead of specifying specific files to request. -.TP -.B --dry-run | \-n -.B etch -will not make any changes to the system. Contents of generated config -files are displayed instead of being written to disk. -.TP -.B --damp-run -Perform an almost dry run, except that 'setup' entries for files are run. -Normally all setup/pre/post entries are ignored for a dry run. However, files -with setup entries will generally fail to build properly if the setup entry -hasn't been run. This allows you to preview the full and correct -configuration while making minimal changes to the system. -.TP -.B --interactive -Causes -.B etch -to pause before making each change and prompt the user for -confirmation. -.TP -.B --full-file -Normally -.B etch -will print a diff to show what changes it will make to a file. This will cause -.B etch -to display the full new file contents instead. Useful if the diff is hard to -read for a particular file. -.TP -.B --filename-only -Normally -.B etch -will print a diff to show what changes it will make to a file. This will cause -etch to display only the name of file to be changed. Useful on the initial -run during your system build process or other times when you want less output. -.TP -.B --disable-force -Ignore the disable_etch file. Use with caution. Typically used with ---interactive or --dry-run to evaluate what would happen if etch were -re-enabled. -.TP -.B --lock-force -.B Etch -does per-file internal locking as it runs to prevent problems with -simultaneous instances of the -.B etch -client stepping on each other. -.B Etch -automatically cleans up lockfiles over two hours old on the assumption that -any lockfiles that old were left behind by a previous instance that failed for -some (hopefully transient) reason. In a large environment you don't want to -have to run around manually cleaning up lockfiles every time a full disk or -unavailable package server or other transient failure causes -.B etch -to fail -temporarily. This option forces the removal of any existing lockfiles no -matter how old. Useful if a buggy configuration or local environmental issue -caused -.B etch -to abort and you want to immediately retry. -.TP -.BI --local " DIR" -Read configuration from a local directory rather than requesting it from -a server. -.TP -.BI --server " SERVER" -Point -.B etch -to an alternate server, specified in the form of a URL. -.TP -.BI --tag " TAG" -Request a specific repository tag from the server. Tags are directory paths -relative to /etc/etchserver by default. Thus examples might be -.I trunk -for /etc/etchserver/trunk, or -.I branches/mytestbranch -for /etc/etchserver/branches/mytestbranch. -.TP -.BI --key " PRIVATE_KEY" -Use an alternate SSH private key file for signing messages that are sent to -the server. -.TP -.BI --test-base " TESTDIR" -Use an alternate local working directory instead of /var/etch. Generally only -used for allowing the etch test suite to be run as a non-root user. -.TP -.B --debug -Print lots of messages about what etch is doing. -.TP -.B --version -Show the etch client version and exit. -.TP -.B --help | \-h -Display the etch usage message and exit. - -.SH FILES - -.TP -.B /etc/etch.conf -Optional configuration file for the etch client. The distribution ships with -an example file showing the available settings and their defaults. The file -syntax consists of "name = value" parameters. Lines starting with '#' and -empty lines are interpreted as comments. -.IP -.B server = -The URL for connecting to the server. http:// and https:// are supported. -.IP -.B path = -PATH environment etch should use when executing external commands. -.IP -.B local = -Etch can read configuration from a local directory rather than from a server. -If set this will override the server setting. -.IP -.B key = -SSH host key to use for authentication rather than standard system key. -.IP -.B detailed_results = -Etch can send detailed results back to the server for viewing in the web UI -and/or to a local log file. Value should be SERVER or the full path to a log -file. Setting may be specified multiple times to send logs to multiple -destinations. -.TP -.B /etc/etch/ca.pem -SSL certificate(s) needed to verify the -.B etch -server's identity. If -.B etch -is using a server with an https:// URL and if this file exists then -.B etch -will not proceed if the server's SSL certificate can't be verified against the -certs in this file. -.TP -.B /etc/etch/dhparams -The Diffie-Hellman parameters used as part of the SSL connection process. Etch -comes with a set and there's no need to generate your own, but a new set can -be generated via "openssl dhparam" if desired. If this file is not present the -Ruby SSL library will warn that it is using its internal default set of -parameters. -.TP -.B /var/etch/disable_etch -If this file is present -.B etch -will do nothing other than send a message to the -.B etch -server that it is disabled. Any text in this file will be included in -that message to the server and displayed locally. If you are disabling -.B etch -always put a note in this file indicating who you are, today's date, and why -you are disabling -.B etch -so that fellow administrators won't have to guess later why -.B etch -was disabled. Re-enabling -.B etch -after it has been disabled for a long -time can be time-consuming, as the person doing so must review any potential -changes that have been queued up and ensure that they won't interfere with the -current usage of the system. As such be thoughtful about whether disabling -.B etch -is necessary, and re-enable it as soon as possible. -.TP -.B /var/etch/history -A revision history of each -.B etch -managed file, stored using the RCS revision control system. -.TP -.B /var/etch/locks -Directory used by the -.B etch -internal locking mechanism. See the --lock-force option for more details. -.TP -.B /var/etch/orig -A backup of the original contents of each -.B etch -managed file as it was before etch first touched it. - -.SH DIAGNOSTICS - -See the --debug option and the server logs. - -.SH AUTHOR - -.B Etch -is designed and maintained by Jason Heiss Deleted: trunk/client/etch.conf =================================================================== --- trunk/client/etch.conf 2011-05-04 14:34:24 UTC (rev 277) +++ trunk/client/etch.conf 2011-05-04 17:43:47 UTC (rev 278) @@ -1,25 +0,0 @@ -# The default server url is https://etch -#server = https://etch - -# Etch is usually run from cron, and cron usually executes jobs with a very -# minimal PATH environment variable setting. You may want etch to have a more -# complete PATH setting so that pre and post commands are more readily found. -#path = /bin:/usr/bin:/sbin:/usr/sbin - -# Etch can read configuration from a local directory rather than from a -# server. If set this will override the server setting. -#local = /var/etch/configs - -# Etch will try to find an SSH host key and use it to sign all requests to the -# etch server. Several standard locations for host keys are searched by -# default. If your host key is not in a standard location then you can point -# etch to it. -# See http://sourceforge.net/apps/trac/etch/wiki/ClientAuthentication -#key = /etc/ssh/ssh_host_rsa_key - -# Etch can send detailed results back to the server for viewing in the web UI -# and/or to a local log file. They are sent to the server by default. -# Note that SERVER is ignored when etch is running in local mode. -#detailed_results = SERVER -#detailed_results = /var/etch/results.log - Deleted: trunk/client/etch.spec =================================================================== --- trunk/client/etch.spec 2011-05-04 14:34:24 UTC (rev 277) +++ trunk/client/etch.spec 2011-05-04 17:43:47 UTC (rev 278) @@ -1,44 +0,0 @@ -Name: etch -Version: %VER% -Release: 1%{?dist} -BuildArch: noarch -Summary: A tool for system configuration management -Group: Applications/System -License: MIT -URL: http://etch.sourceforge.net/ -Source0: http://downloads.sourceforge.net/project/etch/etch/%{version}/etch-%{version}.tar.gz -BuildRoot: %{_tmppath}/%{name}-%{version}-%{release}-root-%(%{__id_u} -n) - -BuildRequires: rubygem-rake -Requires: ruby(abi) = 1.8, facter - -# Per http://fedoraproject.org/wiki/Packaging:Ruby -%{!?ruby_sitelib: %global ruby_sitelib %(ruby -rrbconfig -e 'puts Config::CONFIG["sitelibdir"] ')} - -%description -A tool for system configuration management, i.e. management of the -configuration files of the operating system and core applications. Easy for a -professional system administrator to start using, yet scalable to large -and/or complex environments. - -%prep -%setup -q - -%build - -%install -rm -rf %{buildroot} -cd client && rake install[%{buildroot}] - -%clean -rm -rf %{buildroot} - -%files -%defattr(-,root,root,-) -%{_sbindir}/* -%{ruby_sitelib}/* -%{_mandir}/man8/* -%config(noreplace) %{_sysconfdir}/* - -%changelog - Deleted: trunk/client/etch_cron =================================================================== --- trunk/client/etch_cron 2011-05-04 14:34:24 UTC (rev 277) +++ trunk/client/etch_cron 2011-05-04 17:43:47 UTC (rev 278) @@ -1,10 +0,0 @@ -# Run the etch client every hour -# If you want to disable etch updates do NOT comment out this cron job. -# Our next client update will just put it back anyway. -# Instead create /var/etch/disable_etch and add a comment as to -# why this box shouldn't be getting updates. Etch will notice -# that file and abort. disable_etch files with no comment will be -# removed by the System Administration team without warning. -MAILTO="" -0 * * * * root /usr/sbin/etch_cron_wrapper - Deleted: trunk/client/etch_cron_wrapper =================================================================== --- trunk/client/etch_cron_wrapper 2011-05-04 14:34:24 UTC (rev 277) +++ trunk/client/etch_cron_wrapper 2011-05-04 17:43:47 UTC (rev 278) @@ -1,18 +0,0 @@ -#!/usr/bin/ruby -w - -require 'socket' -require 'digest/sha1' - -# Seed the random number generator with the hostname of this box so that -# we get a consistent random number. We want to run the registration at a -# consistent time on each individual box, but randomize the runs across -# the environment. -srand(Digest::SHA1.hexdigest(Socket.gethostname)[0,7].hex) - -# Cron job is set to run every hour -MAX_SLEEP = 60 * 60 - -sleep(rand(MAX_SLEEP)) - -exec('/usr/sbin/etch', '--generate-all') - Deleted: trunk/client/etch_to_trunk =================================================================== --- trunk/client/etch_to_trunk 2011-05-04 14:34:24 UTC (rev 277) +++ trunk/client/etch_to_trunk 2011-05-04 17:43:47 UTC (rev 278) @@ -1,77 +0,0 @@ -#!/usr/bin/ruby -w - -require 'nventory' -require 'time' -require 'optparse' - -ETCH_SERVER_TZ = 'UTC' # The etch servers run in UTC - -options = {} -opts = OptionParser.new -opts.banner = 'Usage: etch_to_trunk [options] <server1> [<server2> <server3>]' -opts.on('-u', '--username USERNAME', 'Username for connecting to nventory server.') do |opt| - options[:username] = opt -end -opts.on('-t', '--timezone TIMEZONE', 'Time zone of etch server.') do |opt| - options[:timezone] = opt -end -opts.on('--nv SERVER', 'Where nVentory server is running.') do |opt| - options[:nv_server] = opt -end -opts.on_tail('-h', '--help', 'Show this message.') do - puts opts - exit -end - -nodes = opts.parse(ARGV) - -if ARGV.length == 0 - puts opts - exit -end - -@username = options[:username] || ENV['LOGNAME'] -etch_server_tz = options[:timezone] || ETCH_SERVER_TZ - -if etch_server_tz - currentheadtag = Time.at(Time.now.utc + Time.zone_offset(etch_server_tz)).strftime('trunk-%Y%m%d-%H00') -else # if no timezone is specified then just use local time for the tag - currentheadtag = Time.now.strftime('trunk-%Y%m%d-%H00') -end - -# Find the requested clients -nv_server = options[:nv_server] -if nv_server - nvclient = NVentory::Client.new(:server=>"http://#{nv_server}") -else - nvclient = NVentory::Client.new -end -results = nvclient.get_objects('nodes', {}, { 'name' => nodes }, {}, {}) -nodes.each do |name| - if results.empty? && results[name].nil? - abort "No entry found for #{name}" - else - if !results[name]['config_mgmt_tag'].nil? && - !results[name]['config_mgmt_tag'].empty? - puts "Changing #{name} from #{results[name]['config_mgmt_tag']} to #{currentheadtag}" - else - puts "Setting #{name} to #{currentheadtag}" - end - end -end - -while true - print "Proceed? [y|n] " - response = $stdin.gets.chomp - if response == 'y' - break - elsif response == 'n' - exit - end -end - -# Update the clients -successcount = nvclient.set_objects('nodes', results, {'config_mgmt_tag' => currentheadtag}, @username) - -puts "#{File.basename($0)} operation succeeded for #{successcount} of #{results.size} nodes" - Deleted: trunk/client/etchclient.rb =================================================================== --- trunk/client/etchclient.rb 2011-05-04 14:34:24 UTC (rev 277) +++ trunk/client/etchclient.rb 2011-05-04 17:43:47 UTC (rev 278) @@ -1,2565 +0,0 @@ -############################################################################## -# Etch configuration file management tool library -############################################################################## - -# Ensure we can find etch.rb if run within the development directory structure -# This is roughly equivalent to "../server/lib" -serverlibdir = File.join(File.dirname(File.dirname(File.expand_path(__FILE__))), 'server', 'lib') -if File.exist?(serverlibdir) - $:.unshift(serverlibdir) -end - -begin - # Try loading facter w/o gems first so that we don't introduce a - # dependency on gems if it is not needed. - require 'facter' # Facter -rescue LoadError - require 'rubygems' - require 'facter' -end -require 'find' -require 'digest/sha1' # hexdigest -require 'openssl' # OpenSSL -require 'base64' # decode64, encode64 -require 'uri' -require 'net/http' -require 'net/https' -require 'rexml/document' -require 'fileutils' # copy, mkpath, rmtree -require 'fcntl' # Fcntl::O_* -require 'etc' # getpwnam, getgrnam -require 'tempfile' # Tempfile -require 'find' # Find.find -require 'cgi' -require 'timeout' -require 'logger' -require 'etch' - -class Etch::Client - VERSION = 'unset' - - CONFIRM_PROCEED = 1 - CONFIRM_SKIP = 2 - CONFIRM_QUIT = 3 - PRIVATE_KEY_PATHS = ["/etc/ssh/ssh_host_rsa_key", "/etc/ssh_host_rsa_key"] - DEFAULT_CONFIGDIR = '/etc' - DEFAULT_VARBASE = '/var/etch' - DEFAULT_DETAILED_RESULTS = ['SERVER'] - - # We need these in relation to the output capturing - ORIG_STDOUT = STDOUT.dup - ORIG_STDERR = STDERR.dup - - attr_reader :exec_once_per_run - - def initialize(options) - @server = options[:server] ? options[:server] : 'https://etch' - @tag = options[:tag] - @local = options[:local] ? File.expand_path(options[:local]) : nil - @debug = options[:debug] - @dryrun = options[:dryrun] - @listfiles = options[:listfiles] - @interactive = options[:interactive] - @filenameonly = options[:filenameonly] - @fullfile = options[:fullfile] - @key = options[:key] ? options[:key] : get_private_key_path - @disableforce = options[:disableforce] - @lockforce = options[:lockforce] - - @last_response = "" - - @configdir = DEFAULT_CONFIGDIR - @varbase = DEFAULT_VARBASE - - @file_system_root = '/' # Not sure if this needs to be more portable - # This option is only intended for use by the test suite - if options[:file_system_root] - @file_system_root = options[:file_system_root] - @varbase = File.join(@file_system_root, @varbase) - @configdir = File.join(@file_system_root, @configdir) - end - - @configfile = File.join(@configdir, 'etch.conf') - @detailed_results = [] - - if File.exist?(@configfile) - IO.foreach(@configfile) do |line| - line.chomp! - next if (line =~ /^\s*$/); # Skip blank lines - next if (line =~ /^\s*#/); # Skip comments - line.strip! # Remove leading/trailing whitespace - key, value = line.split(/\s*=\s*/, 2) - if key == 'server' - # A setting for the server to use which comes from upstream - # (generally from a command line option) takes precedence - # over the config file - if !options[:server] - @server = value - # Warn the user, as this could potentially be confusing - # if they don't realize there's a config file lying - # around - warn "Using server #{@server} from #{@configfile}" if @debug - else - # "command line override" isn't necessarily accurate, we don't - # know why the caller passed us an option to override the config - # file, but most of the time it will be due to a command line - # option and I want the message to be easily understood by users. - # If someone can come up with some better wording without turning - # the message into something as long as this comment that would be - # welcome. - warn "Ignoring 'server' option in #{@configfile} due to command line override" if @debug - end - elsif key == 'local' - if !options[:local] && !options[:server] - @local = value - warn "Using local directory #{@local} from #{@configfile}" if @debug - else - warn "Ignoring 'local' option in #{@configfile} due to command line override" if @debug - end - elsif key == 'key' - if !options[:key] - @key = value - warn "Using key #{@key} from #{@configfile}" if @debug - else - warn "Ignoring 'key' option in #{@configfile} due to command line override" if @debug - end - elsif key == 'path' - ENV['PATH'] = value - elsif key == 'detailed_results' - warn "Adding detailed results destination '#{value}'" if @debug - @detailed_results << value - end - end - end - - if @key && !File.readable?(@key) - @key = nil - end - if !@key - warn "No readable private key found, messages to server will not be signed and may be rejected depending on server configuration" - end - - if @detailed_results.empty? - @detailed_results = DEFAULT_DETAILED_RESULTS - end - - @origbase = File.join(@varbase, 'orig') - @historybase = File.join(@varbase, 'history') - @lockbase = File.join(@varbase, 'locks') - @requestbase = File.join(@varbase, 'requests') - - @facts = Facter.to_hash - if @facts['operatingsystemrelease'] - # Some versions of Facter have a bug that leaves extraneous - # whitespace on this fact. Work around that with strip. I.e. on - # CentOS you'll get '5 ' or '5.2 '. - @facts['operatingsystemrelease'].strip! - end - - if @local - logger = Logger.new(STDOUT) - dlogger = Logger.new(STDOUT) - if @debug - dlogger.level = Logger::DEBUG - else - dlogger.level = Logger::INFO - end - @etch = Etch.new(logger, dlogger) - else - # Make sure the server URL ends in a / so that we can append paths - # to it using URI.join - if @server !~ %r{/$} - @server << '/' - end - @filesuri = URI.join(@server, 'files') - @resultsuri = URI.join(@server, 'results') - - @blankrequest = {} - # If the user specified a non-standard key then override the - # sshrsakey fact so that authentication works - if @key - @facts['sshrsakey'] = IO.read(@key+'.pub').chomp.split[1] - end - @facts.each_pair { |key, value| @blankrequest["facts[#{key}]"] = value.to_s } - @blankrequest['fqdn'] = @facts['fqdn'] - if @debug - @blankrequest['debug'] = '1' - end - if @tag - @blankrequest['tag'] = @tag - end - end - - @locked_files = {} - @first_update = {} - @already_processed = {} - @exec_already_processed = {} - @exec_once_per_run = {} - @results = [] - # See start/stop_output_capture for these - @output_pipes = [] - - @lchown_supported = nil - @lchmod_supported = nil - end - - def process_until_done(files, commands) - # Our overall status. Will be reported to the server and used as the - # return value for this method. Command-line clients should use it as - # their exit value. Zero indicates no errors. - status = 0 - message = '' - - # A variable to collect filenames if operating in @listfiles mode - files_to_list = {} - - # Prep http instance - http = nil - if !@local - http = Net::HTTP.new(@filesuri.host, @filesuri.port) - if @filesuri.scheme == "https" - # Eliminate the OpenSSL "using default DH parameters" warning - if File.exist?(File.join(@configdir, 'etch', 'dhparams')) - dh = OpenSSL::PKey::DH.new(IO.read(File.join(@configdir, 'etch', 'dhparams'))) - Net::HTTP.ssl_context_accessor(:tmp_dh_callback) - http.tmp_dh_callback = proc { dh } - end - http.use_ssl = true - if File.exist?(File.join(@configdir, 'etch', 'ca.pem')) - http.ca_file = File.join(@configdir, 'etch', 'ca.pem') - http.verify_mode = OpenSSL::SSL::VERIFY_PEER - elsif File.directory?(File.join(@configdir, 'etch', 'ca')) - http.ca_path = File.join(@configdir, 'etch', 'ca') - http.verify_mode = OpenSSL::SSL::VERIFY_PEER - end - end - http.start - end - - # catch/throw for expected/non-error events that end processing - # begin/raise for error events that end processing - catch :stop_processing do - begin - enabled, message = check_for_disable_etch_file - if !enabled - # 200 is the arbitrarily picked exit value indicating - # that etch is disabled - status = 200 - throw :stop_processing - end - remove_stale_lock_files - - # Assemble the initial request - request = nil - if @local - request = {} - if files && !files.empty? - request[:files] = {} - files.each do |file| - request[:files][file] = {:orig => save_orig(file)} - local_requests = get_local_requests(file) - if local_requests - request[:files][file][:local_requests] = local_requests - end - end - end - if commands && !commands.empty? - request[:commands] = {} - commands.each do |command| - request[:commands][command] = {} - end - end - else - request = get_blank_request - if (files && !files.empty?) || (commands && !commands.empty?) - if files - files.each do |file| - request["files[#{CGI.escape(file)}][sha1sum]"] = - get_orig_sum(file) - local_requests = get_local_requests(file) - if local_requests - request["files[#{CGI.escape(file)}][local_requests]"] = - local_requests - end - end - end - if commands - commands.each do |command| - request["commands[#{CGI.escape(command)}]"] = '1' - end - end - else - request['files[GENERATEALL]'] = '1' - end - end - - # - # Loop back and forth with the server sending requests for files and - # responding to the server's requests for original contents or sums - # it needs - # - - Signal.trap('EXIT') do - STDOUT.reopen(ORIG_STDOUT) - STDERR.reopen(ORIG_STDERR) - unlock_all_files - end - - # It usually takes a few back and forth exchanges with the server to - # exchange all needed data and get a complete set of configuration. - # The number of iterations is capped at 10 to prevent any unplanned - # infinite loops. The limit of 10 was chosen somewhat arbitrarily but - # seems fine in practice. - 10.times do - # - # Send request to server - # - - responsedata = {} - if @local - results = @etch.generate(@local, @facts, request) - # FIXME: Etch#generate returns parsed XML using whatever XML - # library it happens to use. In order to avoid re-parsing - # the XML we'd have to use the XML abstraction code from Etch - # everwhere here. - # Until then re-parse the XML using REXML. - #responsedata[:configs] = results[:configs] - responsedata[:configs] = {} - results[:configs].each {|f,c| responsedata[:configs][f] = REXML::Document.new(c.to_s) } - responsedata[:need_sums] = {} - responsedata[:need_origs] = results[:need_orig] - #responsedata[:allcommands] = results[:allcommands] - responsedata[:allcommands] = {} - results[:allcommands].each {|cn,c| responsedata[:allcommands][cn] = REXML::Document.new(c.to_s) } - responsedata[:retrycommands] = results[:retrycommands] - else - puts "Sending request to server #{@filesuri}: #{request.inspect}" if (@debug) - post = Net::HTTP::Post.new(@filesuri.path) - post.set_form_data(request) - sign_post!(post, @key) - response = http.request(post) - if !response.kind_of?(Net::HTTPSuccess) - $stderr.puts response.body - # error! raises an exception - response.error! - end - puts "Response from server:\n'#{response.body}'" if (@debug) - if !response.body.nil? && !response.body.empty? - response_xml = REXML::Document.new(response.body) - responsedata[:configs] = {} - response_xml.elements.each('/files/configs/config') do |config| - file = config.attributes['filename'] - # We have to make a new document so that XPath paths are - # referenced relative to the configuration for this - # specific file. - #responsedata[:configs][file] = REXML::Document.new(response_xml.elements["/files/configs/config[@filename='#{file}']"].to_s) - responsedata[:configs][file] = REXML::Document.new(config.to_s) - end - responsedata[:need_sums] = {} - response_xml.elements.each('/files/need_sums/need_sum') do |ns| - responsedata[:need_sums][ns.text] = true - end - responsedata[:need_origs] = {} - response_xml.elements.each('/files/need_origs/need_orig') do |no| - responsedata[:need_origs][no.text] = true - end - responsedata[:allcommands] = {} - response_xml.elements.each('/files/allcommands/commands') do |command| - commandname = command.attributes['commandname'] - # We have to make a new document so that XPath paths are - # referenced relative to the configuration for this - # specific file. - #responsedata[:allcommands][commandname] = REXML::Document.new(response_xml.root.elements["/files/allcommands/commands[@commandname='#{commandname}']"].to_s) - responsedata[:allcommands][commandname] = REXML::Document.new(command.to_s) - end - responsedata[:retrycommands] = {} - response_xml.elements.each('/files/retrycommands/retrycommand') do |rc| - responsedata[:retrycommands][rc.text] = true - end - else - puts " Response is empty" if (@debug) - break - end - end - - # - # Process the response from the server - # - - # Prep a clean request hash - if @local - request = {} - if !responsedata[:need_origs].empty? - request[:files] = {} - end - if !responsedata[:retrycommands].empty? - request[:commands] = {} - end - else - request = get_blank_request - end - - # With generateall we expect to make at least two round trips - # to the server. - # 1) Send GENERATEALL request, get back a list of need_sums - # 2) Send sums, possibly get back some need_origs - # 3) Send origs, get back generated files - need_to_loop = false - reset_already_processed - # Process configs first, as they may contain setup entries that are - # needed to create the original files. - responsedata[:configs].each_key do |file| - puts "Processing config for #{file}" if (@debug) - if !@listfiles - continue_processing = process_file(file, responsedata) - if !continue_processing - throw :stop_processing - end - else - files_to_list[file] = true - end - end - responsedata[:need_sums].each_key do |need_sum| - puts "Processing request for sum of #{need_sum}" if (@debug) - if @local - # If this happens we screwed something up, the local mode - # code never requests sums. - raise "No support for sums in local mode" - else - request["files[#{CGI.escape(need_sum)}][sha1sum]"] = - get_orig_sum(need_sum) - end - local_requests = get_local_requests(need_sum) - if local_requests - if @local - request[:files][need_sum][:local_requests] ... [truncated message content] |
From: <jh...@us...> - 2011-05-04 14:34:36
|
Revision: 277 http://etch.svn.sourceforge.net/etch/?rev=277&view=rev Author: jheiss Date: 2011-05-04 14:34:24 +0000 (Wed, 04 May 2011) Log Message: ----------- Restrict will_paginate to the 2.x series, we're not compatible with some of the changes in the 3.x series currently in beta. Modified Paths: -------------- trunk/server/config/environment.rb Modified: trunk/server/config/environment.rb =================================================================== --- trunk/server/config/environment.rb 2011-05-04 05:38:57 UTC (rev 276) +++ trunk/server/config/environment.rb 2011-05-04 14:34:24 UTC (rev 277) @@ -25,7 +25,7 @@ # config.gem "bj" # config.gem "hpricot", :version => '0.6', :source => "http://code.whytheluckystiff.net" # config.gem "aws-s3", :lib => "aws/s3" - config.gem 'will_paginate' + config.gem 'will_paginate', :version => '~> 2.3.15' config.gem 'searchlogic' # Only load the plugins named here, in the order given. By default, all plugins This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site. |
From: <jh...@us...> - 2011-05-04 05:39:03
|
Revision: 276 http://etch.svn.sourceforge.net/etch/?rev=276&view=rev Author: jheiss Date: 2011-05-04 05:38:57 +0000 (Wed, 04 May 2011) Log Message: ----------- Find.find in ruby 1.9 doesn't like being called with a non-existent target. So check that directories exist before calling Find.find against them. Fix a few "shadowing outer local variable" warnings from ruby 1.9 Modified Paths: -------------- trunk/client/etchclient.rb trunk/server/lib/etch.rb Modified: trunk/client/etchclient.rb =================================================================== --- trunk/client/etchclient.rb 2011-05-04 05:37:12 UTC (rev 275) +++ trunk/client/etchclient.rb 2011-05-04 05:38:57 UTC (rev 276) @@ -29,6 +29,7 @@ require 'fcntl' # Fcntl::O_* require 'etc' # getpwnam, getgrnam require 'tempfile' # Tempfile +require 'find' # Find.find require 'cgi' require 'timeout' require 'logger' @@ -1803,7 +1804,7 @@ puts "Original file #{file} doesn't exist, saving that state permanently as #{origpath}" end if proceed - File.open(origpath, 'w') { |file| } if (!@dryrun) + File.open(origpath, 'w') { |origfile| } if (!@dryrun) end end @@ -2014,7 +2015,7 @@ else # If there's no file to back up then leave a marker file so # that restore_backup does the right thing - File.open("#{backuppath}.NOORIG", "w") { |file| } + File.open("#{backuppath}.NOORIG", "w") { |markerfile| } end end @@ -2375,7 +2376,7 @@ begin fd = IO::sysopen(lockpath, Fcntl::O_WRONLY|Fcntl::O_CREAT|Fcntl::O_EXCL) puts "Lock acquired for #{file}" if (@debug) - f = IO.open(fd) { |f| f.puts $$ } + f = IO.open(fd) { |lockfile| lockfile.puts $$ } @locked_files[file] = true return rescue Errno::EEXIST @@ -2420,13 +2421,15 @@ # and can be removed. If told to force we remove all lockfiles. def remove_stale_lock_files twohoursago = Time.at(Time.now - 60 * 60 * 2) - Find.find(@lockbase) do |file| - next unless file =~ /\.LOCK$/ - next unless File.file?(file) - - if @lockforce || File.mtime(file) < twohoursago - puts "Removing stale lock file #{file}" - File.delete(file) + if File.exist?(@lockbase) + Find.find(@lockbase) do |file| + next unless file =~ /\.LOCK$/ + next unless File.file?(file) + + if @lockforce || File.mtime(file) < twohoursago + puts "Removing stale lock file #{file}" + File.delete(file) + end end end end Modified: trunk/server/lib/etch.rb =================================================================== --- trunk/server/lib/etch.rb 2011-05-04 05:37:12 UTC (rev 275) +++ trunk/server/lib/etch.rb 2011-05-04 05:38:57 UTC (rev 276) @@ -170,10 +170,12 @@ filelist = [] if request.empty? @dlogger.debug "Building complete file list for request from #{@fqdn}" - Find.find(@sourcebase) do |path| - if File.directory?(path) && File.exist?(File.join(path, 'config.xml')) - # Strip @sourcebase from start of path - filelist << path.sub(Regexp.new('^' + Regexp.escape(@sourcebase)), '') + if File.exist?(@sourcebase) + Find.find(@sourcebase) do |path| + if File.directory?(path) && File.exist?(File.join(path, 'config.xml')) + # Strip @sourcebase from start of path + filelist << path.sub(Regexp.new('^' + Regexp.escape(@sourcebase)), '') + end end end elsif request[:files] @@ -206,9 +208,11 @@ commandnames = [] if request.empty? @dlogger.debug "Building complete configuration commands for request from #{@fqdn}" - Find.find(@commandsbase) do |path| - if File.directory?(path) && File.exist?(File.join(path, 'commands.xml')) - commandnames << File.basename(path) + if File.exist?(@commandsbase) + Find.find(@commandsbase) do |path| + if File.directory?(path) && File.exist?(File.join(path, 'commands.xml')) + commandnames << File.basename(path) + end end end elsif request[:commands] This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site. |
From: <jh...@us...> - 2011-05-04 05:37:18
|
Revision: 275 http://etch.svn.sourceforge.net/etch/?rev=275&view=rev Author: jheiss Date: 2011-05-04 05:37:12 +0000 (Wed, 04 May 2011) Log Message: ----------- Ensure that the client and server are invoked with the same ruby the user used to invoke the test suite. This allows us to test etch under various ruby versions, etc. Modified Paths: -------------- trunk/test/etchtest.rb Modified: trunk/test/etchtest.rb =================================================================== --- trunk/test/etchtest.rb 2011-05-04 05:02:05 UTC (rev 274) +++ trunk/test/etchtest.rb 2011-05-04 05:37:12 UTC (rev 275) @@ -6,7 +6,10 @@ require 'tempfile' require 'fileutils' require 'net/http' +require 'rbconfig' +RUBY = File.join(*RbConfig::CONFIG.values_at("bindir", "ruby_install_name")) + RbConfig::CONFIG["EXEEXT"] + module EtchTests # Roughly ../server and ../client SERVERDIR = "#{File.dirname(File.dirname(File.expand_path(__FILE__)))}/server" @@ -47,7 +50,8 @@ repo = tempdir # Put the basic files into that directory needed for a basic etch tree - FileUtils.cp_r(Dir.glob("#{File.dirname(__FILE__)}/testrepo/*"), repo) + # :preserve to maintain executable permissions on the scripts + FileUtils.cp_r(Dir.glob("#{File.dirname(__FILE__)}/testrepo/*"), repo, :preserve => true) hostname = `facter fqdn`.chomp nodegroups_string = '' @@ -127,9 +131,9 @@ end else if UNICORN - exec("cd #{SERVERDIR} && unicorn_rails -p #{port}") + exec("cd #{SERVERDIR} && #{RUBY} `which unicorn_rails` -p #{port}") else - exec("cd #{SERVERDIR} && ./script/server -p #{port}") + exec("cd #{SERVERDIR} && #{RUBY} ./script/server -p #{port}") end end {:port => port, :pid => pid, :repo => serverbase} @@ -171,7 +175,7 @@ puts "#" #sleep 3 end - result = system("ruby #{CLIENTDIR}/etch --generate-all --test-root=#{testroot} #{server} #{key} #{extra_args}") + result = system("#{RUBY} #{CLIENTDIR}/etch --generate-all --test-root=#{testroot} #{server} #{key} #{extra_args}") if options[:errors_expected] assert(!result, options[:testname]) else This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site. |
From: <jh...@us...> - 2011-05-04 05:02:11
|
Revision: 274 http://etch.svn.sourceforge.net/etch/?rev=274&view=rev Author: jheiss Date: 2011-05-04 05:02:05 +0000 (Wed, 04 May 2011) Log Message: ----------- Change line that requires etchtest to be compatible with ruby 1.9 Modified Paths: -------------- trunk/Rakefile trunk/test/test_actions.rb trunk/test/test_attributes.rb trunk/test/test_auth.rb trunk/test/test_commands.rb trunk/test/test_conf.rb trunk/test/test_delete.rb trunk/test/test_depend.rb trunk/test/test_file.rb trunk/test/test_history.rb trunk/test/test_link.rb trunk/test/test_local_requests.rb trunk/test/test_nodegroups.rb trunk/test/test_options.rb trunk/test/test_outputcapture.rb trunk/test/test_scripts.rb trunk/test/test_transitions.rb Modified: trunk/Rakefile =================================================================== --- trunk/Rakefile 2011-05-04 05:01:00 UTC (rev 273) +++ trunk/Rakefile 2011-05-04 05:02:05 UTC (rev 274) @@ -3,9 +3,9 @@ # rake test Rake::TestTask.new do |t| # If the user hasn't already set the xmllib environment variable then set it - # to use LibXML so that the tests involving DTD validation are run. + # to use nokogiri so that the tests involving DTD validation are run. if !ENV['xmllib'] - ENV['xmllib'] = 'libxml' + ENV['xmllib'] = 'nokogiri' end t.verbose = true Modified: trunk/test/test_actions.rb =================================================================== --- trunk/test/test_actions.rb 2011-05-04 05:01:00 UTC (rev 273) +++ trunk/test/test_actions.rb 2011-05-04 05:02:05 UTC (rev 274) @@ -4,7 +4,7 @@ # Test etch's handling of various actions: pre, post, setup, test, etc. # -require File.join(File.dirname(__FILE__), 'etchtest') +require "./#{File.dirname(__FILE__)}/etchtest" class EtchActionTests < Test::Unit::TestCase include EtchTests Modified: trunk/test/test_attributes.rb =================================================================== --- trunk/test/test_attributes.rb 2011-05-04 05:01:00 UTC (rev 273) +++ trunk/test/test_attributes.rb 2011-05-04 05:02:05 UTC (rev 274) @@ -4,7 +4,7 @@ # Test etch's handling of attribute filtering in config.xml files # -require File.join(File.dirname(__FILE__), 'etchtest') +require "./#{File.dirname(__FILE__)}/etchtest" require 'rubygems' # Might be needed to find facter require 'facter' Modified: trunk/test/test_auth.rb =================================================================== --- trunk/test/test_auth.rb 2011-05-04 05:01:00 UTC (rev 273) +++ trunk/test/test_auth.rb 2011-05-04 05:02:05 UTC (rev 274) @@ -4,7 +4,7 @@ # Test etch's handling of client authentication # -require File.join(File.dirname(__FILE__), 'etchtest') +require "./#{File.dirname(__FILE__)}/etchtest" require 'net/http' require 'rexml/document' begin Modified: trunk/test/test_commands.rb =================================================================== --- trunk/test/test_commands.rb 2011-05-04 05:01:00 UTC (rev 273) +++ trunk/test/test_commands.rb 2011-05-04 05:02:05 UTC (rev 274) @@ -4,7 +4,7 @@ # Test etch's handling of configuration commands # -require File.join(File.dirname(__FILE__), 'etchtest') +require "./#{File.dirname(__FILE__)}/etchtest" class EtchCommandTests < Test::Unit::TestCase include EtchTests Modified: trunk/test/test_conf.rb =================================================================== --- trunk/test/test_conf.rb 2011-05-04 05:01:00 UTC (rev 273) +++ trunk/test/test_conf.rb 2011-05-04 05:02:05 UTC (rev 274) @@ -4,7 +4,7 @@ # Test etch's handling of its configuration file, etch.conf # -require File.join(File.dirname(__FILE__), 'etchtest') +require "./#{File.dirname(__FILE__)}/etchtest" require 'net/http' require 'rexml/document' require 'cgi' Modified: trunk/test/test_delete.rb =================================================================== --- trunk/test/test_delete.rb 2011-05-04 05:01:00 UTC (rev 273) +++ trunk/test/test_delete.rb 2011-05-04 05:02:05 UTC (rev 274) @@ -4,7 +4,7 @@ # Test etch's handling of deleting files # -require File.join(File.dirname(__FILE__), 'etchtest') +require "./#{File.dirname(__FILE__)}/etchtest" class EtchDeleteTests < Test::Unit::TestCase include EtchTests Modified: trunk/test/test_depend.rb =================================================================== --- trunk/test/test_depend.rb 2011-05-04 05:01:00 UTC (rev 273) +++ trunk/test/test_depend.rb 2011-05-04 05:02:05 UTC (rev 274) @@ -4,7 +4,7 @@ # Test etch's handling of dependencies # -require File.join(File.dirname(__FILE__), 'etchtest') +require "./#{File.dirname(__FILE__)}/etchtest" class EtchDependTests < Test::Unit::TestCase include EtchTests Modified: trunk/test/test_file.rb =================================================================== --- trunk/test/test_file.rb 2011-05-04 05:01:00 UTC (rev 273) +++ trunk/test/test_file.rb 2011-05-04 05:02:05 UTC (rev 274) @@ -4,7 +4,7 @@ # Test etch's handling of creating and updating regular files # -require File.join(File.dirname(__FILE__), 'etchtest') +require "./#{File.dirname(__FILE__)}/etchtest" class EtchFileTests < Test::Unit::TestCase include EtchTests Modified: trunk/test/test_history.rb =================================================================== --- trunk/test/test_history.rb 2011-05-04 05:01:00 UTC (rev 273) +++ trunk/test/test_history.rb 2011-05-04 05:02:05 UTC (rev 274) @@ -5,7 +5,7 @@ # history files # -require File.join(File.dirname(__FILE__), 'etchtest') +require "./#{File.dirname(__FILE__)}/etchtest" class EtchHistoryTests < Test::Unit::TestCase include EtchTests Modified: trunk/test/test_link.rb =================================================================== --- trunk/test/test_link.rb 2011-05-04 05:01:00 UTC (rev 273) +++ trunk/test/test_link.rb 2011-05-04 05:02:05 UTC (rev 274) @@ -4,7 +4,7 @@ # Test etch's handling of creating and updating symbolic links # -require File.join(File.dirname(__FILE__), 'etchtest') +require "./#{File.dirname(__FILE__)}/etchtest" require 'pathname' class EtchLinkTests < Test::Unit::TestCase Modified: trunk/test/test_local_requests.rb =================================================================== --- trunk/test/test_local_requests.rb 2011-05-04 05:01:00 UTC (rev 273) +++ trunk/test/test_local_requests.rb 2011-05-04 05:02:05 UTC (rev 274) @@ -4,7 +4,7 @@ # Test etch's handling of local requests # -require File.join(File.dirname(__FILE__), 'etchtest') +require "./#{File.dirname(__FILE__)}/etchtest" class EtchLocalRequestsTests < Test::Unit::TestCase include EtchTests Modified: trunk/test/test_nodegroups.rb =================================================================== --- trunk/test/test_nodegroups.rb 2011-05-04 05:01:00 UTC (rev 273) +++ trunk/test/test_nodegroups.rb 2011-05-04 05:02:05 UTC (rev 274) @@ -4,7 +4,7 @@ # Test etch's handling of node groups and the node group hierarchy # -require File.join(File.dirname(__FILE__), 'etchtest') +require "./#{File.dirname(__FILE__)}/etchtest" class EtchNodeGroupTests < Test::Unit::TestCase include EtchTests Modified: trunk/test/test_options.rb =================================================================== --- trunk/test/test_options.rb 2011-05-04 05:01:00 UTC (rev 273) +++ trunk/test/test_options.rb 2011-05-04 05:02:05 UTC (rev 274) @@ -4,7 +4,7 @@ # Test command line options to etch client # -require File.join(File.dirname(__FILE__), 'etchtest') +require "./#{File.dirname(__FILE__)}/etchtest" require 'webrick' class EtchOptionTests < Test::Unit::TestCase Modified: trunk/test/test_outputcapture.rb =================================================================== --- trunk/test/test_outputcapture.rb 2011-05-04 05:01:00 UTC (rev 273) +++ trunk/test/test_outputcapture.rb 2011-05-04 05:02:05 UTC (rev 274) @@ -4,7 +4,7 @@ # Test output capturing # -require File.join(File.dirname(__FILE__), 'etchtest') +require "./#{File.dirname(__FILE__)}/etchtest" require 'timeout' $: << EtchTests::CLIENTDIR $: << File.join(EtchTests::SERVERDIR, 'lib') Modified: trunk/test/test_scripts.rb =================================================================== --- trunk/test/test_scripts.rb 2011-05-04 05:01:00 UTC (rev 273) +++ trunk/test/test_scripts.rb 2011-05-04 05:02:05 UTC (rev 274) @@ -5,7 +5,7 @@ # creation of links and directories, and control the deletion of files # -require File.join(File.dirname(__FILE__), 'etchtest') +require "./#{File.dirname(__FILE__)}/etchtest" class EtchScriptTests < Test::Unit::TestCase include EtchTests Modified: trunk/test/test_transitions.rb =================================================================== --- trunk/test/test_transitions.rb 2011-05-04 05:01:00 UTC (rev 273) +++ trunk/test/test_transitions.rb 2011-05-04 05:02:05 UTC (rev 274) @@ -5,7 +5,7 @@ # file, etc.) # -require File.join(File.dirname(__FILE__), 'etchtest') +require "./#{File.dirname(__FILE__)}/etchtest" class EtchTransitionTests < Test::Unit::TestCase include EtchTests This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site. |
From: <jh...@us...> - 2011-05-04 05:01:06
|
Revision: 273 http://etch.svn.sourceforge.net/etch/?rev=273&view=rev Author: jheiss Date: 2011-05-04 05:01:00 +0000 (Wed, 04 May 2011) Log Message: ----------- Add a file for misc tests, starting with test_empty_repository to try to reproduce an issue reported by a user on the mailing list Added Paths: ----------- trunk/test/test_misc.rb Added: trunk/test/test_misc.rb =================================================================== --- trunk/test/test_misc.rb (rev 0) +++ trunk/test/test_misc.rb 2011-05-04 05:01:00 UTC (rev 273) @@ -0,0 +1,40 @@ +#!/usr/bin/ruby -w + +# +# Test miscellaneous items that don't fit elsewhere +# + +require "./#{File.dirname(__FILE__)}/etchtest" +require 'webrick' + +class EtchMiscTests < Test::Unit::TestCase + include EtchTests + + def setup + # Generate a file to use as our etch target/destination + @targetfile = released_tempfile + #puts "Using #{@targetfile} as target file" + + # Generate a directory for our test repository + @repodir = initialize_repository + @server = get_server(@repodir) + + # Create a directory to use as a working directory for the client + @testroot = tempdir + #puts "Using #{@testroot} as client working directory" + end + + def test_empty_repository + # Does etch behave properly if the repository is empty? I.e. no source or + # commands directories. + testname = 'empty repository' + run_etch(@server, @testroot, :testname => testname) + end + + def teardown + remove_repository(@repodir) + FileUtils.rm_rf(@testroot) + FileUtils.rm_rf(@targetfile) + end +end + This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site. |
From: <jh...@us...> - 2011-04-12 06:59:21
|
Revision: 272 http://etch.svn.sourceforge.net/etch/?rev=272&view=rev Author: jheiss Date: 2011-04-12 06:59:15 +0000 (Tue, 12 Apr 2011) Log Message: ----------- Fix the line that generates the distribution tarball to properly exclude databases and log files. Modified Paths: -------------- Rakefile Modified: Rakefile =================================================================== --- Rakefile 2011-04-12 06:49:05 UTC (rev 271) +++ Rakefile 2011-04-12 06:59:15 UTC (rev 272) @@ -18,7 +18,7 @@ task :dist do rm_rf(DIST) mkdir(DIST) - system("(cd #{TAGDIR} && find client server test etchserver-* LICENSE README VERSION | grep -v '\.svn' | grep -v server/log/*.log | grep -v server/db/*.sqlite3 | cpio -pdum ../../#{DIST})") + system("(cd #{TAGDIR} && find client server test etchserver-* LICENSE README VERSION | grep -v '\\.svn' | grep -v server/log/.*.log | grep -v server/db/.*.sqlite3 | cpio -pdum ../../#{DIST})") system("tar czf #{DIST}.tar.gz #{DIST}") rm_rf(DIST) system("openssl md5 #{DIST}.tar.gz > #{DIST}.tar.gz.md5") This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site. |
From: <jh...@us...> - 2011-04-12 06:49:11
|
Revision: 271 http://etch.svn.sourceforge.net/etch/?rev=271&view=rev Author: jheiss Date: 2011-04-12 06:49:05 +0000 (Tue, 12 Apr 2011) Log Message: ----------- Tag 3.19.0 release Modified Paths: -------------- Rakefile tags/release-3.19.0/VERSION Added Paths: ----------- tags/release-3.19.0/ Modified: Rakefile =================================================================== --- Rakefile 2011-04-12 06:44:23 UTC (rev 270) +++ Rakefile 2011-04-12 06:49:05 UTC (rev 271) @@ -1,4 +1,4 @@ -ETCHVER = '3.18.0' +ETCHVER = '3.19.0' TAGNAME = "release-#{ETCHVER}" TAGDIR = "tags/#{TAGNAME}" DIST = "etch-#{ETCHVER}" Modified: tags/release-3.19.0/VERSION =================================================================== --- trunk/VERSION 2011-04-12 06:44:23 UTC (rev 270) +++ tags/release-3.19.0/VERSION 2011-04-12 06:49:05 UTC (rev 271) @@ -1 +1 @@ -trunk +3.19.0 This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site. |
From: <jh...@us...> - 2011-04-12 06:44:31
|
Revision: 270 http://etch.svn.sourceforge.net/etch/?rev=270&view=rev Author: jheiss Date: 2011-04-12 06:44:23 +0000 (Tue, 12 Apr 2011) Log Message: ----------- Switch to rails 2.3.11 Modified Paths: -------------- trunk/server/config/environment.rb Modified: trunk/server/config/environment.rb =================================================================== --- trunk/server/config/environment.rb 2011-04-12 06:20:09 UTC (rev 269) +++ trunk/server/config/environment.rb 2011-04-12 06:44:23 UTC (rev 270) @@ -5,7 +5,7 @@ # ENV['RAILS_ENV'] ||= 'production' # Specifies gem version of Rails to use when vendor/rails is not present -RAILS_GEM_VERSION = '2.3.10' unless defined? RAILS_GEM_VERSION +RAILS_GEM_VERSION = '2.3.11' unless defined? RAILS_GEM_VERSION # Bootstrap the Rails environment, frameworks, and default configuration require File.join(File.dirname(__FILE__), 'boot') This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site. |
From: <jh...@us...> - 2011-04-12 06:20:15
|
Revision: 269 http://etch.svn.sourceforge.net/etch/?rev=269&view=rev Author: jheiss Date: 2011-04-12 06:20:09 +0000 (Tue, 12 Apr 2011) Log Message: ----------- When reading in the node group hierarchy use the xmlattrvalue method rather than directly talking to the underlying XML library. The code to do so was not compatible with nokogiri. Modified Paths: -------------- trunk/server/lib/etch.rb Modified: trunk/server/lib/etch.rb =================================================================== --- trunk/server/lib/etch.rb 2011-04-12 06:08:33 UTC (rev 268) +++ trunk/server/lib/etch.rb 2011-04-12 06:20:09 UTC (rev 269) @@ -135,7 +135,7 @@ Etch.xmleach(@nodegroups_xml, '/nodegroups/nodegroup') do |parent| Etch.xmleach(parent, 'child') do |child| @group_hierarchy[Etch.xmltext(child)] = [] if !@group_hierarchy[Etch.xmltext(child)] - @group_hierarchy[Etch.xmltext(child)] << parent.attributes['name'] + @group_hierarchy[Etch.xmltext(child)] << Etch.xmlattrvalue(parent, 'name') end end This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site. |