PHP Fatal error: Class 'Provision_Service' not found in /var/aegir/.drush/provision_tasks_extra/http_basic_auth/http_basic_auth.drush.inc on line 27

Our manual installation method places provision in ~/.drush, while debian has it in /usr/share/drush/commands/.

The order in which drush extensions are loaded must be at play here.

Moving provision to /usr/share/drush/commands/ fixed this issue.

Not sure yet what the nicest fix is....

Support from Acquia helps fund testing for Drupal Acquia logo

Comments

m.stenta’s picture

We're experiencing the same issue in the Puppet Aegir project: #2078019: Aegir::extras does not work with Aegir::dev

m.stenta’s picture

Started a branch to work on it here: https://github.com/mstenta/puppet-aegir/tree/dev/2078019

Sorry... wrong issue. :-/

ergonlogic’s picture

Maybe we want something more like this:

function http_basic_auth_drush_init(){
  static $loaded = FALSE;
  if (!$loaded) {
    $loaded = TRUE;
    $list = drush_commandfile_list();
    $provision_dir = dirname($list['provision']);
    include_once($provision_dir . '/provision.inc');
    include_once($provision_dir . '/provision.service.inc');
  }
}
m.stenta’s picture

Component: Documentation » Code

Hmm this is a bit trickier. I tried the code in #3 above, but unfortunately, PHP doesn't even get to that point, because it declares a class farther down in the same file that extends the Provision_Service class, which doesn't exist.

I tried moving the code to the very top of the file (provision_tasks_extra/http_basic_auth/http_basic_auth.drush.inc), but then the drush_commandfile_list() returns an empty list, because Drush is in the process of building that list when the code gets loaded. And since provision_tasks_extra is being loaded before provision, the provision include files are not going to be there anyway.

This seems to really just be a race condition between the two extensions. Does Drush have any mechanism to control the order in which extensions are loaded?

m.stenta’s picture

Title: Provision installed in .drush » Race condition between Provision and Provision tasks extra

Oops, meant to change the title, not the tags...

ergonlogic’s picture

See: http://community.aegirproject.org/upgrading/path#Class_auto-loading

Basically, in Aegir 2, we'd normally put that class in Provision/Service/http_basic_auth.php, and then register it with the autoloader. That way it isn't parsed too early.

m.stenta’s picture

I read through some of the code in the Provision extension itself, and tried to set up this extension to autoload the Provision_Service_http_basic_auth class, but I'm still having trouble.

Attached is a patch that takes a first stab at it. Can anyone see what's wrong with it?

This is the error that I'm getting:

PHP Fatal error:  Uncaught exception 'ReflectionException' with message 'Class Provision_Service_http_basic_auth does not exist' in /var/aegir/.drush/provision/Provision/Context/server.php:31
Stack trace:
#0 /var/aegir/.drush/provision/Provision/Context/server.php(31): ReflectionClass->__construct('Provision_Servi...')
#1 /var/aegir/.drush/provision/provision.drush.inc(97): Provision_Context_server::option_documentation()
#2 /usr/share/php/drush/includes/command.inc(967): provision_drush_command()
#3 /usr/share/php/drush/includes/command.inc(1120): drush_get_commands()
#4 /usr/share/php/drush/includes/drush.inc(1201): drush_parse_command()
#5 /usr/share/php/drush/drush.php(59): drush_preflight_command_dispatch()
#6 /usr/share/php/drush/drush.php(16): drush_main()
#7 {main}
  thrown in /var/aegir/.drush/provision/Provision/Context/server.php on line 31

Fatal error: Uncaught exception 'ReflectionException' with message 'Class Provision_Service_http_basic_auth does not exist' in /var/aegir/.drush/provision/Provision/Context/server.php:31
Stack trace:
#0 /var/aegir/.drush/provision/Provision/Context/server.php(31): ReflectionClass->__construct('Provision_Servi...')
#1 /var/aegir/.drush/provision/provision.drush.inc(97): Provision_Context_server::option_documentation()
#2 /usr/share/php/drush/includes/command.inc(967): provision_drush_command()
#3 /usr/share/php/drush/includes/command.inc(1120): drush_get_commands()
#4 /usr/share/php/drush/includes/drush.inc(1201): drush_parse_command()
#5 /usr/share/php/drush/drush.php(59): drush_preflight_command_dispatch()
#6 /usr/share/php/drush/drush.php(16): drush_main()
#7 {main}
  thrown in /var/aegir/.drush/provision/Provision/Context/server.php on line 31
Drush command terminated abnormally due to an unrecoverable error.                                                                        [error]
Error: Uncaught exception 'ReflectionException' with message 'Class Provision_Service_http_basic_auth does not exist' in
/var/aegir/.drush/provision/Provision/Context/server.php:31
Stack trace:
#0 /var/aegir/.drush/provision/Provision/Context/server.php(31): ReflectionClass->__construct('Provision_Servi...')
#1 /var/aegir/.drush/provision/provision.drush.inc(97): Provision_Context_server::option_documentation()
#2 /usr/share/php/drush/includes/command.inc(967): provision_drush_command()
#3 /usr/share/php/drush/includes/command.inc(1120): drush_get_commands()
#4 /usr/share/php/drush/includes/drush.inc(1201): drush_parse_command()
#5 /usr/share/php/drush/drush.php(59): drush_preflight_command_dispatch()
#6 /usr/share/php/drush/drush.php(16): drush_main()
#7 {main}
  thrown in /var/aegir/.drush/provision/Provision/Context/server.php, line 31
m.stenta’s picture

Here's the patch (and again... it doesn't work... just a first attempt). :-)

m.stenta’s picture

Status: Active » Needs review
FileSize
2.51 KB

Figured it out...

Symfony's class loader function decides that the class must be located in:

"/var/aegir/.drush/provision_tasks_extra/http_basic_auth/Provision/Service/http/basic/auth.php"

It puts an underscore in place of each of the underlines in http_basic_auth.

So, if we put the class in there, it works!

Attached is a patch that does that, and fixes this issue.

However, this doesn't seem like the "right" way to do it... because it sort of implies that the Provision_Service_http_basic_auth class inherits from the Provision_Service_http_basic class (which does not exist), which inherits from the Provision_Service_http class (which DOES exist). Will this cause any issues in the long run?

ergonlogic’s picture

Status: Needs review » Fixed

Fixed in 3246a697150eb

Status: Fixed » Closed (fixed)

Automatically closed -- issue fixed for 2 weeks with no activity.

helmo’s picture

I think provisionacl has a similar issue: #1984098: Aegir 2.x compatibility And so maybe other contribs...