I'm trying to follow this guide: http://mig5.net/node/346 to learn how to handle provision without Aegir.
However, even with a trivial make file as the one listed in the guide, drush dies with:
drush --root='/var/www/localhost/htdocs' provision-save '@platform_test' --context_type='platform' --makefile='drupal.make'
PHP Fatal error: Allowed memory size of 201326592 bytes exhausted (tried to allocate 130968 bytes) in /usr/share/drush/commands/provision/provision.context.inc on line 139
Fatal error: Allowed memory size of 201326592 bytes exhausted (tried to allocate 130968 bytes) in /usr/share/drush/commands/provision/provision.context.inc on line 139
I tried some variations with relative vs local paths, I cleared out everything from ~/.drush to make sure nothing else was broken and caused some type of conflict. I'm not very familiar with the codebase, but it looks to me like provision get's stuck in loading contexts. It is definitely a recursive loop however.
I counted the length of the backtrace in function get_services(), and it reaches into several thousands if I set php to allow it.
The problem occurs in
[file] => /usr/share/drush/commands/provision/provision.context.inc
[line] => 377
[function] => get_services, which calls back onto itself infinitely.
Below is an excerpt of backtrace of where the problem happens. Number 8 and 9 in this trace, repeat all the way to the top, except the very final call that's always the magic __get function.
[8] => Array (
[file] => /usr/share/drush/commands/provision/provision.context.inc
[line] => 377
[function] => get_services
[class] => provisionContext
[object] => provisionContext_platform Object (
[parent_key] => server
[name] => @server_master
[type] => platform
[properties:protected] => Array (
[context_type] => platform
[server] => @server_master
[web_server] => @server_master
)
[oid_map:protected] => Array (
[server] => 1
[web_server] => 1
)
[service_subs:protected] => Array (
[http] => @server_master
)
)
[type] => ->
[args] => Array ()
)
[9] => Array (
[file] => /usr/share/drush/commands/provision/provision.context.inc
[line] => 377
[function] => get_services
[class] => provisionContext
[object] => provisionContext_platform Object (
[parent_key] => server
[name] => @server_master
[type] => platform
[properties:protected] => Array (
[context_type] => platform
[server] => @server_master
[web_server] => @server_master
)
[oid_map:protected] => Array (
[server] => 1
[web_server] => 1
)
[service_subs:protected] => Array (
[http] => @server_master
)
)
[type] => ->
[args] => Array ()
)
[10] => Array (
[file] => /usr/share/drush/commands/provision/provision.context.inc
[line] => 358
[function] => get_services
[class] => provisionContext
[object] => provisionContext_platform Object (
[parent_key] => server
[name] => @server_master
[type] => platform
[properties:protected] => Array (
[context_type] => platform
[server] => @server_master
[web_server] => @server_master
)
[oid_map:protected] => Array (
[server] => 1
[web_server] => 1
)
[service_subs:protected] => Array (
[http] => @server_master
)
)
[type] => ->
[args] => Array ()
)
[11] => Array (
[file] => /usr/share/drush/commands/provision/provision.context.inc
[line] => 210
[function] => services_invoke
[class] => provisionContext
[object] => provisionContext_platform Object (
[parent_key] => server
[name] => @server_master
[type] => platform
[properties:protected] => Array (
[context_type] => platform
[server] => @server_master
[web_server] => @server_master
)
[oid_map:protected] => Array (
[server] => 1
[web_server] => 1
)
[service_subs:protected] => Array (
[http] => @server_master
)
)
[type] => ->
[args] => Array (
[0] => init
[1] => Array()
)
)
Comment | File | Size | Author |
---|---|---|---|
#11 | provision-1454316-context-loops.patch | 2.79 KB | Steven Jones |
Comments
Comment #1
anarcat CreditAttribution: anarcat commentedCould this be related with this bug #946606: provision-save core dumps on loops?
Comment #2
Letharion CreditAttribution: Letharion commentedNot that I can see, my php doesn't segfault.
I realized a --debug would perhaps also be useful:
Comment #3
Letharion CreditAttribution: Letharion commentedThe difference between "Fatal error: Allowed memory size of 201326592 bytes exhausted" the first time and "Error: Maximum function nesting level of '100' reached, aborting!" is because I've tried with both php 5.3 and 5.4, and their ini files differ a bit.
Comment #4
anarcat CreditAttribution: anarcat commentedI think the core dump was happening in PHP 5.2
Comment #5
Anonymous (not verified) CreditAttribution: Anonymous commentedIs this a duplicate of #946606: provision-save core dumps on loops ?
Comment #6
Letharion CreditAttribution: Letharion commented@mig5, anarcat asked the same thing in #1 :) I'm not sure. I will attempt to debug the problem some more, and get back with more info.
Comment #7
Letharion CreditAttribution: Letharion commentedWhen the provision command inits, we call
This always results in d('@self', TRUE)
Since @self is not a known instance at this point, we call
Which creates a new provisionContext_platform, and runs init() on it. This in turn calls d('@server_master', FALSE); and creates an instance for '@server_master', and runs init on this object.
During my debugging, I noticed that
returns an arrays where all keys 'dns', 'http' and 'db' are NULL. Not sure if that's a problem. As the last step, '@server_master' method_invoke('init'), calls
leading to:
which is the end of our journey. $this->parent_key, is server, so we call get_services() on the parent instead. Problem now is that d(), returns the '@server_master', which is ourselves. Hence $parent_key is _still_ server, and hilarity ensues.
I lack sufficient understanding of the code base to grasp where exactly this goes awry, and would very much like some feedback on the above.
I tried with the newly released 1.7, as well as 2.x, both of which exhibit the same behavior, although I haven't debugged them in the same detail.
Comment #8
Steven Jones CreditAttribution: Steven Jones commentedComment #9
wamilton CreditAttribution: wamilton commenteddarthsteven helped me out with this during #aegir office hours. I had no @server_master alias, so he had me generate one with
drush provision-save @server_master --context_type='server'
and all was well. Kind of obvious if you think about it, but also an obvious case for throwing a bold, red warning to the tune of
there is something glaringly wrong with what you're doing: you need an alias for @server_master
Letharion: please confirm if doing this solves your issue, and if so I think we can open a new issue for documentation or error messaging, or switch the tags on this ticket?
Comment #10
Steven Jones CreditAttribution: Steven Jones commentedRight, so getting somewhere with this, if I run the following:
Where the web_server alias doesn't exist then this command will eat up all the memory when it enters the infinite loop described in #7.
This is because the '@server_non_existing' alias doesn't exist and it's created, and uses the 'context_type' from the command line, incorrectly assuming that the new server alias is, in fact a platform, which causes the loop.
This is because of the following in
provision_context_factory
:Which unconditionally creates the '@server_non_existing' context with the context type from the command line. It should only do this if the context was the one specified on the command line I think.
Comment #11
Steven Jones CreditAttribution: Steven Jones commentedRight, so here's a patch that essentially throws an error when referencing a context as a service property that doesn't exist. It seems to fix the problem, and gives a helpful error message too.
Comment #12
Steven Jones CreditAttribution: Steven Jones commentedWorked on this a little more, and tested it out, seems to work great!
Fixed in 6.x-2.x and 6.x-1.x
Comment #13
Letharion CreditAttribution: Letharion commentedThanks a lot for looking further into this. What you say is indeed obivous, but since I was following along with mig5's blog post, I simply assumed I had done everything that was necessary. I haven't had the time to look into/test this further, but your fix seems, again, totally obvious.