Current version of drush_make appears to depend on PHP's curl libraries, and if not found, it borks.

per our aegir install script which downloads drush_make and then executes a make of the frontend

==> Creating basic directory structure
==> Drush found in /var/aegir/drush/drush.php, good
==> Drush seems to be functionning properly
==> Drush make already seems to be installed
==> Provision already seems to be installed
==> Deploying hostmaster application
The external command could not be executed due to an application     [error]
error.
Drush command could not be completed.                                [error]
Output from failed command :                                         [error]

Fatal error: Call to undefined function curl_init() in
/var/aegir/.drush/drush_make/drush_make.utilities.inc on line 354

An error occurred at function : drush_provision_hostmaster_make      [error]

of course an apt-get install php5-curl fixes this no problem on Debian. We could add this as a dependency but dww/Vertice have pointed out that it should try a number of options first before failing, so some extra conditionals may be required (haven't actually looked at the code for a while).

CommentFileSizeAuthor
#9 drush_make-647546-9.patch1.54 KBmfer
#1 drush_make-647546.patch1.05 KBmfer

Comments

mfer’s picture

Status: Active » Needs review
StatusFileSize
new1.05 KB

In DrushMakeDownload_Get::downloadFile we are already setting up wget or curl as shell requirements to download files. The attached patch uses wget or curl in place of libcurl in php.

dmitrig01’s picture

$ wget -qO- /Users/dmitri/basic.make
$ curl /Users/dmitri/basic.make 
curl: (3) <url> malformed

This won't work for us ATM.

dmitrig01’s picture

Status: Needs review » Needs work
mfer’s picture

Status: Needs work » Needs review

The current implementation will fail the test in #2 as well. If you inject curl_error to see the error in the current drush_make_get_remote_file() you would see the error on a local file to be "<url> malformed".

The current setup sets 3 ops we should set as well so I don't think this is ready to be committed. Conceptually, what's wrong with this?

dww’s picture

Status: Needs review » Needs work

If PHP supports curl, that's faster and safer than invoking curl or wget via the shell. We should really try all of the below, in order, and only give up if none of them worked:

  1. PHP natively supports cURL (e.g. if (function_exists('curl_init')))
  2. PHP is configured to allow URLs in fopen -- it's insecure, but if someone's configured that way, we might as well just use file_get_contents() with the URL as the filename.
  3. drush_shell_exec('wget')
  4. drush_shell_exec('curl')
  5. drush_shell_exec('lynx') ;) (ok, just kidding)

But seriously, we should test for #1 and #2 and use one of those before we fall back to fork/exec for #3 and #4.

adrian’s picture

amen, it should be as dww said.

also, dww.. keep in mind that the makefile parameter can also be a url

ie: drush make mydomain/profiles/drupalprofile.make

mfer’s picture

Assigned: Unassigned » mfer

/me raises hand to code this.

dww’s picture

Thanks, mfer! ;)

/me goes back to dealing with #649254: version_extra can't just be string sorted -- ugh

mfer’s picture

Status: Needs work » Needs review
StatusFileSize
new1.54 KB

Uses the order listed in #5 and sets an error if none of them are available.

Anonymous’s picture

In my testing of the patch in #9, I expected to see the final error 'Unable to download remote file. No download services supported.' thrown but I didn't.

On my system there was no php5-curl, curl, or wget, and I saw this:

Executing: wget                                                         [notice]
'http://ftp.drupal.org/files/projects/drupal-6.14.tar.gz' -O
'/tmp/drush_make_tmp_1259979208/drupal-6.14.tar.gz' [0.211 sec]
  sh: wget: command not found
Executing: curl -o                                                      [notice]
'/tmp/drush_make_tmp_1259979208/drupal-6.14.tar.gz'
'http://ftp.drupal.org/files/projects/drupal-6.14.tar.gz' [0.216 sec]
  sh: curl: command not found
Unable to download /tmp/drush_make_tmp_1259979208/drupal-6.14.tar.gz [error]
from http://ftp.drupal.org/files/projects/drupal-6.14.tar.gz. [0.22
sec]

However, problematically, it plowed on and checked out the relevant install profile from CVS (ManagingNews) and recursively started executing its make file, of which each dependency failed in the same way. I expected it to immediately die after attempting to fetch core.

With curl or wget installed, the build would complete after one of those tools worked. With only php5-curl installed, somehow it still failed and instead moved on to trying wget or curl - so somehow ignored or didn't pass the check for function_exists('curl_init') (though I verified manually that the function did exist, so not sure why this is failing now where it was the *only* option that used to work)

dww’s picture

Status: Needs review » Needs work

Sounds like this "needs work" then. ;)

Anonymous’s picture

Sorry thought I marked it as such :)

dmitrig01’s picture

I'd like to be able to specify local sources. However, I can't wget a local file.

anarcat’s picture

I must say that to its defense, the patch actually works for systems with wget and no php5-curl.

The problem that needs fixing is then twofold:

* make sure we cleanly abort when everything is missing
* fix php5-curl only environment (which should be fairly rare, to be honest, but still need to work if we want to benefit from it)

Thanks for the patch mfer!

anarcat’s picture

Status: Needs work » Reviewed & tested by the community

thinking more about this: the other thing is this may be a better situation than *without* the patch so I would suggest going ahead and committing the patch, because the two issues noticed by mig5 above are present in the current code too. It's just that there are still other occurences in the code that do not use the common download stub:

anarcat@marvin$ grep wget *
drush_make.download.inc:      // Download the project -- try wget, fall back to curl.
drush_make.download.inc:      if (drush_get_context('DRUSH_SIMULATE') || drush_shell_exec('wget %s -O %s', $url, $filename) || drush_shell_exec('curl -o %s %s', $filename, $url)) {
drush_make.project.inc:        if (!drush_shell_exec('wget %s', $url)) {
drush_make.utilities.inc:  elseif (drush_shell_exec('wget -qO- %s', $url) || drush_shell_exec('curl --silent %s', $url)) {

So in a sense, the patch is complete and fixes the problem (that we depend on curl libraries). The reverse problem exists though: we don't use them everywhere (but I consider that a separate issue).

The issue about the remote failures are another thing altogether: failure handling is non-existent in drush_make_get_remote_file(), with or without the patch, and we have a similar situation elsewhere in the code that uses wget and friends.

Finally, I wonder if that function is properly named. get_remote_file() is really get_remote_file_contents() and a new function get_remote_file() should be written to factor out the wget/curl calls used above.

Again, that should be treated separately and the patch should go in, marking RTBC.

grendzy’s picture

Status: Reviewed & tested by the community » Needs work

There's a report of this not working with github, because it doesn't use the content-disposition header: #654798: Curl is stupid

grendzy’s picture

Status: Needs work » Reviewed & tested by the community

Hm, we already have a pure-php http library: http://api.drupal.org/api/function/drupal_http_request/6
Maybe this should be incorporated into drush core? See also #581348: have drush make use the pm primitives

grendzy’s picture

Status: Reviewed & tested by the community » Needs work

ack, didn't mean to reset status.

adrian’s picture

Status: Needs work » Fixed

@grendzy - the redirect issue is separate from this one.

i agree with anarcat that this patch fixes the existing issue.

committed

Status: Fixed » Closed (fixed)

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