Permalink
Browse files

Merge remote-tracking branch 'upstream/2.7.x'

* upstream/2.7.x: (22 commits)
  Removed duplication of compiling a catalog
  Cleaner test for create_resources doing nothing
  Fixing problem caused by activerecord
  Put back require 'puppet' in Puppet::Util
  (#13299) Fix error message when agent is disabled
  Update puppet.spec for rpm packaging
  Fixed old log test to match new autoflush behavior
  Make sure the log file writable
  Default autoflushing of log files to true
  Created test that shows enc warning problem
  (Maint) Fix order-dependent test failure
  (Maint) Don't assume eventlog gem is installed on Windows
  options[:ca_location] is a string not a symbol. Safer to pull Puppet::SSL::Host.ca_location since it is already set correctly.
  (#13204) Don't ignore missing PATH.augnew files
  (#13640) Only agents should use next_agent_run
  Increased test coverage of scoping rules
  Use more descriptive terms for the differing scopes
  Make new scoping look through inherited scopes
  Add tests for mixed inheritence/inclusion
  Remove dynamic option for lookupvar
  ...

Conflicts:
	lib/puppet/defaults.rb
	lib/puppet/parser/scope.rb
	spec/unit/parser/functions/create_resources_spec.rb
	spec/unit/parser/scope_spec.rb
	spec/unit/resource/type_spec.rb
	test/util/log.rb
  • Loading branch information...
2 parents 32172d5 + 8908c09 commit 7a430815424e053d6e6c5925eef711ca5edd8373 @zaphod42 zaphod42 committed Apr 16, 2012
@@ -0,0 +1,80 @@
+test_name "#8174: incorrect warning about deprecated scoping"
+
+testdir = master.tmpdir('scoping_deprecation')
+
+create_remote_file(master, "#{testdir}/puppet.conf", <<END)
+[main]
+node_terminus = exec
+external_nodes = "#{testdir}/enc"
+manifest = "#{testdir}/site.pp"
+modulepath = "#{testdir}/modules"
+END
+
+on master, "mkdir -p #{testdir}/modules/a/manifests"
+
+create_remote_file(master, "#{testdir}/enc", <<-PP)
+#!/usr/bin/env sh
+
+cat <<END
+---
+classes:
+ a
+parameters:
+ enc_var: "Set from ENC."
+END
+exit 0
+PP
+
+create_remote_file(master, "#{testdir}/site.pp", <<-PP)
+$top_scope = "set from site.pp"
+node default {
+ $node_var = "in node"
+}
+PP
+create_remote_file(master, "#{testdir}/modules/a/manifests/init.pp", <<-PP)
+class a {
+ $locally = "locally declared"
+ $dynamic_for_b = "dynamic and declared in a"
+ notify { "fqdn from facts": message => $fqdn }
+ notify { "locally declared var": message => $locally }
+ notify { "var via enc": message => $enc_var }
+ notify { "declared top scope": message => $top_scope }
+ notify { "declared node": message => $node_var }
+
+ include a::b
+}
+PP
+create_remote_file(master, "#{testdir}/modules/a/manifests/b.pp", <<-PP)
+class a::b {
+ notify { "dynamic from elsewhere": message => $dynamic_for_b }
+}
+PP
+
+on master, "chown -R root:puppet #{testdir}"
+on master, "chmod -R g+rwX #{testdir}"
+on master, "chmod -R a+x #{testdir}/enc"
+on master, "touch #{testdir}/log"
+on master, "chown puppet #{testdir}/log"
+
+assert_log_on_master_contains = lambda do |string|
+ on master, "grep '#{string}' #{testdir}/log"
+end
+
+assert_log_on_master_does_not_contain = lambda do |string|
+ on master, "grep -v '#{string}' #{testdir}/log"
+end
+
+with_master_running_on(master, "--config #{testdir}/puppet.conf --debug --verbose --daemonize --dns_alt_names=\"puppet,$(hostname -s),$(hostname -f)\" --autosign true --logdest #{testdir}/log") do
+ agents.each do |agent|
+ run_agent_on(agent, "--no-daemonize --onetime --server #{master}")
+ end
+
+ assert_log_on_master_contains['Dynamic lookup of $dynamic_for_b']
+ assert_log_on_master_does_not_contain['Dynamic lookup of $fqdn']
+ assert_log_on_master_does_not_contain['Dynamic lookup of $locally']
+ assert_log_on_master_does_not_contain['Dynamic lookup of $enc_var']
+ assert_log_on_master_does_not_contain['Dynamic lookup of $top_scope']
+ assert_log_on_master_does_not_contain['Dynamic lookup of $node_var']
+end
+
+on master, "rm -rf #{testdir}"
@@ -14,13 +14,16 @@ def get_cmd(host)
# get remote time
now = on(agent, "#{get_cmd(agent)} -e \"puts Time.now.utc.strftime('%m/%d/%Y %H:%M:%S')\"").stdout.chomp
+ # it should fail to start since parent directories don't exist
+ confdir = "/does/not/exist"
+
# generate an error, no master on windows boxes
- on agent, puppet_agent('--server', '127.0.0.1', '--test'), :acceptable_exit_codes => [1]
+ on agent, puppet_agent('--server', '127.0.0.1', '--test', '--confdir', confdir), :acceptable_exit_codes => [1]
# make sure there's a Puppet error message in the log
# cygwin + ssh + wmic hangs trying to read stdin, so echo '' |
on agent, "cmd /c echo '' | wmic ntevent where \"LogFile='Application' and SourceName='Puppet' and TimeWritten >= '#{now}'\" get Message,Type /format:csv" do
fail_test "Event not found in Application event log" unless
- stdout =~ /Could not retrieve catalog from remote server.*,Error/m
+ stdout =~ /Cannot create [a-z]:\/does\/not\/exist.*,Error/mi
end
end
View
@@ -5,7 +5,7 @@
%global confdir conf/redhat
Name: puppet
-Version: 2.7.12
+Version: 2.7.13
#Release: 0.1rc1%{?dist}
Release: 1%{?dist}
Summary: A network tool for managing many disparate systems
@@ -21,13 +21,11 @@ Group: System Environment/Base
BuildRoot: %{_tmppath}/%{name}-%{version}-%{release}-root-%(%{__id_u} -n)
BuildRequires: facter >= 1.5
-BuildRequires: ruby >= 1.8.1
+BuildRequires: ruby >= 1.8.5
-%if 0%{?fedora} || 0%{?rhel} >= 5
BuildArch: noarch
Requires: ruby(abi) >= 1.8
Requires: ruby-shadow
-%endif
# Pull in ruby selinux bindings where available
%if 0%{?fedora} || 0%{?rhel} >= 6
@@ -39,7 +37,7 @@ Requires: ruby-shadow
%endif
Requires: facter >= 1.5
-Requires: ruby >= 1.8.1
+Requires: ruby >= 1.8.5
%{!?_without_augeas:Requires: ruby-augeas}
Requires(pre): shadow-utils
@@ -287,6 +285,9 @@ fi
rm -rf %{buildroot}
%changelog
+* Tue Apr 10 2012 Matthaus Litteken <matthaus@puppetlabs.com> - 2.7.13-1
+- Update for 2.7.13
+
* Mon Mar 12 2012 Michael Stahnke <stahnma@puppetlabs.com> - 2.7.12-1
- Update for 2.7.12
View
@@ -32,7 +32,7 @@ def run(*args)
return
end
if disabled?
- Puppet.notice "Skipping run of #{client_class}; administratively disabled; use 'puppet #{client_class} --enable' to re-enable."
+ Puppet.notice "Skipping run of #{client_class}; administratively disabled; use 'puppet agent --enable' to re-enable."
return
end
View
@@ -167,6 +167,13 @@ def run_event_loop
loop do
now = Time.now.to_i
+ # We set a default wakeup of "one hour from now", which will
+ # recheck everything at a minimum every hour. Just in case something in
+ # the math messes up or something; it should be inexpensive enough to
+ # wake once an hour, then go back to sleep after doing nothing, if
+ # someone only wants listen mode.
+ next_event = now + 60 * 60
+
# Handle reparsing of configuration files, if desired and required.
# `reparse` will just check if the action is required, and would be
# better named `reparse_if_changed` instead.
@@ -176,7 +183,12 @@ def run_event_loop
# The time to the next reparse might have changed, so recalculate
# now. That way we react dynamically to reconfiguration.
reparse_interval = Puppet[:filetimeout].to_i
- next_reparse = now + reparse_interval
+
+ # Set up the next reparse check based on the new reparse_interval.
+ if reparse_interval > 0
+ next_reparse = now + reparse_interval
+ next_event > next_reparse and next_event = next_reparse
+ end
# We should also recalculate the agent run interval, and adjust the
# next time it is scheduled to run, just in case. In the event that
@@ -191,21 +203,14 @@ def run_event_loop
# behaviour. You should not change that. --daniel 2012-02-21
if agent and now >= next_agent_run
agent.run
+
+ # Set up the next agent run time
next_agent_run = now + agent_run_interval
+ next_event > next_agent_run and next_event = next_agent_run
end
# Finally, an interruptable able sleep until the next scheduled event.
- # We also set a default wakeup of "one hour from now", which will
- # recheck everything at a minimum every hour. Just in case something in
- # the math messes up or something; it should be inexpensive enough to
- # wake once an hour, then go back to sleep after doing nothing, if
- # someone only wants listen mode.
- next_event = now + 60 * 60
- next_event > next_reparse and next_event = next_reparse
- next_event > next_agent_run and next_event = next_agent_run
-
how_long = next_event - now
-
how_long > 0 and select([], [], [], how_long)
end
end
View
@@ -62,7 +62,7 @@ module Puppet
:desc => "Whether to print stack traces on some errors",
},
:autoflush => {
- :default => false,
+ :default => true,
:type => :boolean,
:desc => "Whether log files should always flush to disk.",
:hook => proc { |value| Log.autoflush = value }
View
@@ -20,7 +20,7 @@ class Puppet::Parser::Scope
attr_accessor :source, :resource
attr_accessor :base, :keyword
attr_accessor :top, :translated, :compiler
- attr_accessor :parent, :dynamic
+ attr_accessor :parent
attr_reader :namespaces
# thin wrapper around an ephemeral
@@ -258,10 +258,63 @@ def qualified_scope(classname)
private :qualified_scope
- # Look up a variable. The simplest value search we do.
- # This method is effectively deprecated - use self[] instead.
+ # Look up a variable with traditional scoping and then with new scoping. If
+ # the answers differ then print a deprecation warning.
def lookupvar(name, options = {})
- self[name, options]
+ dynamic_value = dynamic_lookupvar(name,options)
+ twoscope_value = twoscope_lookupvar(name,options)
+ if dynamic_value != twoscope_value
+ location = (options[:file] && options[:line]) ? " at #{options[:file]}:#{options[:line]}" : ''
+ Puppet.deprecation_warning "Dynamic lookup of $#{name}#{location} is deprecated. Support will be removed in a later version of Puppet. Use a fully-qualified variable name (e.g., $classname::variable) or parameterized classes."
+ end
+ dynamic_value
+ end
+
+ # Look up a variable. The simplest value search we do.
+ def twoscope_lookupvar(name, options = {})
+ # Save the originating scope for the request
+ options[:origin] = self unless options[:origin]
+ table = ephemeral?(name) ? @ephemeral.last : @symtable
+ if name =~ /^(.*)::(.+)$/
+ begin
+ qualified_scope($1).twoscope_lookupvar($2, options.merge({:origin => nil}))
+ rescue RuntimeError => e
+ location = (options[:file] && options[:line]) ? " at #{options[:file]}:#{options[:line]}" : ''
+ warning "Could not look up qualified variable '#{name}'; #{e.message}#{location}"
+ :undefined
+ end
+ # If the value is present and either we are top/node scope or originating scope...
+ elsif (ephemeral_include?(name) or table.include?(name)) and (compiler and self == compiler.topscope or (self.resource and self.resource.type == "Node") or self == options[:origin])
+ table[name]
+ elsif resource and resource.type == "Class" and parent_type = resource.resource_type.parent
+ class_scope(parent_type).twoscope_lookupvar(name,options.merge({:origin => nil}))
+ elsif parent
+ parent.twoscope_lookupvar(name, options)
+ else
+ :undefined
+ end
+ end
+
+ # Look up a variable. The simplest value search we do.
+ def dynamic_lookupvar(name, options = {})
+ table = ephemeral?(name) ? @ephemeral.last : @symtable
+ # If the variable is qualified, then find the specified scope and look the variable up there instead.
+ if name =~ /^(.*)::(.+)$/
+ begin
+ qualified_scope($1).dynamic_lookupvar($2,options)
+ rescue RuntimeError => e
+ location = (options[:file] && options[:line]) ? " at #{options[:file]}:#{options[:line]}" : ''
+ warning "Could not look up qualified variable '#{name}'; #{e.message}#{location}"
+ :undefined
+ end
+ elsif ephemeral_include?(name) or table.include?(name)
+ # We can't use "if table[name]" here because the value might be false
+ table[name]
+ elsif parent
+ parent.dynamic_lookupvar(name,options)
+ else
+ :undefined
+ end
end
# Return a hash containing our variables and their values, optionally (and
@@ -392,7 +445,7 @@ def unset_ephemeral_var(level=:all)
# check if name exists in one of the ephemeral scope.
def ephemeral_include?(name)
- @ephemeral.reverse.each do |eph|
+ @ephemeral.reverse_each do |eph|
return true if eph.include?(name)
end
false
@@ -332,9 +332,8 @@ def need_to_run?
saved_files = @aug.match("/augeas/events/saved")
if saved_files.size > 0
root = resource[:root].sub(/^\/$/, "")
- saved_files.each do |key|
- saved_file = @aug.get(key).sub(/^\/files/, root)
- next unless File.exists?(saved_file + ".augnew")
+ saved_files.map! {|key| @aug.get(key).sub(/^\/files/, root) }
+ saved_files.uniq.each do |saved_file|
if Puppet[:show_diff]
notice "\n" + diff(saved_file, saved_file + ".augnew")
end
@@ -66,7 +66,7 @@ def evaluate_code(resource)
static_parent = evaluate_parent_type(resource)
scope = static_parent || resource.scope
- scope = scope.newscope(:namespace => namespace, :source => self, :resource => resource, :dynamic => !static_parent) unless resource.title == :main
+ scope = scope.newscope(:namespace => namespace, :source => self, :resource => resource) unless resource.title == :main
scope.compiler.add_class(name) unless definition?
set_resource_parameters(resource, scope)
View
@@ -228,6 +228,10 @@ def absolute_path?(path, platform=nil)
:posix => %r!^/!,
}
+ # Due to weird load order issues, I was unable to remove this require.
+ # This is fixed in Telly so it can be removed there.
+ require 'puppet'
+
# Ruby only sets File::ALT_SEPARATOR on Windows and the Ruby standard
# library uses that to test what platform it's on. Normally in Puppet we
# would use Puppet.features.microsoft_windows?, but this method needs to
@@ -0,0 +1,6 @@
+module PuppetSpec::Compiler
+ def compile_to_catalog(string)
+ Puppet[:code] = string
+ Puppet::Parser::Compiler.compile(Puppet::Node.new('foonode'))
+ end
+end
Oops, something went wrong.

0 comments on commit 7a43081

Please sign in to comment.