hudson 0.2.4 → 0.2.5.pre2

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -0,0 +1,16 @@
1
+ require 'socket'
2
+
3
+ Before do
4
+ @hudson_cleanup = []
5
+ end
6
+
7
+ After do
8
+ for port in @hudson_cleanup do
9
+ begin
10
+ TCPSocket.open("localhost", port) do |sock|
11
+ sock.write("0")
12
+ end
13
+ rescue
14
+ end
15
+ end
16
+ end
@@ -0,0 +1,12 @@
1
+
2
+ module Matchers
3
+ def contain(expected)
4
+ Spec::Matchers::SimpleMatcher.new("contain #{expected.inspect}") do |given, matcher|
5
+ matcher.failure_message = "expected #{given.inspect} to contain #{expected.inspect}"
6
+ matcher.negative_failure_message = "expected #{given.inspect} not to contain #{expected.inspect}"
7
+ given.index expected
8
+ end
9
+ end
10
+ end
11
+
12
+ World(Matchers)
data/hudson.gemspec ADDED
@@ -0,0 +1,57 @@
1
+ # -*- encoding: utf-8 -*-
2
+
3
+ Gem::Specification.new do |s|
4
+ s.name = %q{hudson}
5
+ s.version = "0.2.5.pre2"
6
+
7
+ s.required_rubygems_version = Gem::Requirement.new("> 1.3.1") if s.respond_to? :required_rubygems_version=
8
+ s.authors = ["Charles Lowell", "Dr Nic Williams"]
9
+ s.date = %q{2010-06-22}
10
+ s.default_executable = %q{hudson}
11
+ s.description = %q{A suite of utilities for bringing continous integration to your projects (not the other way around) with hudson CI}
12
+ s.email = ["cowboyd@thefrontside.net", "drnicwilliams@gmail.com"]
13
+ s.executables = ["hudson"]
14
+ s.files = ["bin", "bin/hudson", "features", "features/create_jobs.feature", "features/development.feature", "features/fixtures", "features/fixtures/projects", "features/fixtures/projects/ruby", "features/fixtures/projects/ruby/Rakefile", "features/managing_remote_servers.feature", "features/server.feature", "features/step_definitions", "features/step_definitions/common_steps.rb", "features/step_definitions/fixture_project_steps.rb", "features/step_definitions/hudson_steps.rb", "features/step_definitions/scm_steps.rb", "features/support", "features/support/common.rb", "features/support/env.rb", "features/support/hooks.rb", "features/support/matchers.rb", "hudson.gemspec", "lib", "lib/hudson", "lib/hudson/api.rb", "lib/hudson/cli", "lib/hudson/cli/formatting.rb", "lib/hudson/cli.rb", "lib/hudson/hudson.war", "lib/hudson/job_config_builder.rb", "lib/hudson/plugins", "lib/hudson/plugins/git.hpi", "lib/hudson/plugins/github.hpi", "lib/hudson/plugins/greenballs.hpi", "lib/hudson/plugins/rake.hpi", "lib/hudson/plugins/ruby.hpi", "lib/hudson/project_scm.rb", "lib/hudson.rb", "Rakefile", "README.md", "spec", "spec/fixtures", "spec/fixtures/ec2_global.config.xml", "spec/fixtures/rails.multi.config.xml", "spec/fixtures/rails.single.config.xml", "spec/fixtures/rubygem.config.xml", "spec/fixtures/therubyracer.config.xml", "spec/job_config_builder_spec.rb", "spec/spec_helper.rb"]
15
+ s.homepage = %q{http://github.com/cowboyd/hudson.rb}
16
+ s.require_paths = ["lib"]
17
+ s.rubyforge_project = %q{hudson}
18
+ s.rubygems_version = %q{1.3.7}
19
+ s.summary = %q{Painless Continuous Integration with Hudson Server}
20
+
21
+ if s.respond_to? :specification_version then
22
+ current_version = Gem::Specification::CURRENT_SPECIFICATION_VERSION
23
+ s.specification_version = 3
24
+
25
+ if Gem::Version.new(Gem::VERSION) >= Gem::Version.new('1.2.0') then
26
+ s.add_runtime_dependency(%q<term-ansicolor>, [">= 1.0.4"])
27
+ s.add_runtime_dependency(%q<yajl-ruby>, [">= 0.7.6"])
28
+ s.add_runtime_dependency(%q<httparty>, ["~> 0.5.2"])
29
+ s.add_runtime_dependency(%q<builder>, ["~> 2.1.2"])
30
+ s.add_runtime_dependency(%q<thor>, ["~> 0.13.6"])
31
+ s.add_runtime_dependency(%q<hpricot>, [">= 0"])
32
+ s.add_development_dependency(%q<cucumber>, ["~> 0.7.3"])
33
+ s.add_development_dependency(%q<rspec>, ["~> 1.3.0"])
34
+ s.add_development_dependency(%q<json>, ["~> 1.4.0"])
35
+ else
36
+ s.add_dependency(%q<term-ansicolor>, [">= 1.0.4"])
37
+ s.add_dependency(%q<yajl-ruby>, [">= 0.7.6"])
38
+ s.add_dependency(%q<httparty>, ["~> 0.5.2"])
39
+ s.add_dependency(%q<builder>, ["~> 2.1.2"])
40
+ s.add_dependency(%q<thor>, ["~> 0.13.6"])
41
+ s.add_dependency(%q<hpricot>, [">= 0"])
42
+ s.add_dependency(%q<cucumber>, ["~> 0.7.3"])
43
+ s.add_dependency(%q<rspec>, ["~> 1.3.0"])
44
+ s.add_dependency(%q<json>, ["~> 1.4.0"])
45
+ end
46
+ else
47
+ s.add_dependency(%q<term-ansicolor>, [">= 1.0.4"])
48
+ s.add_dependency(%q<yajl-ruby>, [">= 0.7.6"])
49
+ s.add_dependency(%q<httparty>, ["~> 0.5.2"])
50
+ s.add_dependency(%q<builder>, ["~> 2.1.2"])
51
+ s.add_dependency(%q<thor>, ["~> 0.13.6"])
52
+ s.add_dependency(%q<hpricot>, [">= 0"])
53
+ s.add_dependency(%q<cucumber>, ["~> 0.7.3"])
54
+ s.add_dependency(%q<rspec>, ["~> 1.3.0"])
55
+ s.add_dependency(%q<json>, ["~> 1.4.0"])
56
+ end
57
+ end
data/lib/hudson/api.rb ADDED
@@ -0,0 +1,43 @@
1
+ require 'httparty'
2
+ require 'cgi'
3
+
4
+ module Hudson
5
+ class Api
6
+ include HTTParty
7
+
8
+ headers 'content-type' => 'application/json'
9
+ format :json
10
+ # http_proxy 'localhost', '8888'
11
+
12
+ def self.setup_base_url(options)
13
+ server_name, host, port = options[:server], options[:host], options[:port]
14
+ return false unless host || server_name
15
+ p "http://#{host}:#{port}"
16
+ base_uri "http://#{host}:#{port}"
17
+ end
18
+
19
+ # returns true if successfully create a new job on Hudson
20
+ def self.create_job(name, job_config)
21
+ res = post "/createItem/api/xml?name=#{CGI.escape(name)}", {
22
+ :body => job_config.to_xml, :format => :xml, :headers => { 'content-type' => 'application/xml' }
23
+ }
24
+ if res.code == 200
25
+ true
26
+ else
27
+ require "hpricot"
28
+ puts "Server error:"
29
+ puts Hpricot(res.body).search("//body").text
30
+ false
31
+ end
32
+ end
33
+
34
+ def self.summary
35
+ get "/api/json"
36
+ end
37
+
38
+ # Return hash of job sta
39
+ def self.job(name)
40
+ get "/job/#{name}/api/json"
41
+ end
42
+ end
43
+ end
@@ -0,0 +1,53 @@
1
+ require 'term/ansicolor'
2
+
3
+ module Hudson
4
+ class CLI < Thor
5
+ module Formatting
6
+ module ClassMethods
7
+ def task_help(shell, task_name)
8
+ meth = normalize_task_name(task_name)
9
+ task = all_tasks[meth]
10
+ handle_no_task_error(meth) unless task
11
+
12
+ shell.say "usage: #{banner(task)}"
13
+ shell.say
14
+ class_options_help(shell, nil => task.options.map { |_, o| o })
15
+ # shell.say task.description
16
+ # shell.say
17
+ end
18
+
19
+
20
+ def print_options(shell, options, grp = nil)
21
+ return if options.empty?
22
+ table = options.map do |option|
23
+ prototype = if option.default
24
+ " [#{option.default}]"
25
+ elsif option.boolean
26
+ ""
27
+ elsif option.required?
28
+ " #{option.banner}"
29
+ else
30
+ " [#{option.banner}]"
31
+ end
32
+ aliases = option.aliases.empty? ? "" : option.aliases.join(" ") + ","
33
+ [aliases, "--#{option.name}#{prototype}", "\t",option.description]
34
+ end
35
+ shell.print_table(table, :ident => 2)
36
+ shell.say
37
+ end
38
+ end
39
+
40
+ module InstanceMethods
41
+ def c
42
+ Term::ANSIColor
43
+ end
44
+ end
45
+
46
+ def self.included(receiver)
47
+ receiver.extend ClassMethods
48
+ receiver.send :include, InstanceMethods
49
+ end
50
+ end
51
+ end
52
+ end
53
+
data/lib/hudson/cli.rb ADDED
@@ -0,0 +1,141 @@
1
+ require 'thor'
2
+ require 'hudson/cli/formatting'
3
+
4
+ module Hudson
5
+ class CLI < Thor
6
+ include CLI::Formatting
7
+
8
+ map "-v" => :version, "--version" => :version, "-h" => :help, "--help" => :help
9
+
10
+ def self.common_options
11
+ method_option :host, :desc => 'connect to hudson server on this host'
12
+ method_option :port, :desc => 'connect to hudson server on this port'
13
+ method_option :server, :desc => 'connect to remote hudson server by search'
14
+ end
15
+
16
+ desc "server [options]", "run a hudson server"
17
+ method_option :home, :type => :string, :default => File.join(ENV['HOME'], ".hudson", "server"), :banner => "PATH", :desc => "use this directory to store server data"
18
+ method_option :port, :type => :numeric, :default => 3001, :desc => "run hudson server on this port", :aliases => "-p"
19
+ method_option :control, :type => :numeric, :default => 3002, :desc => "set the shutdown/control port", :aliases => "-c"
20
+ method_option :daemon, :type => :boolean, :default => false, :desc => "fork into background and run as a daemon"
21
+ method_option :kill, :type => :boolean, :desc => "send shutdown signal to control port", :aliases => "-k"
22
+ method_option :logfile, :type => :string, :banner => "PATH", :desc => "redirect log messages to this file"
23
+ def server
24
+ if options[:kill]
25
+ require 'socket'
26
+ TCPSocket.open("localhost", options[:control]) do |sock|
27
+ sock.write("0")
28
+ end
29
+ exit
30
+ end
31
+
32
+ serverhome = File.join(options[:home])
33
+ javatmp = File.join(serverhome, "javatmp")
34
+ FileUtils.mkdir_p serverhome
35
+ FileUtils.mkdir_p javatmp
36
+ FileUtils.cp_r Hudson::PLUGINS, serverhome
37
+ ENV['HUDSON_HOME'] = serverhome
38
+ cmd = ["java", "-Djava.io.tmpdir=#{javatmp}", "-jar", Hudson::WAR]
39
+ cmd << "--daemon" if options[:daemon]
40
+ cmd << "--logfile=#{File.expand_path(options[:logfile])}" if options[:logfile]
41
+ cmd << "--httpPort=#{options[:port]}"
42
+ cmd << "--controlPort=#{options[:control]}"
43
+ puts cmd.join(" ")
44
+ exec(*cmd)
45
+ end
46
+
47
+ desc "create [project_path] [options]", "create a continuous build for your project"
48
+ common_options
49
+ method_option :name, :banner => "dir_name", :desc => "name of the build"
50
+ def create(project_path = ".")
51
+ select_hudson_server(options)
52
+ FileUtils.chdir(project_path) do
53
+ unless scm = Hudson::ProjectScm.discover
54
+ error "Cannot determine project SCM. Currently supported: #{Hudson::ProjectScm.supported}"
55
+ end
56
+ job_config = Hudson::JobConfigBuilder.new(:rubygem) do |c|
57
+ c.scm = scm.url
58
+ end
59
+ name = options[:name] || File.basename(FileUtils.pwd)
60
+ if Hudson::Api.create_job(name, job_config)
61
+ build_url = "http://#{options[:host]}:#{options[:port]}/job/#{name.gsub(/\s/,'%20')}/build"
62
+ puts "Added project '#{name}' to Hudson."
63
+ puts "Trigger builds via: #{build_url}"
64
+ else
65
+ error "Failed to create project '#{name}'"
66
+ end
67
+ end
68
+ end
69
+
70
+ desc "list [project_path] [options]", "list builds on a hudson server"
71
+ common_options
72
+ def list(project_path = ".")
73
+ select_hudson_server(options)
74
+ FileUtils.chdir(project_path) do
75
+ if summary = Hudson::Api.summary
76
+ if summary["jobs"]
77
+ summary["jobs"].each do |job|
78
+ color = job['color']
79
+ color = 'green' if color == 'blue'
80
+ shell.say job['name'], color.to_sym, false
81
+ shell.say " - #{job['url']}"
82
+ end
83
+ else
84
+ display "No jobs found on #{options[:host]}:#{options[:port]}"
85
+ end
86
+ else
87
+ error "Failed connection to #{options[:host]}:#{options[:port]}"
88
+ end
89
+ end
90
+ end
91
+
92
+ desc "remote command [options]", "manage integration with hudson servers"
93
+ def remote(command)
94
+ puts command
95
+ end
96
+
97
+
98
+ desc "help [command]", "show help for hudson or for a specific command"
99
+ def help(*args)
100
+ super(*args)
101
+ end
102
+
103
+ desc "version", "show version information"
104
+ def version
105
+ shell.say "#{Hudson::VERSION} (Hudson Server #{Hudson::HUDSON_VERSION})"
106
+ end
107
+
108
+ def self.help(shell)
109
+ list = printable_tasks
110
+ shell.say <<-USEAGE
111
+ Hudson.rb is a smart set of utilities for making
112
+ continuous integration as simple as possible
113
+
114
+ Usage: hudson command [arguments] [options]
115
+
116
+ USEAGE
117
+
118
+ shell.say "Commands:"
119
+ shell.print_table(list, :ident => 2, :truncate => true)
120
+ shell.say
121
+ class_options_help(shell)
122
+ end
123
+
124
+ private
125
+
126
+ def select_hudson_server(options)
127
+ unless Hudson::Api.setup_base_url(options)
128
+ error "Either use --host or add remote servers."
129
+ end
130
+ end
131
+ def display(text)
132
+ shell.say text
133
+ exit
134
+ end
135
+
136
+ def error(text)
137
+ shell.say "ERROR: #{text}"
138
+ exit
139
+ end
140
+ end
141
+ end
Binary file
@@ -0,0 +1,161 @@
1
+ require "builder"
2
+
3
+ module Hudson
4
+ class JobConfigBuilder
5
+ attr_accessor :scm, :git_branches
6
+ attr_accessor :job_type, :matrix_project
7
+
8
+ def initialize(options = nil, &block)
9
+ if options.is_a?(Symbol)
10
+ @job_type = options.to_s
11
+ elsif options.is_a?(Hash)
12
+ @job_type = options[:job_type].to_s
13
+ end
14
+ @matrix_project = %w[rubygem].include? job_type
15
+ yield self
16
+ @git_branches ||= ["**"]
17
+ end
18
+
19
+ def builder
20
+ b = Builder::XmlMarkup.new :indent => 2
21
+ b.instruct!
22
+ b.tag!(matrix_project ? "matrix-project" : "project") do
23
+ b.actions
24
+ b.description
25
+ b.keepDependencies false
26
+ b.properties
27
+ build_scm b
28
+ b.canRoam true
29
+ b.disabled false
30
+ b.blockBuildWhenUpstreamBuilding false
31
+ build_triggers b
32
+ b.concurrentBuild false
33
+ build_axes b if matrix_project
34
+ build_steps b
35
+ b.publishers
36
+ b.buildWrappers
37
+ b.runSequentially false if matrix_project
38
+ end
39
+ end
40
+
41
+ def to_xml
42
+ builder.to_s
43
+ end
44
+
45
+ protected
46
+
47
+ # <scm class="hudson.plugins.git.GitSCM"> ... </scm>
48
+ def build_scm(b)
49
+ if scm && scm =~ /git/
50
+ b.scm :class => "hudson.plugins.git.GitSCM" do
51
+ b.configVersion 1
52
+ b.remoteRepositories do
53
+ b.tag! "org.spearce.jgit.transport.RemoteConfig" do
54
+ b.string "origin"
55
+ b.int 5
56
+ b.string "fetch"
57
+ b.string "+refs/heads/*:refs/remotes/origin/*"
58
+ b.string "receivepack"
59
+ b.string "git-upload-pack"
60
+ b.string "uploadpack"
61
+ b.string "git-upload-pack"
62
+ b.string "url"
63
+ b.string scm
64
+ b.string "tagopt"
65
+ b.string
66
+ end
67
+ end
68
+
69
+ if git_branches
70
+ b.branches do
71
+ git_branches.each do |branch|
72
+ b.tag! "hudson.plugins.git.BranchSpec" do
73
+ b.name branch
74
+ end
75
+ end
76
+ end
77
+ end
78
+
79
+ b.mergeOptions
80
+ b.doGenerateSubmoduleConfigurations false
81
+ b.clean false
82
+ b.choosingStrategy "Default"
83
+ b.submoduleCfg :class => "list"
84
+ end
85
+ end
86
+ end
87
+
88
+ # <triggers class="vector">
89
+ # <hudson.triggers.SCMTrigger>
90
+ # <spec># every minute
91
+ # * * * * *</spec>
92
+ # </hudson.triggers.SCMTrigger>
93
+ # </triggers>
94
+ def build_triggers(b)
95
+ b.triggers :class => "vector" do
96
+ b.tag! "hudson.triggers.SCMTrigger" do
97
+ b.spec "# every minute\n* * * * *"
98
+ end
99
+ end
100
+ end
101
+
102
+ def build_axes(b)
103
+ b.axes
104
+ end
105
+
106
+ def build_steps(b)
107
+ b.builders do
108
+ if job_type == "rails"
109
+ build_ruby_step b, <<-RUBY.gsub(/^ /, '')
110
+ unless File.exist?("config/database.yml")
111
+ require 'fileutils'
112
+ example = Dir["config/database*"].first
113
+ puts "Using \#{example} for config/database.yml"
114
+ FileUtils.cp example, "config/database.yml"
115
+ end
116
+ RUBY
117
+ build_rake_step b, "db:schema:load"
118
+ build_rake_step b, "features"
119
+ build_rake_step b, "spec"
120
+ elsif job_type == "rubygem"
121
+ build_rake_step b, "features"
122
+ end
123
+ end
124
+ end
125
+
126
+ # <hudson.plugins.ruby.Ruby>
127
+ # <command>unless File.exist?(&quot;config/database.yml&quot;)
128
+ # require &apos;fileutils&apos;
129
+ # example = Dir[&quot;config/database*&quot;].first
130
+ # puts &quot;Using #{example} for config/database.yml&quot;
131
+ # FileUtils.cp example, &quot;config/database.yml&quot;
132
+ # end</command>
133
+ # </hudson.plugins.ruby.Ruby>
134
+ def build_ruby_step(b, command)
135
+ b.tag! "hudson.plugins.ruby.Ruby" do
136
+ b.command command
137
+ end
138
+ end
139
+
140
+ # Usage: build_ruby_step b, "db:schema:load"
141
+ #
142
+ # <hudson.plugins.rake.Rake>
143
+ # <rakeInstallation>(Default)</rakeInstallation>
144
+ # <rakeFile></rakeFile>
145
+ # <rakeLibDir></rakeLibDir>
146
+ # <rakeWorkingDir></rakeWorkingDir>
147
+ # <tasks>db:schema:load</tasks>
148
+ # <silent>false</silent>
149
+ # </hudson.plugins.rake.Rake>
150
+ def build_rake_step(b, tasks)
151
+ b.tag! "hudson.plugins.rake.Rake" do
152
+ b.rakeInstallation "(Default)"
153
+ b.rakeFile
154
+ b.rakeLibDir
155
+ b.rakeWorkingDir
156
+ b.tasks tasks
157
+ b.silent false
158
+ end
159
+ end
160
+ end
161
+ end
@@ -0,0 +1,22 @@
1
+ module Hudson
2
+ class ProjectScm
3
+
4
+ def self.discover
5
+ ProjectScmGit.new if File.exist?(".git") && File.directory?(".git")
6
+ end
7
+
8
+ def self.supported
9
+ %w[git]
10
+ end
11
+ end
12
+
13
+ class ProjectScmGit < ProjectScm
14
+ def initialize(url = nil)
15
+ @url = nil
16
+ end
17
+
18
+ def url
19
+ @url ||= `git config remote.origin.url`.strip
20
+ end
21
+ end
22
+ end
data/lib/hudson.rb CHANGED
@@ -1,6 +1,10 @@
1
1
  module Hudson
2
- VERSION = "0.2.4"
3
- HUDSON_VERSION = "1.359"
4
- WAR = File.expand_path(File.dirname(__FILE__) + "/hudson/hudson.war")
5
- PLUGINS = File.expand_path(File.dirname(__FILE__) + "/hudson/plugins")
6
- end
2
+ VERSION = "0.2.5.pre2"
3
+ HUDSON_VERSION = "1.363"
4
+ WAR = File.expand_path(File.dirname(__FILE__) + "/hudson/hudson.war")
5
+ PLUGINS = File.expand_path(File.dirname(__FILE__) + "/hudson/plugins")
6
+ end
7
+
8
+ require 'hudson/api'
9
+ require 'hudson/job_config_builder'
10
+ require 'hudson/project_scm'
@@ -0,0 +1,103 @@
1
+ <?xml version='1.0' encoding='UTF-8'?>
2
+ <hudson>
3
+ <version>1.359</version>
4
+ <numExecutors>2</numExecutors>
5
+ <mode>NORMAL</mode>
6
+ <authorizationStrategy class="hudson.security.AuthorizationStrategy$Unsecured"/>
7
+ <securityRealm class="hudson.security.SecurityRealm$None"/>
8
+ <jdks/>
9
+ <clouds>
10
+ <hudson.plugins.ec2.EC2Cloud>
11
+ <name>ec2-US_EAST_1</name>
12
+ <accessId>0MVEQ5Q0BNYEGJX898G2</accessId>
13
+ <secretKey>[REMOVED]</secretKey>
14
+ <privateKey>
15
+ <privateKey>[REMOVED]</privateKey>
16
+ </privateKey>
17
+ <instanceCap>2147483647</instanceCap>
18
+ <templates>
19
+ <hudson.plugins.ec2.SlaveTemplate>
20
+ <ami>ami-79d43d10</ami>
21
+ <description>Ubuntu Lucid 10.04 64bit Server</description>
22
+ <remoteFS>/mnt/hudson</remoteFS>
23
+ <type>LARGE</type>
24
+ <labels>Ubuntu-Lucid-10.04-server-amd64 GCC_44</labels>
25
+ <initScript></initScript>
26
+ <userData></userData>
27
+ <numExecutors>4</numExecutors>
28
+ <remoteAdmin>ubuntu</remoteAdmin>
29
+ <rootCommandPrefix>sudo</rootCommandPrefix>
30
+ </hudson.plugins.ec2.SlaveTemplate>
31
+ <hudson.plugins.ec2.SlaveTemplate>
32
+ <ami>ami-e7d53c8e</ami>
33
+ <description>Ubuntu Karmic 9.10 64bit Server</description>
34
+ <remoteFS>/mnt/hudson</remoteFS>
35
+ <type>LARGE</type>
36
+ <labels>Ubuntu-Karmic-9.10-server-amd64 GCC_43</labels>
37
+ <initScript></initScript>
38
+ <userData></userData>
39
+ <numExecutors>4</numExecutors>
40
+ <remoteAdmin>ubuntu</remoteAdmin>
41
+ <rootCommandPrefix>sudo</rootCommandPrefix>
42
+ </hudson.plugins.ec2.SlaveTemplate>
43
+ </templates>
44
+ <region>US_EAST_1</region>
45
+ </hudson.plugins.ec2.EC2Cloud>
46
+ </clouds>
47
+ <slaves>
48
+ <slave>
49
+ <name>Legolas</name>
50
+ <description>Legolas Mac Pro</description>
51
+ <remoteFS>/Users/hudon/work</remoteFS>
52
+ <numExecutors>2</numExecutors>
53
+ <mode>NORMAL</mode>
54
+ <retentionStrategy class="hudson.slaves.RetentionStrategy$Always"/>
55
+ <launcher class="hudson.plugins.sshslaves.SSHLauncher">
56
+ <host>legolas.thefrontside.net</host>
57
+ <port>22</port>
58
+ <username>cowboyd</username>
59
+ <password>[REMOVED]</password>
60
+ <privatekey></privatekey>
61
+ <jvmOptions></jvmOptions>
62
+ </launcher>
63
+ <label>OSX-Snow-Leopard-10.6.3</label>
64
+ <nodeProperties/>
65
+ </slave>
66
+ <slave>
67
+ <name>Gimli</name>
68
+ <description>The Mac Mini Sitting on the bookshelf at the frontside office</description>
69
+ <remoteFS>/Users/hudson/work</remoteFS>
70
+ <numExecutors>2</numExecutors>
71
+ <mode>NORMAL</mode>
72
+ <retentionStrategy class="hudson.slaves.RetentionStrategy$Always"/>
73
+ <launcher class="hudson.plugins.sshslaves.SSHLauncher">
74
+ <host>gimli.thefrontside.net</host>
75
+ <port>22</port>
76
+ <username>hudson</username>
77
+ <password>[REMOVED]</password>
78
+ <privatekey></privatekey>
79
+ <jvmOptions></jvmOptions>
80
+ </launcher>
81
+ <label>OSX-Leopard-10.5</label>
82
+ <nodeProperties/>
83
+ </slave>
84
+ </slaves>
85
+ <quietPeriod>5</quietPeriod>
86
+ <scmCheckoutRetryCount>0</scmCheckoutRetryCount>
87
+ <views>
88
+ <hudson.model.AllView>
89
+ <owner class="hudson" reference="../../.."/>
90
+ <name>All</name>
91
+ <filterExecutors>false</filterExecutors>
92
+ <filterQueue>false</filterQueue>
93
+ </hudson.model.AllView>
94
+ </views>
95
+ <primaryView>All</primaryView>
96
+ <slaveAgentPort>0</slaveAgentPort>
97
+ <label></label>
98
+ <nodeProperties/>
99
+ <globalNodeProperties/>
100
+ <disabledAdministrativeMonitors>
101
+ <string>OldData</string>
102
+ </disabledAdministrativeMonitors>
103
+ </hudson>