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: <jh...@us...> - 2009-09-23 00:53:27
|
Revision: 94
http://etch.svn.sourceforge.net/etch/?rev=94&view=rev
Author: jheiss
Date: 2009-09-23 00:53:21 +0000 (Wed, 23 Sep 2009)
Log Message:
-----------
Add test of filename with special characters.
Modified Paths:
--------------
trunk/test/file.rb
Modified: trunk/test/file.rb
===================================================================
--- trunk/test/file.rb 2009-09-23 00:53:07 UTC (rev 93)
+++ trunk/test/file.rb 2009-09-23 00:53:21 UTC (rev 94)
@@ -652,7 +652,45 @@
# Verify that the file contents didn't change
assert_equal(origcontents, get_file_contents(@targetfile), 'contradictory script instructions')
+ end
+
+ def test_filename_with_special_characters
+ #
+ # Test filename with special characters
+ #
+ testname = 'filename with special characters'
+ # + because urlencode and CGI.escape handle it differently, so we want to
+ # catch any possible mismatches where one format is used on encode and the
+ # other on decode.
+ # [] because they have special meaning to the Rails parameter parsing and
+ # we want to make sure that doesn't get confused.
+ specialtargetfile = "#{@targetfile}+[]"
+ FileUtils.mkdir_p("#{@repodir}/source/#{specialtargetfile}")
+ File.open("#{@repodir}/source/#{specialtargetfile}/config.xml", 'w') do |file|
+ file.puts <<-EOF
+ <config>
+ <file>
+ <warning_file/>
+ <source>
+ <plain>source</plain>
+ </source>
+ </file>
+ </config>
+ EOF
+ end
+
+ sourcecontents = "Test #{testname}\n"
+ File.open("#{@repodir}/source/#{specialtargetfile}/source", 'w') do |file|
+ file.write(sourcecontents)
+ end
+
+ # Run etch
+ #puts "Running '#{testname}' test"
+ run_etch(@port, @testbase)
+
+ # Verify that the file was created properly
+ assert_equal(sourcecontents, get_file_contents(specialtargetfile), testname)
end
def teardown
This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site.
|
|
From: <jh...@us...> - 2009-09-23 00:53:19
|
Revision: 93
http://etch.svn.sourceforge.net/etch/?rev=93&view=rev
Author: jheiss
Date: 2009-09-23 00:53:07 +0000 (Wed, 23 Sep 2009)
Log Message:
-----------
Put killswitch test in its own method.
Modified Paths:
--------------
trunk/test/options.rb
Modified: trunk/test/options.rb
===================================================================
--- trunk/test/options.rb 2009-09-14 20:13:25 UTC (rev 92)
+++ trunk/test/options.rb 2009-09-23 00:53:07 UTC (rev 93)
@@ -26,7 +26,7 @@
#puts "Using #{@testbase} as client working directory"
end
- def test_dryrun
+ def test_killswitch
#
# Test killswitch (not really a command-line option, but seems to
# fit best in this file)
@@ -67,9 +67,9 @@
run_etch(@port, @testbase, true)
assert_equal(origcontents, get_file_contents(@targetfile), 'killswitch')
-
- File.delete("#{@repodir}/killswitch")
-
+ end
+
+ def test_dryrun
#
# Test --dry-run
#
This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site.
|
|
From: <jh...@us...> - 2009-09-14 20:13:33
|
Revision: 92
http://etch.svn.sourceforge.net/etch/?rev=92&view=rev
Author: jheiss
Date: 2009-09-14 20:13:25 +0000 (Mon, 14 Sep 2009)
Log Message:
-----------
Updated per recent migrations
Modified Paths:
--------------
trunk/server/db/schema.rb
Modified: trunk/server/db/schema.rb
===================================================================
--- trunk/server/db/schema.rb 2009-09-14 20:12:12 UTC (rev 91)
+++ trunk/server/db/schema.rb 2009-09-14 20:13:25 UTC (rev 92)
@@ -14,10 +14,12 @@
create_table "clients", :force => true do |t|
t.string "name", :null => false
t.integer "status"
+ t.text "message"
t.datetime "created_at"
t.datetime "updated_at"
end
+ add_index "clients", ["updated_at"], :name => "index_clients_on_updated_at"
add_index "clients", ["status"], :name => "index_clients_on_status"
add_index "clients", ["name"], :name => "index_clients_on_name", :unique => true
@@ -63,6 +65,7 @@
t.datetime "updated_at"
end
+ add_index "results", ["created_at"], :name => "index_results_on_created_at"
add_index "results", ["file"], :name => "index_results_on_file"
add_index "results", ["client_id"], :name => "index_results_on_client_id"
This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site.
|
|
From: <jh...@us...> - 2009-09-14 20:12:25
|
Revision: 91
http://etch.svn.sourceforge.net/etch/?rev=91&view=rev
Author: jheiss
Date: 2009-09-14 20:12:12 +0000 (Mon, 14 Sep 2009)
Log Message:
-----------
Update paths to reflect directory structure of SF svn repo.
Modified Paths:
--------------
trunk/test/etchtest.rb
trunk/test/outputcapture.rb
Modified: trunk/test/etchtest.rb
===================================================================
--- trunk/test/etchtest.rb 2009-09-11 23:06:37 UTC (rev 90)
+++ trunk/test/etchtest.rb 2009-09-14 20:12:12 UTC (rev 91)
@@ -53,7 +53,7 @@
puts "Giving the server some time to start up"
sleep(5)
else
- Dir.chdir('../server/trunk')
+ Dir.chdir('../server')
# FIXME: silence the server (see various failed attempts...)
# Causes ruby to fork, so we're left with a useless pid
#exec("./script/server -d -p #{port}")
@@ -81,7 +81,7 @@
puts "#"
sleep 3
end
- result = system("ruby ../client/trunk/etch --generate-all --server=http://localhost:#{port} --test-base=#{testbase} --key=keys/testkey #{extra_args}")
+ result = system("ruby ../client/etch --generate-all --server=http://localhost:#{port} --test-base=#{testbase} --key=keys/testkey #{extra_args}")
if errors_expected
assert(!result)
else
Modified: trunk/test/outputcapture.rb
===================================================================
--- trunk/test/outputcapture.rb 2009-09-11 23:06:37 UTC (rev 90)
+++ trunk/test/outputcapture.rb 2009-09-14 20:12:12 UTC (rev 91)
@@ -9,7 +9,7 @@
require 'tempfile'
require 'fileutils'
require 'timeout'
-$: << '../client/trunk'
+$: << '../client'
require 'etch'
class EtchOutputCaptureTests < Test::Unit::TestCase
This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site.
|
|
From: <jh...@us...> - 2009-09-11 23:06:49
|
Revision: 90
http://etch.svn.sourceforge.net/etch/?rev=90&view=rev
Author: jheiss
Date: 2009-09-11 23:06:37 +0000 (Fri, 11 Sep 2009)
Log Message:
-----------
Add timeout to output capturing so that ill-behaved daemons don't cause
etch to hang around forever. Add unit tests for output capturing.
Note that the output capturing timeout test is commented out as the
timeout is rather long, thus causing the test to take a long time to
run. Not quite sure the best way to handle that.
Replace instances of assert(string.include?(substring)) with
assert_match(substring, string) so that the user gets a better error if
the assertion fails. Verified that it does a substring match if the
first arg is a string instead of a regex (a la String#sub), as the
documentation doesn't make that clear.
Add support for local requests.
Tests of client authentication
Modify start_server method to return pid in addition to port, and modify
stop_server method to take a pid to stop. This allows folks to run more
than one server at a time.
Modify run_etch method to run etch with a test key, otherwise etch tries
to use the system's host key, which won't be readable unless you run the
tests as root, so etch just skips over attaching an authentication
signature to requests.
Modified Paths:
--------------
trunk/test/actions.rb
trunk/test/attributes.rb
trunk/test/delete.rb
trunk/test/depend.rb
trunk/test/etchtest.rb
trunk/test/file.rb
trunk/test/history.rb
trunk/test/link.rb
trunk/test/nodegroups.rb
trunk/test/options.rb
trunk/test/scripts.rb
trunk/test/transitions.rb
Added Paths:
-----------
trunk/test/auth.rb
trunk/test/keys/
trunk/test/keys/testkey
trunk/test/keys/testkey.pub
trunk/test/keys/testkey2
trunk/test/keys/testkey2.pub
trunk/test/local_requests.rb
trunk/test/outputcapture.rb
Modified: trunk/test/actions.rb
===================================================================
--- trunk/test/actions.rb 2009-09-11 22:57:27 UTC (rev 89)
+++ trunk/test/actions.rb 2009-09-11 23:06:37 UTC (rev 90)
@@ -19,7 +19,7 @@
# Generate a directory for our test repository
@repodir = initialize_repository
- @port = start_server(@repodir)
+ @port, @pid = start_server(@repodir)
# Create a directory to use as a working directory for the client
@testbase = tempdir
@@ -85,8 +85,8 @@
# The setup actions will get run several times as we loop
# back and forth with the server sending original sums and
# contents. So just verify that they were run at least once.
- assert(get_file_contents("#{@repodir}/server_setup").include?("server_setup\n"), 'server_setup')
- assert(get_file_contents("#{@repodir}/setup").include?("setup\n"), 'setup')
+ assert_match("server_setup\n", get_file_contents("#{@repodir}/server_setup"), 'server_setup')
+ assert_match("setup\n", get_file_contents("#{@repodir}/setup"), 'setup')
assert_equal("pre\n", get_file_contents("#{@repodir}/pre"), 'pre')
assert_equal(
"exec_once\n", get_file_contents("#{@repodir}/exec_once"), 'exec_once')
@@ -372,7 +372,7 @@
end
def teardown
- stop_server
+ stop_server(@pid)
remove_repository(@repodir)
FileUtils.rm_rf(@testbase)
FileUtils.rm_rf(@targetfile)
Modified: trunk/test/attributes.rb
===================================================================
--- trunk/test/attributes.rb 2009-09-11 22:57:27 UTC (rev 89)
+++ trunk/test/attributes.rb 2009-09-11 23:06:37 UTC (rev 90)
@@ -20,7 +20,7 @@
# Generate a directory for our test repository
@repodir = initialize_repository
- @port = start_server(@repodir)
+ @port, @pid = start_server(@repodir)
# Create a directory to use as a working directory for the client
@testbase = tempdir
@@ -627,7 +627,7 @@
end
def teardown
- stop_server
+ stop_server(@pid)
remove_repository(@repodir)
FileUtils.rm_rf(@testbase)
FileUtils.rm_rf(@targetfile)
Added: trunk/test/auth.rb
===================================================================
--- trunk/test/auth.rb (rev 0)
+++ trunk/test/auth.rb 2009-09-11 23:06:37 UTC (rev 90)
@@ -0,0 +1,259 @@
+#!/usr/bin/ruby -w
+
+#
+# Test etch's handling of client authentication
+#
+
+require 'test/unit'
+require 'etchtest'
+require 'tempfile'
+require 'fileutils'
+require 'net/http'
+require 'rexml/document'
+require 'facter'
+
+class EtchAuthTests < Test::Unit::TestCase
+ include EtchTests
+
+ def setup
+ # Generate a file to use as our etch target/destination
+ @targetfile = Tempfile.new('etchtest').path
+ #puts "Using #{@targetfile} as target file"
+
+ # Generate a directory for our test repository
+ @repodir = initialize_repository
+ @port, @pid = start_server(@repodir)
+
+ # Create a directory to use as a working directory for the client
+ @testbase = tempdir
+ #puts "Using #{@testbase} as client working directory"
+
+ # Make sure the server will initially think this is a new client
+ hostname = Facter['fqdn'].value
+ Net::HTTP.start('localhost', @port) do |http|
+ # Find our client id
+ response = http.get("/clients.xml?name=#{hostname}")
+ if !response.kind_of?(Net::HTTPSuccess)
+ response.error!
+ end
+ response_xml = REXML::Document.new(response.body)
+ client_id = nil
+ if response_xml.elements['/clients/client/id']
+ client_id = response_xml.elements['/clients/client/id'].text
+ end
+ # Delete our client entry
+ if client_id
+ response = http.delete("/clients/#{client_id}.xml")
+ if !response.kind_of?(Net::HTTPSuccess)
+ response.error!
+ end
+ end
+ end
+ end
+
+ # Test authentication when new clients are allowed
+ def test_auth_allow_new_clients
+ File.open(File.join(@repodir, 'etchserver.conf'), 'w') do |file|
+ file.puts 'auth_enabled=true'
+ file.puts 'auth_deny_new_clients=false'
+ end
+
+ #
+ # New client, should work
+ #
+ testname = 'auth, allow new clients, new client'
+
+ FileUtils.mkdir_p("#{@repodir}/source/#{@targetfile}")
+ File.open("#{@repodir}/source/#{@targetfile}/config.xml", 'w') do |file|
+ file.puts <<-EOF
+ <config>
+ <file>
+ <warning_file/>
+ <source>
+ <plain>source</plain>
+ </source>
+ </file>
+ </config>
+ EOF
+ end
+
+ sourcecontents = "Test #{testname}\n"
+ File.open("#{@repodir}/source/#{@targetfile}/source", 'w') do |file|
+ file.write(sourcecontents)
+ end
+
+ # Run etch
+ #puts "Running '#{testname}' test"
+ run_etch(@port, @testbase)
+
+ # Verify that the file was created properly
+ assert_equal(sourcecontents, get_file_contents(@targetfile), testname)
+
+ #
+ # Existing client, should work
+ #
+ testname = 'auth, allow new clients, existing client'
+
+ FileUtils.mkdir_p("#{@repodir}/source/#{@targetfile}")
+ File.open("#{@repodir}/source/#{@targetfile}/config.xml", 'w') do |file|
+ file.puts <<-EOF
+ <config>
+ <file>
+ <warning_file/>
+ <source>
+ <plain>source</plain>
+ </source>
+ </file>
+ </config>
+ EOF
+ end
+
+ sourcecontents = "Test #{testname}\n"
+ File.open("#{@repodir}/source/#{@targetfile}/source", 'w') do |file|
+ file.write(sourcecontents)
+ end
+
+ # Run etch
+ #puts "Running '#{testname}' test"
+ run_etch(@port, @testbase)
+
+ # Verify that the file was created properly
+ assert_equal(sourcecontents, get_file_contents(@targetfile), testname)
+
+ #
+ # Existing client, bad signature, should be denied
+ #
+ testname = 'auth, allow new clients, existing client, bad signature'
+
+ FileUtils.mkdir_p("#{@repodir}/source/#{@targetfile}")
+ File.open("#{@repodir}/source/#{@targetfile}/config.xml", 'w') do |file|
+ file.puts <<-EOF
+ <config>
+ <file>
+ <warning_file/>
+ <source>
+ <plain>source</plain>
+ </source>
+ </file>
+ </config>
+ EOF
+ end
+
+ sourcecontents = "Test #{testname}\n"
+ File.open("#{@repodir}/source/#{@targetfile}/source", 'w') do |file|
+ file.write(sourcecontents)
+ end
+
+ # Put some text into the original file so that we can make sure it
+ # is not touched.
+ origcontents = "This is the original text\n"
+ File.delete(@targetfile)
+ File.open(@targetfile, 'w') do |file|
+ file.write(origcontents)
+ end
+
+ # Run etch with the wrong key to force a bad signature
+ #puts "Running '#{testname}' test"
+ run_etch(@port, @testbase, true, '--key=keys/testkey2')
+
+ # Verify that the file was not touched
+ assert_equal(origcontents, get_file_contents(@targetfile), testname)
+ end
+ # Test authentication when new clients are denied
+ def test_auth_deny_new_clients
+ File.open(File.join(@repodir, 'etchserver.conf'), 'w') do |file|
+ file.puts 'auth_enabled=true'
+ file.puts 'auth_deny_new_clients=true'
+ end
+
+ #
+ # New client, should fail
+ #
+ testname = 'auth, deny new clients, new client'
+
+ FileUtils.mkdir_p("#{@repodir}/source/#{@targetfile}")
+ File.open("#{@repodir}/source/#{@targetfile}/config.xml", 'w') do |file|
+ file.puts <<-EOF
+ <config>
+ <file>
+ <warning_file/>
+ <source>
+ <plain>source</plain>
+ </source>
+ </file>
+ </config>
+ EOF
+ end
+
+ sourcecontents = "Test #{testname}\n"
+ File.open("#{@repodir}/source/#{@targetfile}/source", 'w') do |file|
+ file.write(sourcecontents)
+ end
+
+ # Put some text into the original file so that we can make sure it
+ # is not touched.
+ origcontents = "This is the original text\n"
+ File.delete(@targetfile)
+ File.open(@targetfile, 'w') do |file|
+ file.write(origcontents)
+ end
+
+ # Run etch
+ #puts "Running '#{testname}' test"
+ run_etch(@port, @testbase, true)
+
+ # Verify that the file was not touched
+ assert_equal(origcontents, get_file_contents(@targetfile), testname)
+
+ #
+ # Add this client to the server so that it will now be considered
+ # an existing client
+ #
+ puts "# Starting a second copy of the server and adding this client to the database"
+ sleep 3
+ repodir2 = initialize_repository
+ port2, pid2 = start_server(repodir2)
+ run_etch(port2, @testbase)
+ stop_server(pid2)
+ remove_repository(repodir2)
+
+ #
+ # Existing client, should work
+ #
+ testname = 'auth, deny new clients, existing client'
+
+ FileUtils.mkdir_p("#{@repodir}/source/#{@targetfile}")
+ File.open("#{@repodir}/source/#{@targetfile}/config.xml", 'w') do |file|
+ file.puts <<-EOF
+ <config>
+ <file>
+ <warning_file/>
+ <source>
+ <plain>source</plain>
+ </source>
+ </file>
+ </config>
+ EOF
+ end
+
+ sourcecontents = "Test #{testname}\n"
+ File.open("#{@repodir}/source/#{@targetfile}/source", 'w') do |file|
+ file.write(sourcecontents)
+ end
+
+ # Run etch
+ #puts "Running '#{testname}' test"
+ run_etch(@port, @testbase)
+
+ # Verify that the file was created properly
+ assert_equal(sourcecontents, get_file_contents(@targetfile), testname)
+ end
+
+ def teardown
+ stop_server(@pid)
+ remove_repository(@repodir)
+ FileUtils.rm_rf(@testbase)
+ FileUtils.rm_rf(@targetfile)
+ end
+end
+
Property changes on: trunk/test/auth.rb
___________________________________________________________________
Added: svn:executable
+ *
Modified: trunk/test/delete.rb
===================================================================
--- trunk/test/delete.rb 2009-09-11 22:57:27 UTC (rev 89)
+++ trunk/test/delete.rb 2009-09-11 23:06:37 UTC (rev 90)
@@ -19,7 +19,7 @@
# Generate a directory for our test repository
@repodir = initialize_repository
- @port = start_server(@repodir)
+ @port, @pid = start_server(@repodir)
# Create a directory to use as a working directory for the client
@testbase = tempdir
@@ -231,7 +231,7 @@
end
def teardown
- stop_server
+ stop_server(@pid)
remove_repository(@repodir)
FileUtils.rm_rf(@testbase)
FileUtils.rm_rf(@targetfile)
Modified: trunk/test/depend.rb
===================================================================
--- trunk/test/depend.rb 2009-09-11 22:57:27 UTC (rev 89)
+++ trunk/test/depend.rb 2009-09-11 23:06:37 UTC (rev 90)
@@ -21,7 +21,7 @@
# Generate a directory for our test repository
@repodir = initialize_repository
- @port = start_server(@repodir)
+ @port, @pid = start_server(@repodir)
# Create a directory to use as a working directory for the client
@testbase = tempdir
@@ -202,7 +202,7 @@
end
def teardown
- stop_server
+ stop_server(@pid)
remove_repository(@repodir)
FileUtils.rm_rf(@testbase)
FileUtils.rm_rf(@targetfile)
Modified: trunk/test/etchtest.rb
===================================================================
--- trunk/test/etchtest.rb 2009-09-11 22:57:27 UTC (rev 89)
+++ trunk/test/etchtest.rb 2009-09-11 23:06:37 UTC (rev 90)
@@ -48,13 +48,13 @@
def start_server(repodir)
ENV['etchserverbase'] = repodir
# Pick a random port in the 3001-6000 range (range somewhat randomly chosen)
- port = 3001 + rand(2999)
- if @serverpid = fork
+ port = 3001 + rand(3000)
+ if pid = fork
puts "Giving the server some time to start up"
sleep(5)
else
Dir.chdir('../server/trunk')
- #Dir.chdir('../server/branches/libxml')
+ # FIXME: silence the server (see various failed attempts...)
# Causes ruby to fork, so we're left with a useless pid
#exec("./script/server -d -p #{port}")
# Causes ruby to invoke a copy of sh to run the command (to handle
@@ -62,12 +62,12 @@
#exec("./script/server -p #{port} > /dev/null")
exec("./script/server -p #{port}")
end
- port
+ [port, pid]
end
- def stop_server
- Process.kill('TERM', @serverpid)
- Process.waitpid(@serverpid)
+ def stop_server(pid)
+ Process.kill('TERM', pid)
+ Process.waitpid(pid)
end
def run_etch(port, testbase, errors_expected=false, extra_args='')
@@ -80,9 +80,12 @@
puts "# Errors expected here"
puts "#"
sleep 3
- assert(!system("ruby ../client/trunk/etch --generate-all --server=http://localhost:#{port} --test-base=#{testbase} #{extra_args}"))
+ end
+ result = system("ruby ../client/trunk/etch --generate-all --server=http://localhost:#{port} --test-base=#{testbase} --key=keys/testkey #{extra_args}")
+ if errors_expected
+ assert(!result)
else
- assert(system("ruby ../client/trunk/etch --generate-all --server=http://localhost:#{port} --test-base=#{testbase} #{extra_args}"))
+ assert(result)
end
end
Modified: trunk/test/file.rb
===================================================================
--- trunk/test/file.rb 2009-09-11 22:57:27 UTC (rev 89)
+++ trunk/test/file.rb 2009-09-11 23:06:37 UTC (rev 90)
@@ -19,7 +19,7 @@
# Generate a directory for our test repository
@repodir = initialize_repository
- @port = start_server(@repodir)
+ @port, @pid = start_server(@repodir)
# Create a directory to use as a working directory for the client
@testbase = tempdir
@@ -656,7 +656,7 @@
end
def teardown
- stop_server
+ stop_server(@pid)
remove_repository(@repodir)
FileUtils.rm_rf(@testbase)
FileUtils.rm_rf(@targetfile)
Modified: trunk/test/history.rb
===================================================================
--- trunk/test/history.rb 2009-09-11 22:57:27 UTC (rev 89)
+++ trunk/test/history.rb 2009-09-11 23:06:37 UTC (rev 90)
@@ -20,7 +20,7 @@
# Generate a directory for our test repository
@repodir = initialize_repository
- @port = start_server(@repodir)
+ @port, @pid = start_server(@repodir)
# Create a directory to use as a working directory for the client
@testbase = tempdir
@@ -220,7 +220,7 @@
assert_equal(@destfile, File.readlink(origfile), 'original backup of link')
system("cd #{historydir} && co -q -f -r1.1 #{historyfile}")
- assert(get_file_contents(historyfile).include?("#{@targetfile} -> #{@destfile}"), 'history backup of link')
+ assert_match("#{@targetfile} -> #{@destfile}", get_file_contents(historyfile), 'history backup of link')
end
def test_history_directory
@@ -275,7 +275,7 @@
assert_equal(before_mode, File.stat(origfile).mode, 'original directory mode')
# Check that the history log looks reasonable, it should contain an
# 'ls -ld' of the directory
- assert(get_file_contents(historyfile).include?(" #{@targetfile}"), 'history backup of directory')
+ assert_match(" #{@targetfile}", get_file_contents(historyfile), 'history backup of directory')
end
def test_history_directory_contents
@@ -328,7 +328,7 @@
end
def teardown
- stop_server
+ stop_server(@pid)
remove_repository(@repodir)
FileUtils.rm_rf(@testbase)
FileUtils.rm_rf(@targetfile)
Added: trunk/test/keys/testkey
===================================================================
--- trunk/test/keys/testkey (rev 0)
+++ trunk/test/keys/testkey 2009-09-11 23:06:37 UTC (rev 90)
@@ -0,0 +1,27 @@
+-----BEGIN RSA PRIVATE KEY-----
+MIIEoQIBAAKCAQEA7+HtwaFvMwwoquMEHrhMBHp0gsy4bXkmWrTc6bn37BTLnIr/
+fA6CkdzP+L/bvLbUzKh8mCRIiJNiuytz3AJEdBF4x2SrRO873iN6/32SN0dh8ER3
+CL2McR+SFgJO5LH59d7vi20VWpcquz3eog/siMb5N2r02D3j7n7fZqOLyQ+bjM29
+XaeuylPJlok7o0KXzp4lFqmLoN7EVAty1PsewYwb/k9RGAirwUW++nB/86qPs3kN
+nwibNiGIYAW44U56MMXZuLTKZJOVaOcBDDbSKEK3QkqOPZFIAxMI49k0hDoMX5n3
+mi5n3QSS3p9BiK8elKke4KQZawsg088Q7obQGwIBIwKCAQAUj7VLHHc+48j4tF9w
+WPCSq2kShpN3GQNJmnlV3L16orJd4AdFJdCtarK9jMmxFvxMDnEUWuGlTnYtTN4L
+iypwWUTd5A6uIyJjf2JQadlVMgEUmCd1xxqqnE5ZqG0pi5kVExvYwDUHw9B2cwR0
+SoH9GF6BF8vYBU4NINFR8MLWuAdqix492wgh16aur/VvDIei4z8t8Ny/DHd8Hpwp
+Kn3y5vfnNt5XMEHE53ZNUzYTsYHJtJzZ/y4aITfEu2+GvsNxpRCSnvDNehpppEiu
+QYlgEi4fsR52ltyKfli9qKoxGFxN30RqrVDxATK9TDdRoOII9Tfra6txlfJtIj8N
+cjzzAoGBAPwhFmTEGx09wh2NHQC9PFRE6EfZqc7xD8ohO3Tz1+N2dS4h6wHHUM43
+yD6hUatbEMrMcg+1zXt9r/V8lDS18QSjtKB2vmwkiHMjRQ4aQRmQCjC9kILnNzTY
+FUEkUtAkuXEThKyWclmRpMcalZQ8oUjlsdYc/qElhgzprFa5lewdAoGBAPOQtaJy
+kTKsaGi+EguBHr/IBVF6WwKlkt2KwDVWM33j5aGoOYKs2jOQRnF9qV2y2DALIS1P
+RLCHmLLsPBmyATgJ4M0+DWTiz+4fz/hWTnXiDxcS/P1EJLDbO7xwK/giubu/kyzR
+1gik/HvOOyfpDjNGdRGzvVLDBQebky/tZseXAoGBAPTs8S6v39NDTtrg2lh9UIxg
+MhnpYyDM6sRazAs2BOuXpQg+NL/mMT1awoX7y63GLZHN6yU0Q/RONecoj/iwvj8F
+baMxhcgjfTyl60+HN+zyUwrGxuWQJwAiXcpAivYVC+owN72ZdmWjbN6sHEbbz+Bq
+Gng5bGIHMcNmp2owoERzAoGAFOCEmOU/pUH6Uh7rmpYJ8y5m2xkdvmX2pUZoPxYE
+aeBVguKIliwSs/ZscCC2vuNxnbfPpMxHt1wUZxuQH3WoVUKs3mRnjE30kMDl8Lbw
+yEaTlEN0xUBa6pZy1aM2+AL5+iZdEnhizYp8Cpyl/BtKXCqcUfl2oLGhWGxrs6ai
+aOECgYAdCplM1lgfd9NsCe00kj6j4or+W6dOJuwZuYncLlnFOmtu+zNQyDUIL5tU
+DYL6iCst2AzzoKrhlw5W/PdnMSrfKw2KnXhJnibZrucRuCrkjelhgEffQwA2/JQN
+efPp5CZ2wZitEwSgKlCSERibHnRQKgXiDdSvXlpCMBY9qyPsdw==
+-----END RSA PRIVATE KEY-----
Added: trunk/test/keys/testkey.pub
===================================================================
--- trunk/test/keys/testkey.pub (rev 0)
+++ trunk/test/keys/testkey.pub 2009-09-11 23:06:37 UTC (rev 90)
@@ -0,0 +1 @@
+ssh-rsa AAAAB3NzaC1yc2EAAAABIwAAAQEA7+HtwaFvMwwoquMEHrhMBHp0gsy4bXkmWrTc6bn37BTLnIr/fA6CkdzP+L/bvLbUzKh8mCRIiJNiuytz3AJEdBF4x2SrRO873iN6/32SN0dh8ER3CL2McR+SFgJO5LH59d7vi20VWpcquz3eog/siMb5N2r02D3j7n7fZqOLyQ+bjM29XaeuylPJlok7o0KXzp4lFqmLoN7EVAty1PsewYwb/k9RGAirwUW++nB/86qPs3kNnwibNiGIYAW44U56MMXZuLTKZJOVaOcBDDbSKEK3QkqOPZFIAxMI49k0hDoMX5n3mi5n3QSS3p9BiK8elKke4KQZawsg088Q7obQGw== testkey
Added: trunk/test/keys/testkey2
===================================================================
--- trunk/test/keys/testkey2 (rev 0)
+++ trunk/test/keys/testkey2 2009-09-11 23:06:37 UTC (rev 90)
@@ -0,0 +1,27 @@
+-----BEGIN RSA PRIVATE KEY-----
+MIIEogIBAAKCAQEAyKTk+SmvLUnZ1AYCDFw1NAqGwddGcavPJu2mQzx0sfZKVR6V
+dUsE8pR4z2uZszEH/yqeA+hoxebjNWUgb7hV6FS+T5Vzwm9sIWeul/d6Erqu2bxU
+DNfWamhsY+Xf+ubrnCEeSWku5EsFJNqLiwu7ZlzFG0f6l9kmUH3BGgralUaVWOeR
+ci/GSDJ3phIA1XqRBR92ImlMp9nQY2kd9Hr3O3Ey90dwGKfY8a8sUqD1RKya/0+7
+JSbuWHUI4LMNKed8i4JkpH7QP2okXyPJtfq9GzShv5RRl/C5gVsLMvpajPX9tFKe
+uk9z7BucQfZ5qDipR3m8RAcUwqOjZpz34RD1qwIBIwKCAQBbuRg3Y4NH5z8B1txd
+a/sQedc0CqPcMUjBVrJn4R9nTAS5Mo13csBu5MmDZGOFHbqDRq6is2MYpBAYaL5e
+9S6WGBx8JxBY4nqS7ZGkjmOwyl6PbAkqcUwTYu+4o5mXRP3+OwaH9ZHHcsCF4D/K
+iQU2G8fR9QTXs7m+ZV+W4GPsdzot5GltI7Xg7ewZq0f6piMYUOwJLtc/ma+cW0F4
+ta9SyN6ORMOH5poJpNYTF6p7YvL6187aCKu8W4NVCeTTct5iJy/i2OQmiFFNIptz
+gIbZV/GN0qdrdsoW0Z3VkZlVyKO+rjILV20PRxtSGOks26F1Peuak+iBEkugOKRY
+hB4LAoGBAPCKt6C9/o9+HD3XerYKfyXN9+kxALH67mfKJcGuDA2NgyhitczrO2wK
+cSmSFCtp86PhALM9NHIV54Psms6ZOZAE6IBhSM/mp5FOC42QvxJtKOkgwrFESeBi
+IUpGICMEsaTvVICGzjh7oYD2Eiq1p9e+1xfDokauuLTxJ+wOnBUFAoGBANWJzEoV
+cxjuDcVWcJ1Wr/5x9oidUiPRyzhzO70OYXoo1qO9Wzd0I/vyJW52yQTs0IOZlvNq
+/4SWhVWqEpoCIqYP5CuC+41EeGE4XIgYkoOym1g4lNIYkv8NTzepq7gcnXKT4RC6
+sfzfDo+ITdDgcGBYKzEeQUF5kukG+SRQ097vAoGAdNWppdigNxFeLKp9blzeq/ZT
+16oWR9Gm/zZM2mp64gLn7wtfngvbCJdbiThS8IPrXjoWSG4vapzsywyFtM4UpQmy
+wgNd4VLGayXoWrQFCPMxIMbE9wPpXluMgylgEQJHp+H12Ab2czS8KLII0uqEuT9v
+ybbLKaVSZoPC7v/IJ3cCgYEAwzwofj9/LLxkXKbNXKcHTwkb6p52/C2GmgL0yhvG
+1ha1nQTlrwsZleS0gkC3yf0WabD/CnB0lnr9kCZ3aDx3c0G6q3Bw9i/5CG4LdR3H
+yN3P26FyHyxpI7RlrzwKtvWXRC9usDWqC8SfmSwp44tfbgd38mTN8rhLzb07jurQ
+VssCgYEAuu5KWdb2ns5CGAclpi/Qm/+si9jSCwq/JGiztrLwG6eJKCS3FPOMzjbt
+3skfBA+yepewc3tQgCLYdPfuN0A4R28Yv3uET05ysp4O0AXaMhMx8t63uT+titOT
+3if5nWOPnoCM1TCpNnnUQAptJF6R/XSX89FFaszGJfgNKI15+2Q=
+-----END RSA PRIVATE KEY-----
Added: trunk/test/keys/testkey2.pub
===================================================================
--- trunk/test/keys/testkey2.pub (rev 0)
+++ trunk/test/keys/testkey2.pub 2009-09-11 23:06:37 UTC (rev 90)
@@ -0,0 +1 @@
+ssh-rsa AAAAB3NzaC1yc2EAAAABIwAAAQEAyKTk+SmvLUnZ1AYCDFw1NAqGwddGcavPJu2mQzx0sfZKVR6VdUsE8pR4z2uZszEH/yqeA+hoxebjNWUgb7hV6FS+T5Vzwm9sIWeul/d6Erqu2bxUDNfWamhsY+Xf+ubrnCEeSWku5EsFJNqLiwu7ZlzFG0f6l9kmUH3BGgralUaVWOeRci/GSDJ3phIA1XqRBR92ImlMp9nQY2kd9Hr3O3Ey90dwGKfY8a8sUqD1RKya/0+7JSbuWHUI4LMNKed8i4JkpH7QP2okXyPJtfq9GzShv5RRl/C5gVsLMvpajPX9tFKeuk9z7BucQfZ5qDipR3m8RAcUwqOjZpz34RD1qw== testkey2
Modified: trunk/test/link.rb
===================================================================
--- trunk/test/link.rb 2009-09-11 22:57:27 UTC (rev 89)
+++ trunk/test/link.rb 2009-09-11 23:06:37 UTC (rev 90)
@@ -20,7 +20,7 @@
# Generate a directory for our test repository
@repodir = initialize_repository
- @port = start_server(@repodir)
+ @port, @pid = start_server(@repodir)
# Create a directory to use as a working directory for the client
@testbase = tempdir
@@ -332,7 +332,7 @@
end
def teardown
- stop_server
+ stop_server(@pid)
remove_repository(@repodir)
FileUtils.rm_rf(@testbase)
FileUtils.rm_rf(@targetfile)
Added: trunk/test/local_requests.rb
===================================================================
--- trunk/test/local_requests.rb (rev 0)
+++ trunk/test/local_requests.rb 2009-09-11 23:06:37 UTC (rev 90)
@@ -0,0 +1,142 @@
+#!/usr/bin/ruby -w
+
+#
+# Test etch's handling of local requests
+#
+
+require 'test/unit'
+require 'etchtest'
+require 'tempfile'
+require 'fileutils'
+
+class EtchLocalRequestsTests < Test::Unit::TestCase
+ include EtchTests
+
+ def setup
+ # Generate a file to use as our etch target/destination
+ @targetfile = Tempfile.new('etchtest').path
+ #puts "Using #{@targetfile} as target file"
+
+ # Generate a directory for our test repository
+ @repodir = initialize_repository
+ @port, @pid = start_server(@repodir)
+
+ # Create a directory to use as a working directory for the client
+ @testbase = tempdir
+ #puts "Using #{@testbase} as client working directory"
+ end
+
+ def test_local_requests_script
+ #
+ # Run a test with a local request and a script
+ #
+ testname = 'local request with script'
+
+ FileUtils.mkdir_p("#{@repodir}/source/#{@targetfile}")
+ File.open("#{@repodir}/source/#{@targetfile}/config.xml", 'w') do |file|
+ file.puts <<-EOF
+ <config>
+ <file>
+ <warning_file/>
+ <source>
+ <script>source.script</script>
+ </source>
+ </file>
+ </config>
+ EOF
+ end
+
+ # Create the local request file
+ requestdir = File.join(@testbase, 'requests', @targetfile)
+ requestfile = File.join(requestdir, 'testrequest')
+ FileUtils.mkdir_p(requestdir)
+ File.open(requestfile, 'w') do |file|
+ file.puts <<-EOF
+ <request>
+ <foo/>
+ </request>
+ EOF
+ end
+
+ sourcecontents = "Test #{testname}\n"
+ File.open("#{@repodir}/source/#{@targetfile}/source.script", 'w') do |file|
+ file.puts <<-EOF
+ require 'rexml/document'
+ doc = REXML::Document.new(@local_requests)
+ if doc.root.elements['/requests/request/foo']
+ @contents << '#{sourcecontents}'
+ end
+ EOF
+ end
+
+ # Run etch
+ #puts "Running '#{testname}' test"
+ run_etch(@port, @testbase)
+
+ # Verify that the file was created properly
+ assert_equal(sourcecontents, get_file_contents(@targetfile), testname)
+ end
+
+ def test_local_requests_template
+ #
+ # Run a test with a local request and a template
+ #
+ testname = 'local request with template'
+
+ FileUtils.mkdir_p("#{@repodir}/source/#{@targetfile}")
+ File.open("#{@repodir}/source/#{@targetfile}/config.xml", 'w') do |file|
+ file.puts <<-EOF
+ <config>
+ <file>
+ <warning_file/>
+ <source>
+ <template>source.template</template>
+ </source>
+ </file>
+ </config>
+ EOF
+ end
+
+ # Create the local request file
+ requestdir = File.join(@testbase, 'requests', @targetfile)
+ requestfile = File.join(requestdir, 'testrequest')
+ FileUtils.mkdir_p(requestdir)
+ File.open(requestfile, 'w') do |file|
+ file.puts <<-EOF
+ <request>
+ <foo/>
+ </request>
+ EOF
+ end
+
+ sourcecontents = "Test #{testname}\n"
+ File.open("#{@repodir}/source/#{@targetfile}/source.template", 'w') do |file|
+ file.puts <<-EOF
+ <% sourcecontents = '#{sourcecontents}' %>
+ <% require 'rexml/document' %>
+ <% doc = REXML::Document.new(@local_requests) %>
+ <% if doc.root.elements['/requests/request/foo'] %>
+ <%= sourcecontents %>
+ <% end %>
+ EOF
+ end
+
+ # Run etch
+ #puts "Running '#{testname}' test"
+ run_etch(@port, @testbase)
+
+ # Verify that the file was created properly
+ # Our whitespace in the heredoc above gets added to the generated file, so
+ # pass both strings through strip so we just compare the meat at the
+ # center.
+ assert_equal(sourcecontents.strip, get_file_contents(@targetfile).strip, testname)
+ end
+
+ def teardown
+ stop_server(@pid)
+ remove_repository(@repodir)
+ FileUtils.rm_rf(@testbase)
+ FileUtils.rm_rf(@targetfile)
+ end
+end
+
Property changes on: trunk/test/local_requests.rb
___________________________________________________________________
Added: svn:executable
+ *
Modified: trunk/test/nodegroups.rb
===================================================================
--- trunk/test/nodegroups.rb 2009-09-11 22:57:27 UTC (rev 89)
+++ trunk/test/nodegroups.rb 2009-09-11 23:06:37 UTC (rev 90)
@@ -20,7 +20,7 @@
# Generate a directory for our test repository
# Specify that the node should be put into 'testgroup' in nodes.xml
@repodir = initialize_repository(['testgroup'])
- @port = start_server(@repodir)
+ @port, @pid = start_server(@repodir)
# Create a directory to use as a working directory for the client
@testbase = tempdir
@@ -187,7 +187,7 @@
end
def teardown
- stop_server
+ stop_server(@pid)
remove_repository(@repodir)
FileUtils.rm_rf(@testbase)
FileUtils.rm_rf(@targetfile)
Modified: trunk/test/options.rb
===================================================================
--- trunk/test/options.rb 2009-09-11 22:57:27 UTC (rev 89)
+++ trunk/test/options.rb 2009-09-11 23:06:37 UTC (rev 90)
@@ -19,7 +19,7 @@
# Generate a directory for our test repository
@repodir = initialize_repository
- @port = start_server(@repodir)
+ @port, @pid = start_server(@repodir)
# Create a directory to use as a working directory for the client
@testbase = tempdir
@@ -108,7 +108,7 @@
end
def teardown
- stop_server
+ stop_server(@pid)
remove_repository(@repodir)
FileUtils.rm_rf(@testbase)
FileUtils.rm_rf(@targetfile)
Added: trunk/test/outputcapture.rb
===================================================================
--- trunk/test/outputcapture.rb (rev 0)
+++ trunk/test/outputcapture.rb 2009-09-11 23:06:37 UTC (rev 90)
@@ -0,0 +1,140 @@
+#!/usr/bin/ruby -w
+
+#
+# Test output capturing
+#
+
+require 'test/unit'
+require 'etchtest'
+require 'tempfile'
+require 'fileutils'
+require 'timeout'
+$: << '../client/trunk'
+require 'etch'
+
+class EtchOutputCaptureTests < Test::Unit::TestCase
+ include EtchTests
+
+ def setup
+ # Generate a file to use as our etch target/destination
+ @targetfile = Tempfile.new('etchtest').path
+ #puts "Using #{@targetfile} as target file"
+
+ # Generate a directory for our test repository
+ @repodir = initialize_repository
+ @port, @pid = start_server(@repodir)
+
+ # Create a directory to use as a working directory for the client
+ @testbase = tempdir
+ #puts "Using #{@testbase} as client working directory"
+ end
+
+ def test_output_capture
+ #
+ # Run a test where a post command outputs something, make sure that output
+ # is reported to the server.
+ #
+ testname = 'output capture'
+
+ postoutput = "This is output from\nthe post\ncommand"
+ postcmd = Tempfile.new('etchoutputtest')
+ postcmd.puts '#!/bin/sh'
+ # echo may or may not add a trailing \n depending on which echo we end
+ # up, so use printf, which doesn't add things.
+ postcmd.puts "printf \"#{postoutput}\""
+ postcmd.close
+ File.chmod(0755, postcmd.path)
+
+ FileUtils.mkdir_p("#{@repodir}/source/#{@targetfile}")
+ File.open("#{@repodir}/source/#{@targetfile}/config.xml", 'w') do |file|
+ file.puts <<-EOF
+ <config>
+ <file>
+ <source>
+ <plain>source</plain>
+ </source>
+ </file>
+ <post>
+ <exec>#{postcmd.path}</exec>
+ </post>
+ </config>
+ EOF
+ end
+
+ sourcecontents = "Test #{testname}\n"
+ File.open("#{@repodir}/source/#{@targetfile}/source", 'w') do |file|
+ file.write(sourcecontents)
+ end
+
+ # Run etch
+ #puts "Running '#{testname}' test"
+ run_etch(@port, @testbase)
+
+ # Fetch the latest result for this client from the server and verify that
+ # it contains the output from the post command.
+ hostname = Facter['fqdn'].value
+ latest_result_message = ''
+ Net::HTTP.start('localhost', @port) do |http|
+ response = http.get("/results.xml?clients.name=#{hostname}&sort=created_at_reverse")
+ if !response.kind_of?(Net::HTTPSuccess)
+ response.error!
+ end
+ response_xml = REXML::Document.new(response.body)
+ latest_result_message = nil
+ if response_xml.elements['/results/result/message']
+ latest_result_message = response_xml.elements['/results/result/message'].text
+ end
+ end
+ assert_match(postoutput, latest_result_message, testname)
+ end
+
+ def test_output_capture_timeout
+ #
+ # Run a test where a post command does not properly daemonize, ensure that
+ # etch eventually times out.
+ #
+ testname = 'output capture timeout'
+
+ FileUtils.mkdir_p("#{@repodir}/source/#{@targetfile}")
+ File.open("#{@repodir}/source/#{@targetfile}/config.xml", 'w') do |file|
+ file.puts <<-EOF
+ <config>
+ <file>
+ <source>
+ <plain>source</plain>
+ </source>
+ </file>
+ <post>
+ <exec>ruby -e 'sleep #{Etch::Client::OUTPUT_CAPTURE_TIMEOUT + 30}' &</exec>
+ </post>
+ </config>
+ EOF
+ end
+
+ sourcecontents = "Test #{testname}\n"
+ File.open("#{@repodir}/source/#{@targetfile}/source", 'w') do |file|
+ file.write(sourcecontents)
+ end
+
+ begin
+ Timeout.timeout(Etch::Client::OUTPUT_CAPTURE_TIMEOUT + 15) do
+ # Run etch
+ #puts "Running '#{testname}' test"
+ #
+ # NOTE: This test is not normally run because the timeout is so long.
+ # Uncomment this run_etch line to run this test.
+ #
+ #run_etch(@port, @testbase)
+ end
+ rescue Timeout::Error
+ flunk('output capturing did not time out as expected')
+ end
+ end
+
+ def teardown
+ stop_server(@pid)
+ remove_repository(@repodir)
+ FileUtils.rm_rf(@testbase)
+ FileUtils.rm_rf(@targetfile)
+ end
+end
Property changes on: trunk/test/outputcapture.rb
___________________________________________________________________
Added: svn:executable
+ *
Modified: trunk/test/scripts.rb
===================================================================
--- trunk/test/scripts.rb 2009-09-11 22:57:27 UTC (rev 89)
+++ trunk/test/scripts.rb 2009-09-11 23:06:37 UTC (rev 90)
@@ -20,7 +20,7 @@
# Generate a directory for our test repository
@repodir = initialize_repository
- @port = start_server(@repodir)
+ @port, @pid = start_server(@repodir)
# Create a directory to use as a working directory for the client
@testbase = tempdir
@@ -409,7 +409,7 @@
end
def teardown
- stop_server
+ stop_server(@pid)
remove_repository(@repodir)
FileUtils.rm_rf(@testbase)
FileUtils.rm_rf(@targetfile)
Modified: trunk/test/transitions.rb
===================================================================
--- trunk/test/transitions.rb 2009-09-11 22:57:27 UTC (rev 89)
+++ trunk/test/transitions.rb 2009-09-11 23:06:37 UTC (rev 90)
@@ -20,7 +20,7 @@
# Generate a directory for our test repository
@repodir = initialize_repository
- @port = start_server(@repodir)
+ @port, @pid = start_server(@repodir)
# Create a directory to use as a working directory for the client
@testbase = tempdir
@@ -255,7 +255,7 @@
end
def teardown
- stop_server
+ stop_server(@pid)
remove_repository(@repodir)
FileUtils.rm_rf(@testbase)
FileUtils.rm_rf(@targetfile)
This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site.
|
|
From: <jh...@us...> - 2009-09-11 22:57:36
|
Revision: 89
http://etch.svn.sourceforge.net/etch/?rev=89&view=rev
Author: jheiss
Date: 2009-09-11 22:57:27 +0000 (Fri, 11 Sep 2009)
Log Message:
-----------
Added authentication support.
Add support for local requests.
Add RESTful controllers for etch configs, facts and originals. Populate
remaining RESTful methods for results and clients controllers.
Modify repo_update to update repo directories atomically. We don't want
clients getting a partial or partially updated copy of the repository
versiontype bug fixes
Remove the line that enabled protect_from_forgery in application.rb,
thus allowing the removal of the lines from various controllers that
turned around and disabled that feature. It is incompatible with the
way the etch server works, as POST requests to the etch server are not
form data.
Remove the line that turned off sessions for robots in application.rb,
as etch does not store sessions in the database so there's no real
penalty for generating a session for robots. That line was copied over
initially from nVentory, which does (or at least used to) store sessions
in the database.
Copy the convert_includes method from nVentory.
Clean up the handling of find and paginate calls in the results and
client controllers, reducing code duplication. Add support for XML
formatting of results in same.
Rename method in files controller from index to create. See comment
there for reasoning.
Modified Paths:
--------------
trunk/server/app/controllers/application.rb
trunk/server/app/controllers/clients_controller.rb
trunk/server/app/controllers/dashboard_controller.rb
trunk/server/app/controllers/files_controller.rb
trunk/server/app/controllers/results_controller.rb
trunk/server/config/environment.rb
trunk/server/config/repo_update
trunk/server/config/routes.rb
trunk/server/lib/etchserver.rb
trunk/server/lib/versiontype.rb
Added Paths:
-----------
trunk/server/app/controllers/etch_configs_controller.rb
trunk/server/app/controllers/facts_controller.rb
trunk/server/app/controllers/originals_controller.rb
trunk/server/app/helpers/etch_configs_helper.rb
trunk/server/app/helpers/facts_helper.rb
trunk/server/app/helpers/originals_helper.rb
trunk/server/app/views/etch_configs/
trunk/server/app/views/facts/
trunk/server/app/views/originals/
trunk/server/db/backups/
trunk/server/lib/intmax.rb
trunk/server/test/functional/etch_configs_controller_test.rb
trunk/server/test/functional/facts_controller_test.rb
trunk/server/test/functional/originals_controller_test.rb
Modified: trunk/server/app/controllers/application.rb
===================================================================
--- trunk/server/app/controllers/application.rb 2009-09-11 22:42:34 UTC (rev 88)
+++ trunk/server/app/controllers/application.rb 2009-09-11 22:57:27 UTC (rev 89)
@@ -1,3 +1,5 @@
+require 'etchserver'
+
# Filters added to this controller apply to all controllers in the application.
# Likewise, all the methods added will be available for all controllers.
@@ -4,15 +6,6 @@
class ApplicationController < ActionController::Base
helper :all # include all helpers, all the time
- # See ActionController::RequestForgeryProtection for details
- # Uncomment the :secret if you're not using the cookie session store
- protect_from_forgery # :secret => '6f341ac14ba3f458f8420d3a2a879084'
-
- # GET requests with no user agent are probably monitoring agents of some
- # sort (including load balancer health checks) and creating sessions for
- # them just fills up the session table with junk
- session :off, :if => Proc.new { |request| request.env['HTTP_USER_AGENT'].blank? && request.get? }
-
# See ActionController::Base for details
# Uncomment this to filter the contents of submitted sensitive data parameters
# from your application log (in this case, all fields with names like "password").
@@ -25,4 +18,51 @@
# Pick a unique cookie name to distinguish our session data from others'
session :session_key => '_etch_session_id'
+ # Verify that any changes are signed if the administrator has
+ # enabled authentication
+ before_filter :authenticate, :only => [:create, :update, :destroy]
+
+ # This authentication system is targeted at etch clients. There should be
+ # an alternate authentication mechanism targeted at humans so that humans
+ # can interact with this service when authentication is enabled.
+ def authenticate
+ if Etch::Server.auth_enabled?
+ if request.headers['Authorization'] &&
+ request.headers['Authorization'] =~ /^EtchSignature /
+ signature = request.headers['Authorization'].sub(/^EtchSignature /, '')
+ verified = false
+ begin
+ verified = Etch::Server.verify_message(request.raw_post,
+ signature,
+ params)
+ rescue Exception => e
+ logger.error e.message
+ logger.info e.backtrace.join("\n") if params[:debug]
+ response = e.message
+ response << e.backtrace.join("\n") if params[:debug]
+ render :text => response, :status => :unauthorized
+ end
+ else
+ logger.info "Authentication required, no authentication data found"
+ render :text => "Authentication required, no authentication data found", :status => :unauthorized
+ end
+ end
+ end
+
+ # find and to_xml take their :include options in different formats
+ # find wants:
+ # :include => { :rack => { :datacenter_rack_assignment => :datacenter } }
+ # or this (which is what we use because it is easier to generate recursively)
+ # :include => { :rack => { :datacenter_rack_assignment => { :datacenter => {} } } }
+ # to_xml wants:
+ # :include => { :rack => { :include => { :datacenter_rack_assignment => { :include => { :datacenter => {} } } } } }
+ # This method takes the find format and returns the to_xml format
+ def convert_includes(includes)
+ includes.each do |key, value|
+ unless (value.nil? || value.blank?)
+ includes[key] = { :include => convert_includes(value) }
+ end
+ end
+ includes
+ end
end
Modified: trunk/server/app/controllers/clients_controller.rb
===================================================================
--- trunk/server/app/controllers/clients_controller.rb 2009-09-11 22:42:34 UTC (rev 88)
+++ trunk/server/app/controllers/clients_controller.rb 2009-09-11 22:57:27 UTC (rev 89)
@@ -1,3 +1,5 @@
+require 'intmax'
+
class ClientsController < ApplicationController
# GET /clients
def index
@@ -50,19 +52,25 @@
conditions_values << value
end
end
+ conditions_string = conditions_query.join(' AND ')
- if conditions_query.empty?
- @clients = Client.paginate(:all,
- :include => includes,
- :order => sort,
- :page => params[:page])
- else
- conditions_string = conditions_query.join(' AND ')
- @clients = Client.paginate(:all,
- :include => includes,
- :conditions => [ conditions_string, *conditions_values ],
- :order => sort,
- :page => params[:page])
+ per_page = Client.per_page # will_paginate's default value
+ # Client's requesting XML get all entries
+ respond_to { |format| format.html {}; format.xml { per_page = Integer::MAX } }
+
+ @clients = Client.paginate(:all,
+ :include => includes,
+ :conditions => [ conditions_string, *conditions_values ],
+ :order => sort,
+ :page => params[:page],
+ :per_page => per_page)
+
+ respond_to do |format|
+ format.html # index.html.erb
+ format.xml do
+ render :xml => @clients.to_xml(:include => convert_includes(includes),
+ :dasherize => false)
+ end
end
end
@@ -74,5 +82,69 @@
end
@client = Client.find(params[:id])
+ respond_to do |format|
+ format.html # show.html.erb
+ format.xml { render :xml => @client.to_xml(:include => convert_includes(includes),
+ :dasherize => false) }
+ end
end
+
+ # GET /clients/new
+ def new
+ @client = Client.new
+
+ respond_to do |format|
+ format.html # new.html.erb
+ format.xml { render :xml => @client }
+ end
+ end
+
+ # GET /clients/1/edit
+ def edit
+ @client = Client.find(params[:id])
+ end
+
+ # POST /clients
+ def create
+ @client = Client.new(params[:client])
+
+ respond_to do |format|
+ if @client.save
+ flash[:notice] = 'Client was successfully created.'
+ format.html { redirect_to(@client) }
+ format.xml { render :xml => @client, :status => :created, :location => @client }
+ else
+ format.html { render :action => "new" }
+ format.xml { render :xml => @client.errors, :status => :unprocessable_entity }
+ end
+ end
+ end
+
+ # PUT /clients/1
+ def update
+ @client = Client.find(params[:id])
+
+ respond_to do |format|
+ if @client.update_attributes(params[:client])
+ flash[:notice] = 'Client was successfully updated.'
+ format.html { redirect_to(@client) }
+ format.xml { head :ok }
+ else
+ format.html { render :action => "edit" }
+ format.xml { render :xml => @client.errors, :status => :unprocessable_entity }
+ end
+ end
+ end
+
+ # DELETE /clients/1
+ def destroy
+ @client = Client.find(params[:id])
+ @client.destroy
+
+ respond_to do |format|
+ format.html { redirect_to(clients_url) }
+ format.xml { head :ok }
+ end
+ end
end
+
Modified: trunk/server/app/controllers/dashboard_controller.rb
===================================================================
--- trunk/server/app/controllers/dashboard_controller.rb 2009-09-11 22:42:34 UTC (rev 88)
+++ trunk/server/app/controllers/dashboard_controller.rb 2009-09-11 22:57:27 UTC (rev 89)
@@ -39,30 +39,32 @@
months = []
# Find the oldest client
oldest = Client.find(:first, :order => 'created_at')
- # Get the month and year of that date
- month = oldest.created_at.mon
- year = oldest.created_at.year
- # Iterate months to present
- (year..Time.now.year).each do |y|
- start_month = 1
- end_month = 12
- if y == year
- start_month = month
- end
- if y == Time.now.year
- end_month = Time.now.month
- end
- (start_month..end_month).each do |m|
- end_time = nil
- if m == 12
- end_time = Time.local(y+1, 1)
- else
- end_time = Time.local(y, m+1)
+ if oldest
+ # Get the month and year of that date
+ month = oldest.created_at.mon
+ year = oldest.created_at.year
+ # Iterate months to present
+ (year..Time.now.year).each do |y|
+ start_month = 1
+ end_month = 12
+ if y == year
+ start_month = month
end
- # This should get us the last second of the desired month
- end_time - 1
- clients << Client.count(:conditions => ["created_at <= ?", end_time])
- months << end_time.strftime('%b %Y')
+ if y == Time.now.year
+ end_month = Time.now.month
+ end
+ (start_month..end_month).each do |m|
+ end_time = nil
+ if m == 12
+ end_time = Time.local(y+1, 1)
+ else
+ end_time = Time.local(y, m+1)
+ end
+ # This should get us the last second of the desired month
+ end_time - 1
+ clients << Client.count(:conditions => ["created_at <= ?", end_time])
+ months << end_time.strftime('%b %Y')
+ end
end
end
Added: trunk/server/app/controllers/etch_configs_controller.rb
===================================================================
--- trunk/server/app/controllers/etch_configs_controller.rb (rev 0)
+++ trunk/server/app/controllers/etch_configs_controller.rb 2009-09-11 22:57:27 UTC (rev 89)
@@ -0,0 +1,79 @@
+class EtchConfigsController < ApplicationController
+ # GET /etch_configs
+ def index
+ @etch_configs = EtchConfig.find :all
+
+ respond_to do |format|
+ format.html # index.html.erb
+ format.xml { render :xml => @etch_configs }
+ end
+ end
+
+ # GET /etch_configs/1
+ def show
+ @etch_config = EtchConfig.find(params[:id])
+
+ respond_to do |format|
+ format.html # show.html.erb
+ format.xml { render :xml => @etch_config }
+ end
+ end
+
+ # GET /etch_configs/new
+ def new
+ @etch_config = EtchConfig.new
+
+ respond_to do |format|
+ format.html # new.html.erb
+ format.xml { render :xml => @etch_config }
+ end
+ end
+
+ # GET /etch_configs/1/edit
+ def edit
+ @etch_config = EtchConfig.find(params[:id])
+ end
+
+ # POST /etch_configs
+ def create
+ @etch_config = EtchConfig.new(params[:etch_config])
+
+ respond_to do |format|
+ if @etch_config.save
+ flash[:notice] = 'EtchConfig was successfully created.'
+ format.html { redirect_to(@etch_config) }
+ format.xml { render :xml => @etch_config, :status => :created, :location => @etch_config }
+ else
+ format.html { render :action => "new" }
+ format.xml { render :xml => @etch_config.errors, :status => :unprocessable_entity }
+ end
+ end
+ end
+
+ # PUT /etch_configs/1
+ def update
+ @etch_config = EtchConfig.find(params[:id])
+
+ respond_to do |format|
+ if @etch_config.update_attributes(params[:etch_config])
+ flash[:notice] = 'EtchConfig was successfully updated.'
+ format.html { redirect_to(@etch_config) }
+ format.xml { head :ok }
+ else
+ format.html { render :action => "edit" }
+ format.xml { render :xml => @etch_config.errors, :status => :unprocessable_entity }
+ end
+ end
+ end
+
+ # DELETE /etch_configs/1
+ def destroy
+ @etch_config = EtchConfig.find(params[:id])
+ @etch_config.destroy
+
+ respond_to do |format|
+ format.html { redirect_to(admin_etch_configs_url) }
+ format.xml { head :ok }
+ end
+ end
+end
Added: trunk/server/app/controllers/facts_controller.rb
===================================================================
--- trunk/server/app/controllers/facts_controller.rb (rev 0)
+++ trunk/server/app/controllers/facts_controller.rb 2009-09-11 22:57:27 UTC (rev 89)
@@ -0,0 +1,79 @@
+class FactsController < ApplicationController
+ # GET /facts
+ def index
+ @facts = Fact.find :all
+
+ respond_to do |format|
+ format.html # index.html.erb
+ format.xml { render :xml => @facts }
+ end
+ end
+
+ # GET /facts/1
+ def show
+ @fact = Fact.find(params[:id])
+
+ respond_to do |format|
+ format.html # show.html.erb
+ format.xml { render :xml => @fact }
+ end
+ end
+
+ # GET /facts/new
+ def new
+ @fact = Fact.new
+
+ respond_to do |format|
+ format.html # new.html.erb
+ format.xml { render :xml => @fact }
+ end
+ end
+
+ # GET /facts/1/edit
+ def edit
+ @fact = Fact.find(params[:id])
+ end
+
+ # POST /facts
+ def create
+ @fact = Fact.new(params[:fact])
+
+ respond_to do |format|
+ if @fact.save
+ flash[:notice] = 'Fact was successfully created.'
+ format.html { redirect_to(@fact) }
+ format.xml { render :xml => @fact, :status => :created, :location => @fact }
+ else
+ format.html { render :action => "new" }
+ format.xml { render :xml => @fact.errors, :status => :unprocessable_entity }
+ end
+ end
+ end
+
+ # PUT /facts/1
+ def update
+ @fact = Fact.find(params[:id])
+
+ respond_to do |format|
+ if @fact.update_attributes(params[:fact])
+ flash[:notice] = 'Fact was successfully updated.'
+ format.html { redirect_to(@fact) }
+ format.xml { head :ok }
+ else
+ format.html { render :action => "edit" }
+ format.xml { render :xml => @fact.errors, :status => :unprocessable_entity }
+ end
+ end
+ end
+
+ # DELETE /facts/1
+ def destroy
+ @fact = Fact.find(params[:id])
+ @fact.destroy
+
+ respond_to do |format|
+ format.html { redirect_to(admin_facts_url) }
+ format.xml { head :ok }
+ end
+ end
+end
Modified: trunk/server/app/controllers/files_controller.rb
===================================================================
--- trunk/server/app/controllers/files_controller.rb 2009-09-11 22:42:34 UTC (rev 88)
+++ trunk/server/app/controllers/files_controller.rb 2009-09-11 22:57:27 UTC (rev 89)
@@ -1,14 +1,11 @@
-require 'etchserver'
-
class FilesController < ApplicationController
- # Turn off this Rails security mechanism, as it is doesn't work in the
- # way this application works. It expects POST requests to include a
- # token that it auto-inserts into forms, but our POST requests aren't
- # form data, they're unsolicited so Rails never gets a chance to insert
- # the token.
- skip_before_filter :verify_authenticity_token
-
- def index
+ # POST /files
+ # The method name doesn't exactly make sense in this case (since database
+ # entries are only indirectly created here, there is no File model), but it
+ # is consistent with the method name associated with POST in RESTful
+ # controllers, and thus also falls into the actions that are checked for
+ # authentication by our before_filter.
+ def create
response = nil
begin
etchserver = Etch::Server.new(params[:facts], params[:tag], params[:debug])
@@ -20,8 +17,6 @@
response = e.message
response << e.backtrace.join("\n") if params[:debug]
render :text => response, :status => :internal_server_error
- #raise
end
end
-
end
Added: trunk/server/app/controllers/originals_controller.rb
===================================================================
--- trunk/server/app/controllers/originals_controller.rb (rev 0)
+++ trunk/server/app/controllers/originals_controller.rb 2009-09-11 22:57:27 UTC (rev 89)
@@ -0,0 +1,79 @@
+class OriginalsController < ApplicationController
+ # GET /originals
+ def index
+ @originals = Original.find :all
+
+ respond_to do |format|
+ format.html # index.html.erb
+ format.xml { render :xml => @originals }
+ end
+ end
+
+ # GET /originals/1
+ def show
+ @original = Original.find(params[:id])
+
+ respond_to do |format|
+ format.html # show.html.erb
+ format.xml { render :xml => @original }
+ end
+ end
+
+ # GET /originals/new
+ def new
+ @original = Original.new
+
+ respond_to do |format|
+ format.html # new.html.erb
+ format.xml { render :xml => @original }
+ end
+ end
+
+ # GET /originals/1/edit
+ def edit
+ @original = Original.find(params[:id])
+ end
+
+ # POST /originals
+ def create
+ @original = Original.new(params[:original])
+
+ respond_to do |format|
+ if @original.save
+ flash[:notice] = 'Original was successfully created.'
+ format.html { redirect_to(@original) }
+ format.xml { render :xml => @original, :status => :created, :location => @original }
+ else
+ format.html { render :action => "new" }
+ format.xml { render :xml => @original.errors, :status => :unprocessable_entity }
+ end
+ end
+ end
+
+ # PUT /originals/1
+ def update
+ @original = Original.find(params[:id])
+
+ respond_to do |format|
+ if @original.update_attributes(params[:original])
+ flash[:notice] = 'Original was successfully updated.'
+ format.html { redirect_to(@original) }
+ format.xml { head :ok }
+ else
+ format.html { render :action => "edit" }
+ format.xml { render :xml => @original.errors, :status => :unprocessable_entity }
+ end
+ end
+ end
+
+ # DELETE /originals/1
+ def destroy
+ @original = Original.find(params[:id])
+ @original.destroy
+
+ respond_to do |format|
+ format.html { redirect_to(admin_originals_url) }
+ format.xml { head :ok }
+ end
+ end
+end
Modified: trunk/server/app/controllers/results_controller.rb
===================================================================
--- trunk/server/app/controllers/results_controller.rb 2009-09-11 22:42:34 UTC (rev 88)
+++ trunk/server/app/controllers/results_controller.rb 2009-09-11 22:57:27 UTC (rev 89)
@@ -1,11 +1,6 @@
+require 'intmax'
+
class ResultsController < ApplicationController
- # Turn off this Rails security mechanism, as it is doesn't work in the
- # way this application works. It expects POST requests to include a
- # token that it auto-inserts into forms, but our POST requests aren't
- # form data, they're unsolicited so Rails never gets a chance to insert
- # the token.
- skip_before_filter :verify_authenticity_token
-
# GET /results
def index
includes = {}
@@ -50,6 +45,7 @@
next if key == 'page'
@query_params << "#{key}=#{value}" # Used by view
next if key == 'sort'
+ next if key == 'combined'
if key == 'starttime'
conditions_query << "results.created_at > ?"
@@ -62,40 +58,57 @@
conditions_values << value
end
end
+ conditions_string = conditions_query.join(' AND ')
- if conditions_query.empty?
- if @combined # Don't paginate combined results
- @results = Result.find(:all,
- :include => includes,
- :order => sort)
- else
- @results = Result.paginate(:all,
- :include => includes,
- :order => sort,
- :page => params[:page])
+ per_page = Result.per_page # will_paginate's default value
+ # Client's requesting XML get all entries
+ respond_to { |format| format.html {}; format.xml { per_page = Integer::MAX } }
+ # As do clients who specifically request everything
+ if @combined
+ per_page = Integer::MAX
+ end
+
+ @results = Result.paginate(:all,
+ :include => includes,
+ :conditions => [ conditions_string, *conditions_values ],
+ :order => sort,
+ :page => params[:page],
+ :per_page => per_page)
+
+ respond_to do |format|
+ format.html # index.html.erb
+ format.xml do
+ render :xml => @results.to_xml(:include => convert_includes(includes),
+ :dasherize => false)
end
- else
- conditions_string = conditions_query.join(' AND ')
- if @combined # Don't paginate combined results
- @results = Result.find(:all,
- :include => includes,
- :conditions => [ conditions_string, *conditions_values ],
- :order => sort)
- else
- @results = Result.paginate(:all,
- :include => includes,
- :conditions => [ conditions_string, *conditions_values ],
- :order => sort,
- :page => params[:page])
- end
end
end
# GET /results/1
def show
@result = Result.find(params[:id])
+ respond_to do |format|
+ format.html # show.html.erb
+ format.xml { render :xml => @result.to_xml(:include => convert_includes(includes),
+ :dasherize => false) }
+ end
end
+ # GET /results/new
+ def new
+ @result = Result.new
+
+ respond_to do |format|
+ format.html # new.html.erb
+ format.xml { render :xml => @result }
+ end
+ end
+
+ # GET /results/1/edit
+ def edit
+ @result = Result.find(params[:id])
+ end
+
# POST /results
def create
if !params.has_key?(:fqdn)
@@ -127,6 +140,13 @@
# remains unchanged.
client.updated_at = Time.now
client.save
+
+ # NOTE: This skips over the individual file results recording below
+ # Re-enabled by jheiss, 7-July-2009 We have more disk space on the
+ # servers now, we'll see if they can keep up
+ #render :text => 'Client status recorded, individual file results recording disabled for now, jheiss, 9-May-2009'
+ #return
+
success_count = 0
params[:results].each do |result|
# The Rails parameter parsing strips out parameters with empty values.
@@ -147,5 +167,32 @@
render :text => "Successfully recorded #{success_count} of #{params[:results].size} results"
end
-
+
+ # PUT /results/1
+ def update
+ @result = Result.find(params[:id])
+
+ respond_to do |format|
+ if @result.update_attributes(params[:result])
+ flash[:notice] = 'Result was successfully updated.'
+ format.html { redirect_to(@result) }
+ format.xml { head :ok }
+ else
+ format.html { render :action => "edit" }
+ format.xml { render :xml => @result.errors, :status => :unprocessable_entity }
+ end
+ end
+ end
+
+ # DELETE /results/1
+ def destroy
+ @result = Result.find(params[:id])
+ @result.destroy
+
+ respond_to do |format|
+ format.html { redirect_to(admin_results_url) }
+ format.xml { head :ok }
+ end
+ end
end
+
Added: trunk/server/app/helpers/etch_configs_helper.rb
===================================================================
--- trunk/server/app/helpers/etch_configs_helper.rb (rev 0)
+++ trunk/server/app/helpers/etch_configs_helper.rb 2009-09-11 22:57:27 UTC (rev 89)
@@ -0,0 +1,2 @@
+module EtchConfigsHelper
+end
Added: trunk/server/app/helpers/facts_helper.rb
===================================================================
--- trunk/server/app/helpers/facts_helper.rb (rev 0)
+++ trunk/server/app/helpers/facts_helper.rb 2009-09-11 22:57:27 UTC (rev 89)
@@ -0,0 +1,2 @@
+module FactsHelper
+end
Added: trunk/server/app/helpers/originals_helper.rb
===================================================================
--- trunk/server/app/helpers/originals_helper.rb (rev 0)
+++ trunk/server/app/helpers/originals_helper.rb 2009-09-11 22:57:27 UTC (rev 89)
@@ -0,0 +1,2 @@
+module OriginalsHelper
+end
Modified: trunk/server/config/environment.rb
===================================================================
--- trunk/server/config/environment.rb 2009-09-11 22:42:34 UTC (rev 88)
+++ trunk/server/config/environment.rb 2009-09-11 22:57:27 UTC (rev 89)
@@ -25,12 +25,7 @@
# config.gem "bj"
# config.gem "hpricot", :version => '0.6', :source => "http://code.whytheluckystiff.net"
# config.gem "aws-s3", :lib => "aws/s3"
- # This is the syntax in the will_paginate docs, but seems to trigger
- # an install of exactly 2.3.6. At this point I don't know of any
- # specific version requirement we have, so I'm just letting it install
- # the latest.
- #config.gem 'mislav-will_paginate', :version => '~> 2.3.6', :lib => 'will_paginate', :source => 'http://gems.github.com'
- config.gem 'mislav-will_paginate', :lib => 'will_paginate', :source => 'http://gems.github.com'
+ config.gem 'mislav-will_paginate', :version => '~> 2.3.8', :lib => 'will_paginate', :source => 'http://gems.github.com'
# Only load the plugins named here, in the order given. By default, all plugins
# in vendor/plugins are loaded in alphabetical order.
Modified: trunk/server/config/repo_update
===================================================================
--- trunk/server/config/repo_update 2009-09-11 22:42:34 UTC (rev 88)
+++ trunk/server/config/repo_update 2009-09-11 22:57:27 UTC (rev 89)
@@ -1,6 +1,11 @@
#!/usr/bin/ruby -w
+require 'fileutils'
+require 'tempfile'
+
Dir.mkdir('/etc/etchserver') if !File.directory?('/etc/etchserver')
+Dir.mkdir('/etc/etchserver/orig') if !File.directory?('/etc/etchserver/orig')
+FileUtils.chown('nobody', nil, '/etc/etchserver/orig')
Dir.chdir('/etc/etchserver')
system('svn update --quiet')
@@ -8,10 +13,16 @@
currenttag = Time.now.strftime('etchautotag-%Y%m%d-%H00')
tagdir = File.join('tags', currenttag)
if !File.directory?(tagdir)
- #system('svn up trunk')
- #system("svn copy trunk #{tagdir}")
- #system("svn ci -m 'Creating current autotag' --non-interactive #{tagdir}")
- system("cp -a trunk #{tagdir}")
+ # Use Tempfile to make a unique filename
+ tmpdirfile = Tempfile.new('newtag', 'tags')
+ # Turn it into a directory
+ File.delete(tmpdirfile.path)
+ Dir.mkdir(tmpdirfile.path)
+ # Use it to create the new tag atomically
+ system("cp -a trunk #{tmpdirfile.path}")
+ File.rename(File.join(tmpdirfile.path, 'trunk'), tagdir)
+ # Cleanup
+ Dir.delete(tmpdirfile.path)
end
def convert_tagtime_to_unixtime(tagdate, tagtime)
@@ -28,9 +39,7 @@
next unless entry =~ /^etchautotag-(\d{8})-(\d{4})$/
tagunixtime = convert_tagtime_to_unixtime($1, $2)
if tagunixtime < timelimit
- #system("svn delete #{entry}")
- #system("svn ci -m 'Removing old autotag' --non-interactive #{entry}")
- system("rm -rf #{entry}")
+ FileUtils.rm_rf(entry)
end
end
Modified: trunk/server/config/routes.rb
===================================================================
--- trunk/server/config/routes.rb 2009-09-11 22:42:34 UTC (rev 88)
+++ trunk/server/config/routes.rb 2009-09-11 22:57:27 UTC (rev 89)
@@ -4,8 +4,11 @@
# Sample of regular route:
# map.connect 'products/:id', :controller => 'catalog', :action => 'view'
# Keep in mind you can assign values other than :controller and :action
- map.connect 'files', :controller => 'files', :action => 'index'
+ map.connect 'files', :controller => 'files', :action => 'create'
map.resources :clients
+ map.resources :etch_configs
+ map.resources :facts
+ map.resources :originals
map.resources :results
# Sample of named route:
Modified: trunk/server/lib/etchserver.rb
===================================================================
--- trunk/server/lib/etchserver.rb 2009-09-11 22:42:34 UTC (rev 88)
+++ trunk/server/lib/etchserver.rb 2009-09-11 22:57:27 UTC (rev 89)
@@ -2,7 +2,11 @@
require 'pathname' # absolute?
require 'digest/sha1' # hexdigest
require 'base64' # decode64, encode64
+require 'openssl'
+require 'time' # Time.parse
+require 'cgi'
require 'fileutils' # mkdir_p
+require 'rubygems' # libxml is a gem
require 'libxml'
require 'erb'
require 'versiontype' # Version
@@ -11,12 +15,193 @@
end
class Etch::Server
+ DEFAULT_CONFIGBASE = '/etc/etchserver'
+
+ @@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
+
def initialize(facts, tag=nil, debug=false)
@facts = facts
@tag = tag
@debug = debug
+ @fqdn = @facts['fqdn']
- @fqdn = @facts['fqdn']
if !@fqdn
raise "fqdn fact not supplied"
end
@@ -34,12 +219,8 @@
fact.destroy
end
end
-
- if ENV['etchserverbase'] && !ENV['etchserverbase'].empty?
- @configbase = ENV['etchserverbase']
- else
- @configbase = '/etc/etchserver'
- end
+
+ @configbase = Etch::Server.configbase
RAILS_DEFAULT_LOGGER.info "Using #{@configbase} as config base for node #{@fqdn}" if (@debug)
if !File.directory?(@configbase)
raise "Config base #{@configbase} doesn't exist"
@@ -444,7 +625,13 @@
done = true
end
end
-
+
+ # Pull out any local requests
+ local_requests = nil
+ if files[file] && files[file]['local_requests']
+ local_requests = files[file]['local_requests']
+ end
+
#
# Regular file
#
@@ -472,7 +659,7 @@
# Run the template through ERB to generate the file contents
template = template_elements.first.content
- external = EtchExternalSource.new(file, original_file, @facts, @groups, @sourcebase, @sitelibbase, @debug)
+ external = EtchExternalSource.new(file, original_file, @facts, @groups, local_requests, @sourcebase, @sitelibbase, @debug)
newcontents = external.process_template(template)
elsif config_xml.find_first('/config/file/source/script')
script_elements = config_xml.find('/config/file/source/script').to_a
@@ -482,7 +669,7 @@
# Run the script to generate the file contents
script = script_elements.first.content
- external = EtchExternalSource.new(file, original_file, @facts, @groups, @sourcebase, @sitelibbase, @debug)
+ external = EtchExternalSource.new(file, original_file, @facts, @groups, local_requests, @sourcebase, @sitelibbase, @debug)
newcontents = external.run_script(script)
elsif config_xml.find_first('/config/file/always_manage_metadata')
# always_manage_metadata is a special case where we proceed
@@ -669,7 +856,7 @@
end
script = script_elements.first.content
- external = EtchExternalSource.new(file, original_file, @facts, @groups, @sourcebase, @sitelibbase, @debug)
+ external = EtchExternalSource.new(file, original_file, @facts, @groups, local_requests, @sourcebase, @sitelibbase, @debug)
dest = external.run_script(script)
# Remove the script element(s) from the XML, the client won't need
@@ -740,7 +927,7 @@
end
script = script_elements.first.content
- external = EtchExternalSource.new(file, original_file, @facts, @groups, @sourcebase, @sitelibbase, @debug)
+ external = EtchExternalSource.new(file, original_file, @facts, @groups, local_requests, @sourcebase, @sitelibbase, @debug)
create = external.run_script(script)
create = false if create.empty?
@@ -811,7 +998,7 @@
end
script = script_elements.first.content
- external = EtchExternalSource.new(file, original_file, @facts, @groups, @sourcebase, @sitelibbase, @debug)
+ external = EtchExternalSource.new(file, original_file, @facts, @groups, local_requests, @sourcebase, @sitelibbase, @debug)
proceed = external.run_script(script)
proceed = false if proceed.empty?
@@ -996,7 +1183,7 @@
end
class EtchExternalSource
- def initialize(file, original_file, facts, groups, sourcebase, sitelibbase, debug=false)
+ def initialize(file, original_file, facts, groups, local_requests, sourcebase, sitelibbase, debug=false)
# The external source is going to be processed within the same Ruby
# instance as etch. We want to make it clear what variables we are
# intentionally exposing to external sources, essentially this
@@ -1005,6 +1192,7 @@
@original_file = original_file
@facts = facts
@groups = groups
+ @local_requests = local_requests
@sourcebase = sourcebase
@sitelibbase = sitelibbase
@debug = debug
Added: trunk/server/lib/intmax.rb
===================================================================
--- trunk/server/lib/intmax.rb (rev 0)
+++ trunk/server/lib/intmax.rb 2009-09-11 22:57:27 UTC (rev 89)
@@ -0,0 +1,7 @@
+# http://drawohara.com/post/117643208/ruby-integer-max-and-integer-min
+class Integer
+ N_BYTES = [42].pack('i').size
+ N_BITS = N_BYTES * 8
+ MAX = 2 ** (N_BITS - 2) - 1
+ MIN = -MAX - 1
+end
Modified: trunk/server/lib/versiontype.rb
===================================================================
--- trunk/server/lib/versiontype.rb 2009-09-11 22:42:34 UTC (rev 88)
+++ trunk/server/lib/versiontype.rb 2009-09-11 22:57:27 UTC (rev 89)
@@ -1,5 +1,8 @@
# This class stores numbers with multiple decimal points, a format
# commonly used for version numbers. For example '2.5.1'.
+
+require 'generator' # SyncEnumerator
+
class Version
include Comparable
@@ -29,11 +32,54 @@
(ourfields.length...larger).each { ourfields << '0' }
(otherfields.length...larger).each { otherfields << '0' }
end
- # Convert fields of all digits from string to number to get a numeric
- # rather than string comparison. This ensures that 5.9 < 5.10
- ourfields.map! { |field| if field =~ /^\d+$/ then field.to_i else field end }
- otherfields.map! { |field| if field =~ /^\d+$/ then field.to_i else field end }
+
+ ourfields, otherfields = convert_and_split(ourfields, otherfields)
+
# Array conveniently implements <=>
ourfields <=> otherfields
end
+
+ # Private methods below
+ private
+
+ # Loops over two arrays in parallel. If the entry at a given
+ # position in both arrays is numeric it is converted from a string to
+ # a number, or if either entry is a mixture of numeric and
+ # non-numeric characters then both are split into an array consisting
+ # of the numeric and non-numeric components.
+ def convert_and_split(fields1, fields2)
+ # Squish both arrays together
+ bothfields = []
+ sync = SyncEnumerator.new(fields1, fields2)
+ sync.each do |field1, field2|
+ bothfields << [field1, field2]
+ end
+ bothfields.map! do |fields|
+ # Convert fields of all digits from string to number to get a numeric
+ # rather than string comparison. This ensures that 5.9 < 5.10
+ # Unless either start with a zero, as 1.1 != 1.01, but converting
+ # 01 to a number turns it into 1.
+ if fields[0] =~ /^[1-9]\d*$/ && fields[1] =~ /^[1-9]\d*$/
+ fields.map! { |f| f.to_i }
+ else
+ # If the field is a mixture of numeric and non-numeric
+ # characters then split it up into an array of those components
+ # so that we compare "naturally". I.e. 9a < 10a
+ # This is similar to the method used by most "natural sort"
+ # algorithms that aim to sort file9 above file10.
+ if fields[0] =~ /\d\D/ || fields[0] =~ /\D\d/ ||
+ fields[1] =~ /\d\D/ || fields[1] =~ /\D\d/
+ fields.map! { |f| f.scan(/\d+|\D+/) }
+ # Pass back through this method to convert the numeric
+ # entries to numbers
+ fields = convert_and_split(fields[0], fields[1])
+ end
+ end
+ fields
+ end
+ # Unsquish back to separate arrays
+ fields1 = bothfields.collect { |fields| fields[0] }
+ fields2 = bothfields.collect { |fields| fields[1] }
+ [fields1, fields2]
+ end
end
Added: trunk/server/test/functional/etch_configs_controller_test.rb
===================================================================
--- trunk/server/test/functional/etch_configs_controller_test.rb (rev 0)
+++ trunk/server/test/functional/etch_configs_controller_test.rb 2009-09-11 22:57:27 UTC (rev 89)
@@ -0,0 +1,8 @@
+require 'test_helper'
+
+class EtchConfigsControllerTest < ActionController::TestCase
+ # Replace this with your real tests.
+ def test_truth
+ assert true
+ end
+end
Added: trunk/server/test/functional/facts_controller_test.rb
===================================================================
--- trunk/server/test/functional/facts_controller_test.rb (rev 0)
+++ trunk/server/test/functional/facts_controller_test.rb 2009-09-11 22:57:27 UTC (rev 89)
@@ -0,0 +1,8 @@
+require 'test_helper'
+
+class FactsControllerTest < ActionController::TestCase
+ # Replace this with your real tests.
+ def test_truth
+ assert true
+ end
+end
Added: trunk/server/test/functional/originals_controller_test.rb
===================================================================
--- trunk/server/test/functional/originals_controller_test.rb (rev 0)
+++ trunk/server/test/functional/originals_controller_test.rb 2009-09-11 22:57:27 UTC (rev 89)
@@ -0,0 +1,8 @@
+require 'test_helper'
+
+class OriginalsControllerTest < ActionController::TestCase
+ # Replace this with your real tests.
+ def test_truth
+ assert true
+ end
+end
This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site.
|
|
From: <jh...@us...> - 2009-09-11 22:42:49
|
Revision: 88
http://etch.svn.sourceforge.net/etch/?rev=88&view=rev
Author: jheiss
Date: 2009-09-11 22:42:34 +0000 (Fri, 11 Sep 2009)
Log Message:
-----------
Config file for unicorn (mongrel alternative)
Added Paths:
-----------
trunk/server/config/unicorn.rb
Added: trunk/server/config/unicorn.rb
===================================================================
--- trunk/server/config/unicorn.rb (rev 0)
+++ trunk/server/config/unicorn.rb 2009-09-11 22:42:34 UTC (rev 88)
@@ -0,0 +1,4 @@
+worker_processes(20)
+stdout_path('log/unicorn_stdout')
+stderr_path('log/unicorn_stderr')
+
This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site.
|
|
From: <jh...@us...> - 2009-09-11 16:59:30
|
Revision: 87
http://etch.svn.sourceforge.net/etch/?rev=87&view=rev
Author: jheiss
Date: 2009-09-11 16:59:21 +0000 (Fri, 11 Sep 2009)
Log Message:
-----------
Added authentication support. The client will sign messages using its
ssh host key.
Add support for local requests.
Update the method used to eliminate the OpenSSL "using default DH
parameters" warning.
http://techbits.blogspot.com/2009/08/ive-been-using-workaround-shown-at.html
Add timeout to output capturing so that ill-behaved daemons don't cause
etch to hang around forever. Add unit tests for output capturing.
Note that the output capturing timeout test is commented out as the
timeout is rather long, thus causing the test to take a long time to
run. Not quite sure the best way to handle that.
Move Etch::Client.initialize arguments to a hash so that the method
doesn't take 10 or whatever arguments.
Set etch version as a constant in the library (Etch::Client::VERSION).
Add a command line option to etch to display the version.
Modify the make targets to insert the version into the appropriate place
rather than having the version hard-coded in a bunch of files.
Add redhatprep, debianprep and solarisprep targets which install the
packages necessary to extract the version from the library file.
Add code to require rubygems if requiring facter fails.
Change /usr/lib/ruby/site_ruby to /usr/local/lib/ruby/site_ruby for the
Debian package. That seems to be the correct location on Debian
systems.
Modified Paths:
--------------
trunk/client/Makefile
trunk/client/control
trunk/client/etch
trunk/client/etch-client.spec
trunk/client/etch.rb
trunk/client/pkginfo
Added Paths:
-----------
trunk/client/dhparams
Modified: trunk/client/Makefile
===================================================================
--- trunk/client/Makefile 2009-06-25 00:13:39 UTC (rev 86)
+++ trunk/client/Makefile 2009-09-11 16:59:21 UTC (rev 87)
@@ -1,13 +1,15 @@
-# When updating the version number you currently need to update
-# etch-client.spec, control and pkginfo as well
-VER=1.1
+BUILDROOT=/var/tmp/etch-client-buildroot
+# Grab the current version from the library
+VER=$(shell ruby -e "$$:.unshift('.'); require 'etch'; puts Etch::Client::VERSION")
all:
-redhat: rpmbuild-redhat rpm
-rpmbuild-redhat:
- rpm --quiet -q rpm-build || yum -y install rpm-build
-BUILDROOT=/var/tmp/etch-client-buildroot
+redhat: redhatprep rpm
+redhatprep:
+ # Install everything needed for the command which sets VER above
+ rpm --quiet -q ruby || sudo yum install ruby
+ # And the package which contains the rpmbuild command
+ rpm --quiet -q rpm-build || sudo yum install rpm-build
TMPSPEC = etch-client-temp.spec
rpm: etch-client.spec
#
@@ -22,6 +24,7 @@
chmod 444 $(BUILDROOT)/usr/lib/ruby/site_ruby/1.8/etch.rb
mkdir -p $(BUILDROOT)/etc/etch
cp -p ca.pem $(BUILDROOT)/etc/etch
+ cp -p dhparams $(BUILDROOT)/etc/etch
# Cron job
mkdir -p $(BUILDROOT)/etc/cron.d
cp etch_cron $(BUILDROOT)/etc/cron.d/etch
@@ -30,26 +33,38 @@
#
# Now build the package
#
- rpmbuild -bb --buildroot $(BUILDROOT) etch-client.spec
+ sed 's/VER/$(VER)/' etch-client.spec > etch-client.spec_withversion
+ rpmbuild -bb --buildroot $(BUILDROOT) etch-client.spec_withversion
rm -rf $(BUILDROOT)
-debian: control
- rm -rf debtmp
- mkdir -p debtmp/DEBIAN
- grep -v '^#' control > debtmp/DEBIAN/control
- mkdir -p debtmp/usr/sbin
- cp -p etch debtmp/usr/sbin
- chmod 555 debtmp/usr/sbin/etch
- mkdir -p debtmp/usr/lib/ruby/site_ruby/1.8
- cp -p etch.rb debtmp/usr/lib/ruby/site_ruby/1.8
- chmod 444 debtmp/usr/lib/ruby/site_ruby/1.8
- mkdir -p debtmp/etc/etch
- cp -p ca.pem debtmp/etc/etch
- sudo chown -R 0:0 debtmp
- dpkg --build debtmp etch-client-$(VER).deb
- rm -rf debtmp
+debian: debianprep deb
+debianprep:
+ # Install everything needed for the command which sets VER above
+ sudo apt-get --no-upgrade --quiet install ruby libopenssl-ruby rubygems facter
+deb: control
+ rm -rf $(BUILDROOT)
+ mkdir -p $(BUILDROOT)/DEBIAN
+ grep -v '^#' control | sed 's/VER/$(VER)/' > $(BUILDROOT)/DEBIAN/control
+ mkdir -p $(BUILDROOT)/usr/sbin
+ cp -p etch $(BUILDROOT)/usr/sbin
+ chmod 555 $(BUILDROOT)/usr/sbin/etch
+ mkdir -p $(BUILDROOT)/usr/local/lib/site_ruby/1.8
+ cp -p etch.rb $(BUILDROOT)/usr/local/lib/site_ruby/1.8
+ chmod 444 $(BUILDROOT)/usr/local/lib/site_ruby/1.8/etch.rb
+ mkdir -p $(BUILDROOT)/etc/etch
+ cp -p ca.pem $(BUILDROOT)/etc/etch
+ cp -p dhparams $(BUILDROOT)/etc/etch
+ sudo chown -R 0:0 $(BUILDROOT)
+ dpkg --build $(BUILDROOT) etch-client-$(VER).deb
+ rm -rf $(BUILDROOT)
-solaris: pkginfo depend
+solaris: solarisprep sysvpkg sysvpkg-sparc
+solarisprep:
+ # Install everything needed for the command which sets VER above
+ pkginfo -q CSWruby || sudo pkg-get -i ruby
+ pkginfo -q CSWrubygems || sudo pkg-get -i rubygems
+ pkginfo -q CSWfacter || sudo pkg-get -i facter
+sysvpkg: pkginfo depend
#
# Create package file structure in build root
#
@@ -65,27 +80,33 @@
chmod 444 $(BUILDROOT)/opt/csw/lib/ruby/site_ruby/1.8/etch.rb
mkdir -p $(BUILDROOT)/etc/etch
cp -p ca.pem $(BUILDROOT)/etc/etch
+ cp -p dhparams $(BUILDROOT)/etc/etch
# Cron job for registration
cat etch_cron_wrapper | sed 's,/usr/bin/perl,/opt/csw/bin/perl,' > $(BUILDROOT)/usr/sbin/etch_cron_wrapper
chmod 555 $(BUILDROOT)/usr/sbin/etch_cron_wrapper
#
# Now build the package
#
- echo "i pkginfo=./pkginfo" > prototype
- echo "i depend=./depend" >> prototype
- echo "i postinstall=./postinstall" >> prototype
- echo "i postremove=./postremove" >> prototype
+ rm -rf solbuild
+ mkdir solbuild
+ sed 's/%VER%/$(VER)/' pkginfo > solbuild/pkginfo
+ echo "i pkginfo=./pkginfo" > solbuild/prototype
+ cp depend solbuild/depend
+ echo "i depend=./depend" >> solbuild/prototype
+ cp postinstall solbuild/postinstall
+ echo "i postinstall=./postinstall" >> solbuild/prototype
+ cp postremove solbuild/postremove
+ echo "i postremove=./postremove" >> solbuild/prototype
# The tail +2 removes the first line, which is the base directory
# and doesn't need to be included in the package.
# The first sed just cleans up the directory names
# The second sed tell pkgadd to not force our permissions on directories
# The $$ in that sed escapes the $ from make
- find $(BUILDROOT) | pkgproto | tail +2 | sed "s,$(BUILDROOT),," | sed '/^d/s/[^ ]* [^ ]* [^ ]*$$/? ? ?/' >> prototype
- pkgmk -r $(BUILDROOT) -d $(PWD)
- pkgtrans . YPCetch-$(VER).pkg YPCetch
- rm -rf YPCetch
+ find $(BUILDROOT) | pkgproto | tail +2 | sed "s,$(BUILDROOT),," | sed '/^d/s/[^ ]* [^ ]* [^ ]*$$/? ? ?/' >> solbuild/prototype
+ cd solbuild && pkgmk -r $(BUILDROOT) -d $(PWD)/solbuild
+ pkgtrans solbuild ../YPCetch-$(VER).pkg YPCetch
+ rm -rf solbuild
rm -rf $(BUILDROOT)
- rm -f prototype
# On Sparc systems we're having problems with the CSW/Blastwave ruby
# core dumping when running etch. The Sunfreeware ruby seems to work.
@@ -94,7 +115,7 @@
# our library file (etch.rb) into /opt/csw. We modify etch to use
# the Sunfreeware ruby in /usr/local/bin, but then tell it to also look
# in the /opt/csw directory for libraries.
-solaris-sparc: pkginfo depend
+sysvpkg-sparc: pkginfo depend
#
# Create package file structure in build root
#
@@ -114,25 +135,31 @@
chmod 444 $(BUILDROOT)/opt/csw/lib/ruby/site_ruby/1.8/etch.rb
mkdir -p $(BUILDROOT)/etc/etch
cp -p ca.pem $(BUILDROOT)/etc/etch
+ cp -p dhparams $(BUILDROOT)/etc/etch
# Cron job for registration
cat etch_cron_wrapper | sed 's,/usr/bin/perl,/opt/csw/bin/perl,' > $(BUILDROOT)/usr/sbin/etch_cron_wrapper
chmod 555 $(BUILDROOT)/usr/sbin/etch_cron_wrapper
#
# Now build the package
#
- echo "i pkginfo=./pkginfo" > prototype
- echo "i depend=./depend" >> prototype
- echo "i postinstall=./postinstall" >> prototype
- echo "i postremove=./postremove" >> prototype
+ rm -rf solbuild
+ mkdir solbuild
+ sed 's/%VER%/$(VER)/' pkginfo > solbuild/pkginfo
+ echo "i pkginfo=./pkginfo" > solbuild/prototype
+ cp depend solbuild/depend
+ echo "i depend=./depend" >> solbuild/prototype
+ cp postinstall solbuild/postinstall
+ echo "i postinstall=./postinstall" >> solbuild/prototype
+ cp postremove solbuild/postremove
+ echo "i postremove=./postremove" >> solbuild/prototype
# The tail +2 removes the first line, which is the base directory
# and doesn't need to be included in the package.
# The first sed just cleans up the directory names
# The second sed tell pkgadd to not force our permissions on directories
# The $$ in that sed escapes the $ from make
- find $(BUILDROOT) | pkgproto | tail +2 | sed "s,$(BUILDROOT),," | sed '/^d/s/[^ ]* [^ ]* [^ ]*$$/? ? ?/' >> prototype
- pkgmk -r $(BUILDROOT) -d $(PWD)
- pkgtrans . YPCetch-$(VER)-sparc.pkg YPCetch
- rm -rf YPCetch
+ find $(BUILDROOT) | pkgproto | tail +2 | sed "s,$(BUILDROOT),," | sed '/^d/s/[^ ]* [^ ]* [^ ]*$$/? ? ?/' >> solbuild/prototype
+ cd solbuild && pkgmk -r $(BUILDROOT) -d $(PWD)/solbuild
+ pkgtrans solbuild ../YPCetch-$(VER)-sparc.pkg YPCetch
+ rm -rf solbuild
rm -rf $(BUILDROOT)
- rm -f prototype
Modified: trunk/client/control
===================================================================
--- trunk/client/control 2009-06-25 00:13:39 UTC (rev 86)
+++ trunk/client/control 2009-09-11 16:59:21 UTC (rev 87)
@@ -1,5 +1,5 @@
Package: etch-client
-Version: 1.1-1
+Version: VER-1
Maintainer: etc...@li...
Architecture: all
Depends: ruby facter rcs
Added: trunk/client/dhparams
===================================================================
--- trunk/client/dhparams (rev 0)
+++ trunk/client/dhparams 2009-09-11 16:59:21 UTC (rev 87)
@@ -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-----
+
Modified: trunk/client/etch
===================================================================
--- trunk/client/etch 2009-06-25 00:13:39 UTC (rev 86)
+++ trunk/client/etch 2009-09-11 16:59:21 UTC (rev 87)
@@ -13,25 +13,16 @@
# Parse the command line options
#
-$generateall = nil
-$dryrun = nil
-$interactive = nil
-$fullfile = nil
-$filenameonly = nil
-$disableforce = nil
-$lockforce = nil
-$debug = nil
-$server = nil
-$tag = nil
-$varbase = nil
+options = {}
+@generateall = nil
opts = OptionParser.new
opts.banner = 'Usage: etch [options] [/path/to/config/file]'
opts.on('--generate-all', 'Can be used instead of giving a specific file to generate.') do |opt|
- $generateall = opt
+ @generateall = opt
end
opts.on('--dry-run', '-n', 'Prints contents of generated files instead of writing them out to disk.') do |opt|
- $dryrun = opt
+ options[:dryrun] = opt
end
opts.on('--damp-run', "Perform a dry run but run 'setup' entries for files. Normally all setup/pre/post entries are ignored for a dry run. However, files with setup entries will generally fail to build if the setup entry hasn't been run.") do |opt|
# Rather than sprinkle checks of two different variables throught the code, if
@@ -39,35 +30,42 @@
# 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.
- $dryrun = 'damp'
+ options[:dryrun] = 'damp'
end
opts.on('--interactive', 'Causes etch to pause before making each change and prompt the user for confirmation.') do |opt|
- $interactive = opt
+ options[:interactive] = opt
end
opts.on('--full-file', 'Normally etch will print a diff to show what changes it will make to a file. This will cause etch to display the full new file contents instead.') do |opt|
- $fullfile = opt
+ options[:fullfile] = opt
end
opts.on('--filename-only', 'Similar to the previous option, but in the opposite direction. Etch will only display the name of file to be changed.') do |opt|
- $filenameonly = opt
+ options[:filenameonly] = opt
end
opts.on('--disable-force', 'Ignore the disable_etch file. Use with caution.') do |opt|
- $disableforce = opt
+ options[:disableforce] = opt
end
opts.on('--lock-force', 'Force the removal of any existing lockfiles. Normally only lockfile over 2 hours old are removed.') do |opt|
- $lockforce = opt
+ options[:lockforce] = opt
end
opts.on('--debug', 'Print lots of messages about what etch is doing') do |opt|
- $debug = opt
+ options[:debug] = opt
end
opts.on('--server SERVER', 'Point etch to an alternate server') do |opt|
- $server = opt
+ options[:server] = opt
end
opts.on('--tag TAG', 'Request a specific repository tag from the server') do |opt|
- $tag = opt
+ options[:tag] = opt
end
opts.on('--test-base TESTDIR', 'Use an alternate local working directory (for use by test suite only)') do |opt|
- $varbase = opt
+ options[:varbase] = opt
end
+opts.on('--key PRIVATE_KEY', 'Use this private key for signing messages that are sent to the server') do |opt|
+ options[:key] = 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
@@ -77,7 +75,7 @@
files_to_generate = opts.parse(ARGV)
# Display a usage message if the user did not specify a valid action to perform.
-unless (!files_to_generate.nil? && !files_to_generate.empty?) || $generateall
+unless (!files_to_generate.nil? && !files_to_generate.empty?) || @generateall
puts opts
exit
end
@@ -86,7 +84,7 @@
# Do stuff
#
-etchclient = Etch::Client.new($server, $tag, $varbase, $debug, $dryrun, $interactive, $filenameonly, $fullfile)
-status = etchclient.process_until_done(files_to_generate, $disableforce, $lockforce)
+etchclient = Etch::Client.new(options)
+status = etchclient.process_until_done(files_to_generate)
exit status
Modified: trunk/client/etch-client.spec
===================================================================
--- trunk/client/etch-client.spec 2009-06-25 00:13:39 UTC (rev 86)
+++ trunk/client/etch-client.spec 2009-09-11 16:59:21 UTC (rev 87)
@@ -1,6 +1,6 @@
Name: etch-client
Summary: Etch client
-Version: 1.1
+Version: VER
Release: 1
Group: Applications/System
License: MIT
Modified: trunk/client/etch.rb
===================================================================
--- trunk/client/etch.rb 2009-06-25 00:13:39 UTC (rev 86)
+++ trunk/client/etch.rb 2009-09-11 16:59:21 UTC (rev 87)
@@ -2,9 +2,17 @@
# Etch configuration file management tool library
##############################################################################
-require 'facter'
+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'
@@ -14,24 +22,19 @@
require 'fcntl' # Fcntl::O_*
require 'etc' # getpwnam, getgrnam
require 'tempfile' # Tempfile
+require 'cgi'
+require 'timeout'
-# clean up "using default DH parameters" warning for https
-# http://blog.zenspider.com/2008/05/httpsssl-warning-cleanup.html
-class Net::HTTP
- alias :old_use_ssl= :use_ssl=
- def use_ssl= flag
- self.old_use_ssl = flag
- @ssl_context.tmp_dh_callback = proc {}
- end
-end
-
module Etch
end
class Etch::Client
+ VERSION = '1.13'
+
CONFIRM_PROCEED = 1
CONFIRM_SKIP = 2
CONFIRM_QUIT = 3
+ PRIVATE_KEY_PATHS = ["/etc/ssh/ssh_host_rsa_key", "/etc/ssh_host_rsa_key"]
# We need these in relation to the output capturing
ORIG_STDOUT = STDOUT.dup
@@ -39,16 +42,18 @@
attr_reader :exec_once_per_run
- # Cutting down the size of the arg list would be nice
- def initialize(server=nil, tag=nil, varbase=nil, debug=false, dryrun=false, interactive=false, filenameonly=false, fullfile=false)
- @server = server.nil? ? 'https://etch' : server
- @tag = tag
- @varbase = varbase.nil? ? '/var/etch' : varbase
- @debug = debug
- @dryrun = dryrun
- @interactive = interactive
- @filenameonly = filenameonly
- @fullfile = fullfile
+ def initialize(options)
+ @server = options[:server] ? options[:server] : 'https://etch'
+ @tag = options[:tag]
+ @varbase = options[:varbase] ? options[:varbase] : '/var/etch'
+ @debug = options[:debug]
+ @dryrun = options[:dryrun]
+ @interactive = options[:interactive]
+ @filenameonly = options[:filenameonly]
+ @fullfile = options[:fullfile]
+ @key = options[:key] ? options[:key] : get_private_key_path
+ @disableforce = options[:disableforce]
+ @lockforce = options[:lockforce]
# Ensure we have a sane path, particularly since we are often run from
# cron.
@@ -61,10 +66,17 @@
@origbase = File.join(@varbase, 'orig')
@historybase = File.join(@varbase, 'history')
@lockbase = File.join(@varbase, 'locks')
+ @requestbase = File.join(@varbase, 'requests')
@blankrequest = {}
@facts = Facter.to_hash
+ # 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 @facts['operatingsystemrelease']
# Some versions of Facter have a bug that leaves extraneous
# whitespace on this fact. Work around that with strip. I.e. on
@@ -90,8 +102,8 @@
@lchown_supported = nil
@lchmod_supported = nil
end
-
- def process_until_done(files_to_generate, disableforce, lockforce)
+
+ def process_until_done(files_to_generate)
# 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.
@@ -100,6 +112,12 @@
http = Net::HTTP.new(@filesuri.host, @filesuri.port)
if @filesuri.scheme == "https"
+ # Eliminate the OpenSSL "using default DH parameters" warning
+ if File.exist?('/etc/etch/dhparams')
+ dh = OpenSSL::PKey::DH.new(IO.read('/etc/etch/dhparams'))
+ Net::HTTP.ssl_context_accessor(:tmp_dh_callback)
+ http.tmp_dh_callback = proc { dh }
+ end
http.use_ssl = true
if File.exist?('/etc/etch/ca.pem')
http.ca_file = '/etc/etch/ca.pem'
@@ -115,14 +133,14 @@
# begin/raise for error events that end processing
catch :stop_processing do
begin
- enabled, message = check_for_disable_etch_file(disableforce)
+ 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(lockforce)
+ remove_stale_lock_files
# Assemble the initial request
request = get_blank_request
@@ -130,6 +148,10 @@
if !files_to_generate.nil? && !files_to_generate.empty?
files_to_generate.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
else
request['files[GENERATEALL]'] = '1'
@@ -155,6 +177,7 @@
puts "Sending request to server #{@filesuri}" if (@debug)
post = Net::HTTP::Post.new(@filesuri.path)
post.set_form_data(request)
+ sign_post!(post, @key)
response = http.request(post)
response_xml = nil
case response
@@ -198,12 +221,20 @@
response_xml.root.elements.each('/files/need_sums/need_sum') do |need_sum|
puts "Processing request for sum of #{need_sum.text}" if (@debug)
request["files[#{CGI.escape(need_sum.text)}][sha1sum]"] = get_orig_sum(need_sum.text)
+ local_requests = get_local_requests(need_sum.text)
+ if local_requests
+ request["files[#{CGI.escape(need_sum.text)}][local_requests]"] = local_requests
+ end
need_to_loop = true
end
response_xml.root.elements.each('/files/need_origs/need_orig') do |need_orig|
puts "Processing request for contents of #{need_orig.text}" if (@debug)
request["files[#{CGI.escape(need_orig.text)}][contents]"] = Base64.encode64(get_orig_contents(need_orig.text))
request["files[#{CGI.escape(need_orig.text)}][sha1sum]"] = get_orig_sum(need_orig.text)
+ local_requests = get_local_requests(need_orig.text)
+ if local_requests
+ request["files[#{CGI.escape(need_orig.text)}][local_requests]"] = local_requests
+ end
need_to_loop = true
end
@@ -226,17 +257,18 @@
# Send results to server
if !@dryrun
rails_results = []
- # CGI.escape doesn't work on things that aren't strings, so we don't
- # call it on a few of the fields here that are numbers or booleans
+ # A few of the fields here are numbers or booleans and need a
+ # to_s to make them compatible with CGI.escape, which expects a
+ # string.
rails_results << "fqdn=#{CGI.escape(@facts['fqdn'])}"
- rails_results << "status=#{status}"
+ rails_results << "status=#{CGI.escape(status.to_s)}"
rails_results << "message=#{CGI.escape(message)}"
@results.each do |result|
# Strangely enough this works. Even though the key is not unique to
# each result the Rails parameter parsing code keeps track of keys it
# has seen, and if it sees a duplicate it starts a new hash.
rails_results << "results[][file]=#{CGI.escape(result['file'])}"
- rails_results << "results[][success]=#{result['success']}"
+ rails_results << "results[][success]=#{CGI.escape(result['success'].to_s)}"
rails_results << "results[][message]=#{CGI.escape(result['message'])}"
end
puts "Sending results to server #{@resultsuri}" if (@debug)
@@ -244,8 +276,10 @@
# We have to bypass Net::HTTP's set_form_data method in this case
# because it expects a hash and we can't provide the results in the
# format we want in a hash because we'd have duplicate keys (see above).
- resultspost.body = rails_results.join('&')
+ results_as_string = rails_results.join('&')
+ resultspost.body = results_as_string
resultspost.content_type = 'application/x-www-form-urlencoded'
+ sign_post!(resultspost, @key)
response = http.request(resultspost)
case response
when Net::HTTPSuccess
@@ -259,11 +293,11 @@
status
end
- def check_for_disable_etch_file(disableforce)
+ def check_for_disable_etch_file
disable_etch = File.join(@varbase, 'disable_etch')
message = ''
if File.exist?(disable_etch)
- if !disableforce
+ if !@disableforce
message = "Etch disabled:\n"
message << IO.read(disable_etch)
puts message
@@ -1464,7 +1498,39 @@
histrcspath = "#{histrcsdir}/#{histbase},v"
File.chmod(histperms, histrcspath) if (!@dryrun)
end
-
+
+ def get_local_requests(file)
+ requestdir = File.join(@requestbase, file)
+ requestlist = []
+ if File.directory?(requestdir)
+ Dir.foreach(requestdir) do |entry|
+ next if entry == '.'
+ next if entry == '..'
+ requestfile = File.join(requestdir, entry)
+ request = IO.read(requestfile)
+ # Make sure it is valid XML
+ begin
+ request_xml = REXML::Document.new(request)
+ rescue REXML::ParseException => e
+ warn "Local request file #{requestfile} is not valid XML and will be ignored:\n" + e.message
+ next
+ end
+ # Make sure the root element is <request>
+ if request_xml.root.name != 'request'
+ warn "Local request file #{requestfile} is not properly formatted and will be ignored, XML root element is not <request>"
+ next
+ end
+ # Add it to the queue
+ requestlist << request
+ end
+ end
+ requests = nil
+ if !requestlist.empty?
+ requests = "<requests>\n#{requestlist.join('')}\n</requests>"
+ end
+ requests
+ end
+
# Haven't found a Ruby method for creating temporary directories,
# so create a temporary file and replace it with a directory.
def tempdir(file)
@@ -1866,13 +1932,13 @@
# Any etch lockfiles more than a couple hours old are most likely stale
# and can be removed. If told to force we remove all lockfiles.
- def remove_stale_lock_files(force=false)
+ 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 force || File.mtime(file) < twohoursago
+ if @lockforce || File.mtime(file) < twohoursago
puts "Removing stale lock file #{file}"
File.delete(file)
end
@@ -1883,6 +1949,10 @@
@already_processed.clear
end
+ # We limit capturing to 5 minutes. That should be plenty of time
+ # for etch to handle any given file, including running any
+ # setup/pre/post commands.
+ OUTPUT_CAPTURE_TIMEOUT = 5 * 60
def start_output_capture
# Establish a pipe, spawn a child process, and redirect stdout/stderr
# to the pipe. The child gathers up anything sent over the pipe and
@@ -1928,9 +1998,20 @@
# newline.
$stdout.sync = true
output = ''
- while char = pread.getc
- putc(char)
- output << char.chr
+ begin
+ # A surprising number of apps that we restart are ill-behaved and do
+ # not properly close stdin/stdout/stderr. With etch's output
+ # capturing feature this results in etch hanging around forever
+ # waiting for the pipes to close. We time out after a suitable
+ # period of time so that etch processes don't hang around forever.
+ Timeout.timeout(OUTPUT_CAPTURE_TIMEOUT) do
+ while char = pread.getc
+ putc(char)
+ output << char.chr
+ end
+ end
+ rescue Timeout::Error
+ $stderr.puts "Timeout in output capture, some app restarted via post probably didn't daemonize properly"
end
pread.close
owrite.write(output)
@@ -1959,5 +2040,40 @@
Process.wait
output
end
+
+ def get_private_key_path
+ key = nil
+ PRIVATE_KEY_PATHS.each do |path|
+ if File.readable?(path)
+ key = path
+ break
+ end
+ 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
+ key
+ end
+
+ # This method takes in a Net::HTTP::Post and a path to a private key.
+ # It will insert a 'timestamp' parameter to the post body, hash the body of
+ # the post, sign the hash using the private key, and insert that signature
+ # in the HTTP Authorization header field in the post.
+ def sign_post!(post, key)
+ if key
+ post.body << "×tamp=#{CGI.escape(Time.now.to_s)}"
+ private_key = OpenSSL::PKey::RSA.new(File.read(key))
+ hashed_body = Digest::SHA1.hexdigest(post.body)
+ signature = Base64.encode64(private_key.private_encrypt(hashed_body))
+ # encode64 breaks lines at 60 characters with newlines. Having newlines
+ # in an HTTP header screws things up (the lines get interpreted as
+ # separate headers) so strip them out. The Base64 standards seem to
+ # generally have a limit on line length, but Ruby's decode64 doesn't
+ # seem to complain. If it ever becomes a problem the server could
+ # rebreak the lines.
+ signature.gsub!("\n", '')
+ post['Authorization'] = "EtchSignature #{signature}"
+ end
+ end
end
Modified: trunk/client/pkginfo
===================================================================
--- trunk/client/pkginfo 2009-06-25 00:13:39 UTC (rev 86)
+++ trunk/client/pkginfo 2009-09-11 16:59:21 UTC (rev 87)
@@ -1,7 +1,7 @@
PKG="OSSetch"
NAME="Etch client"
ARCH="sparc,i386"
-VERSION="1.1"
+VERSION="%VER%"
CATEGORY="application"
CLASSES="none"
PSTAMP="none"
This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site.
|
|
From: <jh...@us...> - 2009-06-25 01:03:37
|
Revision: 86
http://etch.svn.sourceforge.net/etch/?rev=86&view=rev
Author: jheiss
Date: 2009-06-25 00:13:39 +0000 (Thu, 25 Jun 2009)
Log Message:
-----------
Use openssl to generate md5 and sha1 checksum files rather than some
messy code to check for md5 or md5sum executables.
Modified Paths:
--------------
Makefile
Modified: Makefile
===================================================================
--- Makefile 2009-06-18 00:28:05 UTC (rev 85)
+++ Makefile 2009-06-25 00:13:39 UTC (rev 86)
@@ -1,19 +1,6 @@
VER=3.5
TAGNAME=release-$(VER)
-# Perhaps someone with better make skill than I've got can make this
-# more elegant
-# Note, must indent with spaces here
-MD5=$(shell which md5)
-MD5SUM=$(shell which md5)
-ifdef MD5SUM
- MD5PROG=$(MD5)
-else ifdef MD5
- MD5PROG=$(MD5SUM)
-else
- $(error Couldn't find an MD5 program)
-endif
-
all: dist
test:
@@ -23,7 +10,8 @@
(cd tags/$(TAGNAME) && find client server test etchserver-* README | grep -v '\.svn' | cpio -pdum ../../etch-$(VER))
tar czf etch-$(VER).tar.gz etch-$(VER)
rm -rf etch-$(VER)
- $(MD5PROG) etch-$(VER).tar.gz > etch-$(VER).tar.gz.md5
+ openssl md5 etch-$(VER).tar.gz > etch-$(VER).tar.gz.md5
+ openssl sha1 etch-$(VER).tar.gz > etch-$(VER).tar.gz.sha1
gpg --detach --armor etch-$(VER).tar.gz
tag:
This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site.
|
|
From: <jh...@us...> - 2009-06-18 01:05:47
|
Revision: 85
http://etch.svn.sourceforge.net/etch/?rev=85&view=rev
Author: jheiss
Date: 2009-06-18 00:28:05 +0000 (Thu, 18 Jun 2009)
Log Message:
-----------
Slightly simplify the URL in the comments
Modified Paths:
--------------
trunk/etchserver-samples/source/var/sadm/install/admin/noask/noask
Modified: trunk/etchserver-samples/source/var/sadm/install/admin/noask/noask
===================================================================
--- trunk/etchserver-samples/source/var/sadm/install/admin/noask/noask 2009-06-18 00:08:49 UTC (rev 84)
+++ trunk/etchserver-samples/source/var/sadm/install/admin/noask/noask 2009-06-18 00:28:05 UTC (rev 85)
@@ -1,4 +1,4 @@
-# http://docs.sun.com/app/docs/doc/805-7228/6j6q7uerj?l=en&a=view
+# http://docs.sun.com/app/docs/doc/805-7228/6j6q7uerj?a=view
# "Avoiding User Interaction When Adding Packages"
mail=
instance=overwrite
This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site.
|
|
From: <jh...@us...> - 2009-06-18 00:09:52
|
Revision: 84
http://etch.svn.sourceforge.net/etch/?rev=84&view=rev
Author: jheiss
Date: 2009-06-18 00:08:49 +0000 (Thu, 18 Jun 2009)
Log Message:
-----------
Use pool.ntp.org servers rather than real server names so we don't
encourage too much use of specific stratum 0 and 1 servers.
Modified Paths:
--------------
trunk/etchserver-samples/source/etc/inet/ntp.conf/ntp.conf.server
Modified: trunk/etchserver-samples/source/etc/inet/ntp.conf/ntp.conf.server
===================================================================
--- trunk/etchserver-samples/source/etc/inet/ntp.conf/ntp.conf.server 2009-06-18 00:08:05 UTC (rev 83)
+++ trunk/etchserver-samples/source/etc/inet/ntp.conf/ntp.conf.server 2009-06-18 00:08:49 UTC (rev 84)
@@ -4,11 +4,7 @@
# Permit all access from localhost
restrict 127.0.0.1
-server time.caltech.edu
-server time.apple.com
-server clock.isc.org
-server tick.ucla.edu
-server timekeeper.isi.edu
-server nist1-dc.witime.net
-server nist1-ny.witime.net
+server 0.pool.ntp.org
+server 1.pool.ntp.org
+server 2.pool.ntp.org
This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site.
|
|
From: <jh...@us...> - 2009-06-18 00:09:12
|
Revision: 83
http://etch.svn.sourceforge.net/etch/?rev=83&view=rev
Author: jheiss
Date: 2009-06-18 00:08:05 +0000 (Thu, 18 Jun 2009)
Log Message:
-----------
Remove full path to post command, etch sets a reasonable path
internally.
Modified Paths:
--------------
trunk/etchserver-samples/source/etc/inet/inetd.conf/config.xml
Modified: trunk/etchserver-samples/source/etc/inet/inetd.conf/config.xml
===================================================================
--- trunk/etchserver-samples/source/etc/inet/inetd.conf/config.xml 2009-06-18 00:07:34 UTC (rev 82)
+++ trunk/etchserver-samples/source/etc/inet/inetd.conf/config.xml 2009-06-18 00:08:05 UTC (rev 83)
@@ -5,7 +5,7 @@
</source>
</file>
<post>
- <exec>/usr/bin/pkill -HUP inetd</exec>
+ <exec>pkill -HUP inetd</exec>
</post>
</config>
This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site.
|
|
From: <jh...@us...> - 2009-06-18 00:08:58
|
Revision: 82
http://etch.svn.sourceforge.net/etch/?rev=82&view=rev
Author: jheiss
Date: 2009-06-18 00:07:34 +0000 (Thu, 18 Jun 2009)
Log Message:
-----------
Fix shebang line
Modified Paths:
--------------
trunk/etchserver-samples/source/etc/inet/inetd.conf/inetd.conf.script
Modified: trunk/etchserver-samples/source/etc/inet/inetd.conf/inetd.conf.script
===================================================================
--- trunk/etchserver-samples/source/etc/inet/inetd.conf/inetd.conf.script 2009-06-18 00:07:09 UTC (rev 81)
+++ trunk/etchserver-samples/source/etc/inet/inetd.conf/inetd.conf.script 2009-06-18 00:07:34 UTC (rev 82)
@@ -1,4 +1,4 @@
-#!/usr/bin/perl
+#!/usr/bin/ruby
IO.foreach(@original_file) do |line|
if line =~ /^\s*#/
This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site.
|
|
From: <jh...@us...> - 2009-06-18 00:08:56
|
Revision: 81
http://etch.svn.sourceforge.net/etch/?rev=81&view=rev
Author: jheiss
Date: 2009-06-18 00:07:09 +0000 (Thu, 18 Jun 2009)
Log Message:
-----------
Combine Red Hat and CentOS lines using regex
Modified Paths:
--------------
trunk/etchserver-samples/source/etc/sysconfig/clock/config.xml
Modified: trunk/etchserver-samples/source/etc/sysconfig/clock/config.xml
===================================================================
--- trunk/etchserver-samples/source/etc/sysconfig/clock/config.xml 2009-04-02 01:21:34 UTC (rev 80)
+++ trunk/etchserver-samples/source/etc/sysconfig/clock/config.xml 2009-06-18 00:07:09 UTC (rev 81)
@@ -1,8 +1,7 @@
<config>
<file>
<source>
- <script operatingsystem="RedHat">clock.script</script>
- <script operatingsystem="CentOS">clock.script</script>
+ <script operatingsystem="/RedHat|CentOS/">clock.script</script>
</source>
</file>
</config>
This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site.
|
|
From: SourceForge.net <no...@so...> - 2009-04-11 05:48:45
|
Support Requests item #2728740, was opened at 2009-04-03 12:26 Message generated for change (Settings changed) made by jheiss You can respond by visiting: https://sourceforge.net/tracker/?func=detail&atid=1093659&aid=2728740&group_id=234501 Please note that this message will contain a full copy of the comment thread, including the initial issue submission, for this request, not just the latest update. Category: Install Problem (example) Group: None >Status: Closed Priority: 5 Private: No Submitted By: Christian Lyra (poplyra) Assigned to: Jason Heiss (jheiss) Summary: Etch fails to rake db:migrate Initial Comment: I´m trying to install etch on lenny (sounds funny on debian...), and while trying to rake db:migrate i got this: # rake db:migrate (in /usr/src/etch/trunk/server) rake aborted! no such file to load -- openssl (See full trace by running task with --trace) maybe something is missing? ---------------------------------------------------------------------- Comment By: Jason Heiss (jheiss) Date: 2009-04-10 22:46 Message: Gack, sorry for the slow reply. I lost track of this somehow. A quick check of Google indicates that Debian and Ubuntu package the Ruby OpenSSL library as a separate package call libopenssl-ruby. I built up a Debian box in a virtual machine and confirmed that installing that package with apt-get fixes this error. I've added Debian instructions to http://etch.wiki.sourceforge.net/GettingStarted ---------------------------------------------------------------------- You can respond by visiting: https://sourceforge.net/tracker/?func=detail&atid=1093659&aid=2728740&group_id=234501 |
|
From: SourceForge.net <no...@so...> - 2009-04-11 05:47:45
|
Support Requests item #2728740, was opened at 2009-04-03 12:26 Message generated for change (Settings changed) made by jheiss You can respond by visiting: https://sourceforge.net/tracker/?func=detail&atid=1093659&aid=2728740&group_id=234501 Please note that this message will contain a full copy of the comment thread, including the initial issue submission, for this request, not just the latest update. Category: Install Problem (example) Group: None Status: Open Priority: 5 Private: No Submitted By: Christian Lyra (poplyra) >Assigned to: Jason Heiss (jheiss) Summary: Etch fails to rake db:migrate Initial Comment: I´m trying to install etch on lenny (sounds funny on debian...), and while trying to rake db:migrate i got this: # rake db:migrate (in /usr/src/etch/trunk/server) rake aborted! no such file to load -- openssl (See full trace by running task with --trace) maybe something is missing? ---------------------------------------------------------------------- Comment By: Jason Heiss (jheiss) Date: 2009-04-10 22:46 Message: Gack, sorry for the slow reply. I lost track of this somehow. A quick check of Google indicates that Debian and Ubuntu package the Ruby OpenSSL library as a separate package call libopenssl-ruby. I built up a Debian box in a virtual machine and confirmed that installing that package with apt-get fixes this error. I've added Debian instructions to http://etch.wiki.sourceforge.net/GettingStarted ---------------------------------------------------------------------- You can respond by visiting: https://sourceforge.net/tracker/?func=detail&atid=1093659&aid=2728740&group_id=234501 |
|
From: SourceForge.net <no...@so...> - 2009-04-11 05:46:53
|
Support Requests item #2728740, was opened at 2009-04-03 12:26 Message generated for change (Comment added) made by jheiss You can respond by visiting: https://sourceforge.net/tracker/?func=detail&atid=1093659&aid=2728740&group_id=234501 Please note that this message will contain a full copy of the comment thread, including the initial issue submission, for this request, not just the latest update. Category: Install Problem (example) Group: None Status: Open Priority: 5 Private: No Submitted By: Christian Lyra (poplyra) Assigned to: Nobody/Anonymous (nobody) Summary: Etch fails to rake db:migrate Initial Comment: I´m trying to install etch on lenny (sounds funny on debian...), and while trying to rake db:migrate i got this: # rake db:migrate (in /usr/src/etch/trunk/server) rake aborted! no such file to load -- openssl (See full trace by running task with --trace) maybe something is missing? ---------------------------------------------------------------------- >Comment By: Jason Heiss (jheiss) Date: 2009-04-10 22:46 Message: Gack, sorry for the slow reply. I lost track of this somehow. A quick check of Google indicates that Debian and Ubuntu package the Ruby OpenSSL library as a separate package call libopenssl-ruby. I built up a Debian box in a virtual machine and confirmed that installing that package with apt-get fixes this error. I've added Debian instructions to http://etch.wiki.sourceforge.net/GettingStarted ---------------------------------------------------------------------- You can respond by visiting: https://sourceforge.net/tracker/?func=detail&atid=1093659&aid=2728740&group_id=234501 |
|
From: SourceForge.net <no...@so...> - 2009-04-03 19:26:15
|
Support Requests item #2728740, was opened at 2009-04-03 15:26 Message generated for change (Tracker Item Submitted) made by poplyra You can respond by visiting: https://sourceforge.net/tracker/?func=detail&atid=1093659&aid=2728740&group_id=234501 Please note that this message will contain a full copy of the comment thread, including the initial issue submission, for this request, not just the latest update. Category: Install Problem (example) Group: None Status: Open Priority: 5 Private: No Submitted By: Christian Lyra (poplyra) Assigned to: Nobody/Anonymous (nobody) Summary: Etch fails to rake db:migrate Initial Comment: I´m trying to install etch on lenny (sounds funny on debian...), and while trying to rake db:migrate i got this: # rake db:migrate (in /usr/src/etch/trunk/server) rake aborted! no such file to load -- openssl (See full trace by running task with --trace) maybe something is missing? ---------------------------------------------------------------------- You can respond by visiting: https://sourceforge.net/tracker/?func=detail&atid=1093659&aid=2728740&group_id=234501 |
|
From: <jh...@us...> - 2009-04-02 01:21:39
|
Revision: 80
http://etch.svn.sourceforge.net/etch/?rev=80&view=rev
Author: jheiss
Date: 2009-04-02 01:21:34 +0000 (Thu, 02 Apr 2009)
Log Message:
-----------
Tag 3.5 release
Modified Paths:
--------------
Makefile
Added Paths:
-----------
tags/release-3.5/
Modified: Makefile
===================================================================
--- Makefile 2009-04-02 00:21:34 UTC (rev 79)
+++ Makefile 2009-04-02 01:21:34 UTC (rev 80)
@@ -1,7 +1,7 @@
-VER=3.4
+VER=3.5
TAGNAME=release-$(VER)
-# Perhaps somewith with better make skill than I've got can make this
+# Perhaps someone with better make skill than I've got can make this
# more elegant
# Note, must indent with spaces here
MD5=$(shell which md5)
This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site.
|
|
From: <jh...@us...> - 2009-04-02 00:21:36
|
Revision: 79
http://etch.svn.sourceforge.net/etch/?rev=79&view=rev
Author: jheiss
Date: 2009-04-02 00:21:34 +0000 (Thu, 02 Apr 2009)
Log Message:
-----------
Convert the cron wrapper script to Ruby so that the client package has
no dependency on Perl.
Modified Paths:
--------------
trunk/client/control
trunk/client/depend
trunk/client/etch_cron_wrapper
Modified: trunk/client/control
===================================================================
--- trunk/client/control 2009-04-02 00:20:54 UTC (rev 78)
+++ trunk/client/control 2009-04-02 00:21:34 UTC (rev 79)
@@ -2,6 +2,6 @@
Version: 1.1-1
Maintainer: etc...@li...
Architecture: all
-Depends: ruby facter rcs libdigest-sha1-perl
+Depends: ruby facter rcs
Description: Etch client
Modified: trunk/client/depend
===================================================================
--- trunk/client/depend 2009-04-02 00:20:54 UTC (rev 78)
+++ trunk/client/depend 2009-04-02 00:21:34 UTC (rev 79)
@@ -1,5 +1,4 @@
P CSWruby
P CSWfacter
-P CSWpmdigestsha1
P CSWrcs
Modified: trunk/client/etch_cron_wrapper
===================================================================
--- trunk/client/etch_cron_wrapper 2009-04-02 00:20:54 UTC (rev 78)
+++ trunk/client/etch_cron_wrapper 2009-04-02 00:21:34 UTC (rev 79)
@@ -1,20 +1,18 @@
-#!/usr/bin/perl
+#!/usr/bin/ruby -w
-use Digest::SHA1 qw(sha1_hex);
-use Sys::Hostname;
-use strict;
-use warnings;
+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(hex(substr(sha1_hex(hostname), 0, 7)));
+srand(Digest::SHA1.hexdigest(Socket.gethostname)[0,7].hex)
# Cron job is set to run every hour
-my $MAX_SLEEP = 60 * 60;
+MAX_SLEEP = 60 * 60
-sleep(int(rand($MAX_SLEEP)));
+sleep(rand(MAX_SLEEP))
-exec '/usr/sbin/etch', '--generate-all';
+exec('/usr/sbin/etch', '--generate-all')
This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site.
|
|
From: <jh...@us...> - 2009-04-02 00:20:55
|
Revision: 78
http://etch.svn.sourceforge.net/etch/?rev=78&view=rev
Author: jheiss
Date: 2009-04-02 00:20:54 +0000 (Thu, 02 Apr 2009)
Log Message:
-----------
Work around Facter bug on the operatingsystemrelease fact.
Modified Paths:
--------------
trunk/client/etch.rb
Modified: trunk/client/etch.rb
===================================================================
--- trunk/client/etch.rb 2009-04-02 00:20:31 UTC (rev 77)
+++ trunk/client/etch.rb 2009-04-02 00:20:54 UTC (rev 78)
@@ -65,6 +65,12 @@
@blankrequest = {}
@facts = Facter.to_hash
@facts.each_pair { |key, value| @blankrequest["facts[#{key}]"] = value.to_s }
+ 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 @debug
@blankrequest['debug'] = '1'
end
This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site.
|
|
From: <jh...@us...> - 2009-04-02 00:20:32
|
Revision: 77
http://etch.svn.sourceforge.net/etch/?rev=77&view=rev
Author: jheiss
Date: 2009-04-02 00:20:31 +0000 (Thu, 02 Apr 2009)
Log Message:
-----------
Import improved Version class from tpkg. Many bug fixes. tpkg has unit
tests for the class, any changes should be made and tested there and
imported to etch.
Modified Paths:
--------------
trunk/server/lib/versiontype.rb
Modified: trunk/server/lib/versiontype.rb
===================================================================
--- trunk/server/lib/versiontype.rb 2009-04-02 00:20:11 UTC (rev 76)
+++ trunk/server/lib/versiontype.rb 2009-04-02 00:20:31 UTC (rev 77)
@@ -14,6 +14,25 @@
def <=>(other)
ourfields = @version.split('.')
otherfields = other.to_s.split('.')
+ # Convert anything like '.5' to '0.5'
+ # '.5'.split('.') returns ['', '5']
+ [ourfields, otherfields].each do |fields|
+ if fields[0] == ''
+ fields[0] = '0'
+ end
+ end
+ # Pad with zeros so that '1' == '1.0', etc.
+ if ourfields.length != otherfields.length
+ larger = [ourfields.length, otherfields.length].max
+ # For the longer number this depends on something like (3...1).each
+ # doing nothing. That currently works, but is not documented behavior.
+ (ourfields.length...larger).each { ourfields << '0' }
+ (otherfields.length...larger).each { otherfields << '0' }
+ end
+ # Convert fields of all digits from string to number to get a numeric
+ # rather than string comparison. This ensures that 5.9 < 5.10
+ ourfields.map! { |field| if field =~ /^\d+$/ then field.to_i else field end }
+ otherfields.map! { |field| if field =~ /^\d+$/ then field.to_i else field end }
# Array conveniently implements <=>
ourfields <=> otherfields
end
This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site.
|
|
From: <jh...@us...> - 2009-04-02 00:20:23
|
Revision: 76
http://etch.svn.sourceforge.net/etch/?rev=76&view=rev
Author: jheiss
Date: 2009-04-02 00:20:11 +0000 (Thu, 02 Apr 2009)
Log Message:
-----------
Fix handling of operator comparisons in attribute filtering. Improve
test for same.
Rescue any exceptions in configfilter! where it is called by generate
file so that we can insert the name of the config.xml file that we were
handling when the exception occurred. This should help the user with
debugging. Same logic as the exception catch/re-raise that occurs when
running user scripts.
Modified Paths:
--------------
trunk/server/lib/etchserver.rb
trunk/test/attributes.rb
Modified: trunk/server/lib/etchserver.rb
===================================================================
--- trunk/server/lib/etchserver.rb 2009-02-06 19:47:29 UTC (rev 75)
+++ trunk/server/lib/etchserver.rb 2009-04-02 00:20:11 UTC (rev 76)
@@ -344,7 +344,11 @@
config_xml = LibXML::XML::Document.file(config_xml_file)
# Filter the config.xml file by looking for attributes
- configfilter!(config_xml.root)
+ begin
+ configfilter!(config_xml.root)
+ rescue Exception => e
+ raise e.exception("Error filtering config.xml for #{file}:\n" + e.message)
+ end
# Validate the filtered file against config.dtd
if !config_xml.validate(@config_dtd)
@@ -939,7 +943,7 @@
operator = $1
valueversion = Version.new($2)
compversion = Version.new(comp)
- if valueversion.send(operator.to_sym, compversion)
+ if compversion.send(operator.to_sym, valueversion)
result = true
end
# Regular expressions
Modified: trunk/test/attributes.rb
===================================================================
--- trunk/test/attributes.rb 2009-02-06 19:47:29 UTC (rev 75)
+++ trunk/test/attributes.rb 2009-04-02 00:20:11 UTC (rev 76)
@@ -481,7 +481,17 @@
# Version fact operator comparison
#
testname = 'version fact operator comparison'
-
+
+ # Try to make up a subset of operatingsystemrelease so that we really
+ # test the operator functionality and not just equality. I.e. if osrel
+ # is 2.5.1 we'd like to extract 2.5
+ osrelsubset = osrel
+ osrelparts = osrel.split('.')
+ if osrelparts.length > 1
+ osrelparts.pop
+ osrelsubset = osrelparts.join('.')
+ end
+
FileUtils.mkdir_p("#{@repodir}/source/#{@targetfile}")
File.open("#{@repodir}/source/#{@targetfile}/config.xml", 'w') do |file|
file.puts <<-EOF
@@ -489,7 +499,7 @@
<file>
<warning_file/>
<source>
- <plain operatingsystemrelease=">=#{osrel}">source</plain>
+ <plain operatingsystemrelease=">=#{osrelsubset}">source</plain>
</source>
</file>
</config>
This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site.
|
|
From: <jh...@us...> - 2009-02-06 19:47:36
|
Revision: 75
http://etch.svn.sourceforge.net/etch/?rev=75&view=rev
Author: jheiss
Date: 2009-02-06 19:47:29 +0000 (Fri, 06 Feb 2009)
Log Message:
-----------
Work around LibXML's poor handling of non-existent files.
Modified Paths:
--------------
trunk/server/lib/etchserver.rb
Modified: trunk/server/lib/etchserver.rb
===================================================================
--- trunk/server/lib/etchserver.rb 2009-02-06 17:43:29 UTC (rev 74)
+++ trunk/server/lib/etchserver.rb 2009-02-06 19:47:29 UTC (rev 75)
@@ -333,8 +333,15 @@
end
@filestack[file] = true
+ # LibXML doesn't handle attempting to open a non-existent file well
+ # http://rubyforge.org/tracker/index.php?func=detail&aid=23836&group_id=494&atid=1971
+ config_xml_file = File.join(@sourcebase, file, 'config.xml')
+ if !File.exist?(config_xml_file)
+ raise "config.xml for #{file} does not exist"
+ end
+
# Load the config.xml file
- config_xml = LibXML::XML::Document.file(File.join(@sourcebase, file, 'config.xml'))
+ config_xml = LibXML::XML::Document.file(config_xml_file)
# Filter the config.xml file by looking for attributes
configfilter!(config_xml.root)
This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site.
|
|
From: <jh...@us...> - 2009-02-06 17:43:32
|
Revision: 74
http://etch.svn.sourceforge.net/etch/?rev=74&view=rev
Author: jheiss
Date: 2009-02-06 17:43:29 +0000 (Fri, 06 Feb 2009)
Log Message:
-----------
Add a make target to make a variant of the Solaris package for Sparc
systems to work around problems we're having with the CSW ruby package.
See the comments added to the file here for more info.
Modified Paths:
--------------
trunk/client/Makefile
Modified: trunk/client/Makefile
===================================================================
--- trunk/client/Makefile 2009-02-06 17:42:49 UTC (rev 73)
+++ trunk/client/Makefile 2009-02-06 17:43:29 UTC (rev 74)
@@ -87,3 +87,52 @@
rm -rf $(BUILDROOT)
rm -f prototype
+# On Sparc systems we're having problems with the CSW/Blastwave ruby
+# core dumping when running etch. The Sunfreeware ruby seems to work.
+# Sunfreeware doesn't play well with pkg-get, so we create a bit of a
+# hybrid. We still express all the dependencies against CSW, and put
+# our library file (etch.rb) into /opt/csw. We modify etch to use
+# the Sunfreeware ruby in /usr/local/bin, but then tell it to also look
+# in the /opt/csw directory for libraries.
+solaris-sparc: pkginfo depend
+ #
+ # Create package file structure in build root
+ #
+ rm -rf $(BUILDROOT)
+ mkdir -p $(BUILDROOT)/usr/sbin
+ cp -p etch $(BUILDROOT)/usr/sbin
+ mv $(BUILDROOT)/usr/sbin/etch $(BUILDROOT)/usr/sbin/etch.tmp
+ cat $(BUILDROOT)/usr/sbin/etch.tmp | sed 's,/usr/bin/ruby,/usr/local/bin/ruby,' > $(BUILDROOT)/usr/sbin/etch
+ rm $(BUILDROOT)/usr/sbin/etch.tmp
+ mv $(BUILDROOT)/usr/sbin/etch $(BUILDROOT)/usr/sbin/etch.tmp
+ # The $$ in that awk escapes the $ from make
+ cat $(BUILDROOT)/usr/sbin/etch.tmp | awk '/unshift.*__FILE__/ {print "$$:.unshift \"/opt/csw/lib/ruby/site_ruby/1.8\"\n" $$0; next}; {print}' > $(BUILDROOT)/usr/sbin/etch
+ rm $(BUILDROOT)/usr/sbin/etch.tmp
+ chmod 555 $(BUILDROOT)/usr/sbin/etch
+ mkdir -p $(BUILDROOT)/opt/csw/lib/ruby/site_ruby/1.8
+ cp -p etch.rb $(BUILDROOT)/opt/csw/lib/ruby/site_ruby/1.8
+ chmod 444 $(BUILDROOT)/opt/csw/lib/ruby/site_ruby/1.8/etch.rb
+ mkdir -p $(BUILDROOT)/etc/etch
+ cp -p ca.pem $(BUILDROOT)/etc/etch
+ # Cron job for registration
+ cat etch_cron_wrapper | sed 's,/usr/bin/perl,/opt/csw/bin/perl,' > $(BUILDROOT)/usr/sbin/etch_cron_wrapper
+ chmod 555 $(BUILDROOT)/usr/sbin/etch_cron_wrapper
+ #
+ # Now build the package
+ #
+ echo "i pkginfo=./pkginfo" > prototype
+ echo "i depend=./depend" >> prototype
+ echo "i postinstall=./postinstall" >> prototype
+ echo "i postremove=./postremove" >> prototype
+ # The tail +2 removes the first line, which is the base directory
+ # and doesn't need to be included in the package.
+ # The first sed just cleans up the directory names
+ # The second sed tell pkgadd to not force our permissions on directories
+ # The $$ in that sed escapes the $ from make
+ find $(BUILDROOT) | pkgproto | tail +2 | sed "s,$(BUILDROOT),," | sed '/^d/s/[^ ]* [^ ]* [^ ]*$$/? ? ?/' >> prototype
+ pkgmk -r $(BUILDROOT) -d $(PWD)
+ pkgtrans . YPCetch-$(VER)-sparc.pkg YPCetch
+ rm -rf YPCetch
+ rm -rf $(BUILDROOT)
+ rm -f prototype
+
This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site.
|