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....

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
StatusFileSize
new2.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...