diff --git a/.travis.yml b/.travis.yml index 8193a1496..cf1d21424 100644 --- a/.travis.yml +++ b/.travis.yml @@ -1,14 +1,18 @@ language: ruby bundler_args: --without development script: "bundle exec rake \"parallel:spec[1]\"" notifications: email: false rvm: - 2.1.0 - 2.0.0 - 1.9.3 - 1.8.7 - ruby-head + - jruby-19mode matrix: allow_failures: - rvm: ruby-head + - rvm: jruby-19mode +env: + - JRUBY_OPTS="-J-Xmx1024m" diff --git a/Gemfile b/Gemfile index 7188ad9b7..5e17080d7 100644 --- a/Gemfile +++ b/Gemfile @@ -1,88 +1,92 @@ source ENV['GEM_SOURCE'] || "https://rubygems.org" def location_for(place, fake_version = nil) if place =~ /^(git[:@][^#]*)#(.*)/ [fake_version, { :git => $1, :branch => $2, :require => false }].compact elsif place =~ /^file:\/\/(.*)/ ['>= 0', { :path => File.expand_path($1), :require => false }] else [place, { :require => false }] end end # C Ruby (MRI) or Rubinius, but NOT Windows platforms :ruby do gem 'pry', :group => :development gem 'yard', :group => :development gem 'redcarpet', '~> 2.0', :group => :development gem "racc", "1.4.9", :group => :development end gem "puppet", :path => File.dirname(__FILE__), :require => false gem "facter", *location_for(ENV['FACTER_LOCATION'] || ['> 1.6', '< 3']) gem "hiera", *location_for(ENV['HIERA_LOCATION'] || '~> 1.0') gem "rake", :require => false gem "rgen", "0.6.5", :require => false group(:development, :test) do # Jenkins workers may be using RSpec 2.9, so RSpec 2.11 syntax # (like `expect(value).to eq matcher`) should be avoided. gem "rspec", "~> 2.11.0", :require => false # Mocha is not compatible across minor version changes; because of this only # versions matching ~> 0.10.5 are supported. All other versions are unsupported # and can be expected to fail. gem "mocha", "~> 0.10.5", :require => false gem "yarjuf", "~> 1.0" - # json-schema does not support windows, so use the 'ruby' platform to exclude it on windows - platforms :ruby do - # json-schema uses multi_json, but chokes with multi_json 1.7.9, so prefer 1.7.7 - gem "multi_json", "1.7.7", :require => false - gem "json-schema", "2.1.1", :require => false - end + # json-schema does not support windows, so omit it from the platforms list + # json-schema uses multi_json, but chokes with multi_json 1.7.9, so prefer 1.7.7 + gem "multi_json", "1.7.7", :require => false, :platforms => [:ruby, :jruby] + gem "json-schema", "2.1.1", :require => false, :platforms => [:ruby, :jruby] end group(:development) do case RUBY_VERSION when /^1.8/ gem 'ruby-prof', "~> 0.13.1", :require => false else gem 'ruby-prof', :require => false end end group(:extra) do gem "rack", "~> 1.4", :require => false gem "activerecord", '~> 3.2', :require => false gem "couchrest", '~> 1.0', :require => false gem "net-ssh", '~> 2.1', :require => false gem "puppetlabs_spec_helper", :require => false - gem "sqlite3", :require => false gem "stomp", :require => false gem "tzinfo", :require => false - gem "msgpack", :require => false + case RUBY_PLATFORM + when 'java' + gem "jdbc-sqlite3", :require => false + gem "msgpack-jruby", :require => false + else + gem "sqlite3", :require => false + gem "msgpack", :require => false + end end require 'yaml' data = YAML.load_file(File.join(File.dirname(__FILE__), 'ext', 'project_data.yaml')) bundle_platforms = data['bundle_platforms'] data['gem_platform_dependencies'].each_pair do |gem_platform, info| if bundle_deps = info['gem_runtime_dependencies'] bundle_platform = bundle_platforms[gem_platform] or raise "Missing bundle_platform" platform(bundle_platform.intern) do bundle_deps.each_pair do |name, version| gem(name, version, :require => false) end end end end if File.exists? "#{__FILE__}.local" eval(File.read("#{__FILE__}.local"), binding) end # vim:filetype=ruby diff --git a/lib/puppet/agent.rb b/lib/puppet/agent.rb index 72be5c18d..a06f2e771 100644 --- a/lib/puppet/agent.rb +++ b/lib/puppet/agent.rb @@ -1,122 +1,122 @@ require 'puppet/application' # A general class for triggering a run of another # class. class Puppet::Agent require 'puppet/agent/locker' include Puppet::Agent::Locker require 'puppet/agent/disabler' include Puppet::Agent::Disabler attr_reader :client_class, :client, :splayed, :should_fork # Just so we can specify that we are "the" instance. def initialize(client_class, should_fork=true) @splayed = false @should_fork = can_fork? && should_fork @client_class = client_class end def can_fork? - Puppet.features.posix? + Puppet.features.posix? && RUBY_PLATFORM != 'java' end def needing_restart? Puppet::Application.restart_requested? end # Perform a run with our client. def run(client_options = {}) if running? Puppet.notice "Run of #{client_class} already in progress; skipping (#{lockfile_path} exists)" return end if disabled? Puppet.notice "Skipping run of #{client_class}; administratively disabled (Reason: '#{disable_message}');\nUse 'puppet agent --enable' to re-enable." return end result = nil block_run = Puppet::Application.controlled_run do splay client_options.fetch :splay, Puppet[:splay] result = run_in_fork(should_fork) do with_client do |client| begin client_args = client_options.merge(:pluginsync => Puppet[:pluginsync]) lock { client.run(client_args) } rescue SystemExit,NoMemoryError raise rescue Exception => detail Puppet.log_exception(detail, "Could not run #{client_class}: #{detail}") end end end true end Puppet.notice "Shutdown/restart in progress (#{Puppet::Application.run_status.inspect}); skipping run" unless block_run result end def stopping? Puppet::Application.stop_requested? end # Have we splayed already? def splayed? splayed end # Sleep when splay is enabled; else just return. def splay(do_splay = Puppet[:splay]) return unless do_splay return if splayed? time = rand(Puppet[:splaylimit] + 1) Puppet.info "Sleeping for #{time} seconds (splay is enabled)" sleep(time) @splayed = true end def run_in_fork(forking = true) return yield unless forking or Puppet.features.windows? child_pid = Kernel.fork do $0 = "puppet agent: applying configuration" begin exit(yield) rescue SystemExit exit(-1) rescue NoMemoryError exit(-2) end end exit_code = Process.waitpid2(child_pid) case exit_code[1].exitstatus when -1 raise SystemExit when -2 raise NoMemoryError end exit_code[1].exitstatus end private # Create and yield a client instance, keeping a reference # to it during the yield. def with_client begin @client = client_class.new rescue SystemExit,NoMemoryError raise rescue Exception => detail Puppet.log_exception(detail, "Could not create instance of #{client_class}: #{detail}") return end yield @client ensure @client = nil end end