Issue #7749 has been updated by Daniel Pittman.
> Can you be a bit more specific about what’s happening that’s a problem? I can, indeed. > What’s the code in CommandLine and Application that has to run before core > is loaded? Is this a fundamental flaw, or a happenstance of implementation? This is happenstance; I can't see any compelling reason we *must* behave the way we currently do, although my gut feeling is that it will be complicated to get to different behaviour. (Also, perhaps a little of this is always unavoidable; something, somewhere will have to bootstrap at some time.) Further, I think that a lot of this complexity accreted over time. It probably started quite reasonably, years back, and as we added more capabilities, merged to the single binary, and modified our bootstrap process we ended up in this position. It has all the hallmarks of code flow that should have been cleaned up along the way and, for various good reasons like time pressure, just wasn't. I can't give you an assurance that I have a perfect understanding of all the code. Parts of this are a black box, where I understood just enough to know what behaviour was occurring at a very high level, without understanding the ramifications fully. I do know enough to explain the obvious tip of the potential iceberg here. (...or, it could be this shallow. I /think/ it is, but I can't be sure without a lot more time.) So, the core problem is that when you `require 'puppet'` you implicitly *run* the code in `puppet/defaults.rb` in the context of the top level `Puppet` module. That, in turn, has dependencies on the `run_mode` and/or does setup for the defaults based on the application that is running. Meanwhile, in `Puppet::Util::CommandLine` we actually load the application in the `execute` *instance* method. Loading the application file causes the desired `run_mode` to be declared - this is done at the time the file is loaded. The next thing that the `execute` method does is create an instance of the application class. In the `Puppet::Application` initialize method a small set of things happen: we require the command line file, store that away, then call `set_run_mode` with the `run_mode` we stashed away earlier, at load time. (Here, of course, we are in execution time.) Then, finally, that method will call `require "puppet"` *after* doing all the rest of the setup. This, in our bootstrap process, is when we load the top level class, and so evaluate the defaults: triggered at "load" time, but with that loading deliberately delayed until a bunch of "execution" time code has run to configure global state. I introduced the problem by requiring puppet at the time the command line stuff was loaded, long before the code was executed and the objects instantiated that actually configured the global state of the code. This led to invalid values for various settings, breaking startup in limited ways that showed up in our acceptance tests. To fix this, we should make sure that it is possible to just execute `require "puppet"` as the very first line of whatever loads the puppet code; that, in turn, implies that any library we write can just require the top level puppet module if they depend on it. To get there, I can identify that we need to at least disambiguate the way we handle building the defaults, and the way they interact with the `run_mode`. On the plus side, this *also* means that it should be possible to change `run_mode` at runtime without any risk of things going wrong. :) ---------------------------------------- Refactor #7749: Bootstrapping Puppet in Ruby code has nasty scope cycles... https://projects.puppetlabs.com/issues/7749 Author: Daniel Pittman Status: Unreviewed Priority: Normal Assignee: Category: Target version: Affected Puppet version: Keywords: Branch: So, in debugging an issue using code during early startup of Puppet, I found out that we have some very strange run-scope dependencies in bootstrapping. Specifically, we depend on *runtime* code in `Puppet::Util::CommandLine` and `Puppet::Application` executing before we can safely execute *load* time code in `Puppet`. This manifests as strange defaults in the configuration, because the run mode is configured in P::A during that run-scope code, but the defaults load in puppet earlier than that. This also makes it difficult to just `require 'puppet'` and have things actually work. Coupled with a desire to be able to change run mode on the fly, and a longer term need for things that Faces abstract over to act as if in a run mode without the current hard-coded dependency, we kind of need to get this resolved. -- You have received this notification because you have either subscribed to it, or are involved in it. To change your notification preferences, please click here: http://projects.puppetlabs.com/my/account -- You received this message because you are subscribed to the Google Groups "Puppet Bugs" group. To post to this group, send email to [email protected]. To unsubscribe from this group, send email to [email protected]. For more options, visit this group at http://groups.google.com/group/puppet-bugs?hl=en.
