More than one MySQL server on VPS with only one IP requires non-standard ports and it would be nice to have $db_port here - something like this in provision_drupal_settings.tpl.php:

  $databases['default']['default'] = array(
    'driver' => '<?php print $db_type; ?>',
    'database' => '<?php print $db_name; ?>',
    'username' => '<?php print $db_user; ?>',
    'password' => '<?php print $db_passwd; ?>',
    'host' => '<?php print $db_host ?>',
    'port' => '<?php print $db_port ?>',
  );
  $db_url = '<?php print "$db_type://$db_user:$db_passwd@$db_host:$db_port/$db_name"; ?>';

Comments

anarcat’s picture

Priority: Normal » Minor
Status: Active » Needs work

That will not be enough: you'll need to overhaul the frontend (which means the db_server node form and the db_server table schema) so that this can be changed by the user. I'm marking this as minor since it's fairly uncommon to see a mysqld on a different port (why would you do that anyways?).

omega8cc’s picture

I had to use MySQL 5.1 on a VPS with stable Debian, so with installed MySQL 5.0.
It was VPS with only one IP and without any chance for second IP (Gandi.net case).
Binding one MySQL to public IP and second to localhost was not an option since
remote replication was used.

Trying to find all places in a code where it should be changed, I have found a few
where $port variable was ready to define and use, but there is more where it is
not used (also in parsing template config.php).

This is not a rocket science issue and of course too specific to be a problem. I had a chance
to better learn some details in provision module.

It seems, for example, when you have MySQL listening on a public IP and not localhost,
but both Aegir and MySQL will be on the same IP, Provision will create users in MySQL
with privileges to access from localhost and not public IP. Kind of bug, it seems,
but will report it when confirm if this still exist in 6.x (had this issue under 5.x)

~Grace

anarcat’s picture

Feel free to provide a patch for this functionality.

(as for the grant issue, the behavior likely didn't change in the d6 upgrade, so may as well open a bug about this if you think it's one)

starbow’s picture

Has there been any progress on this? UC Berkeley hosts db accounts separate ports, one per account. So, for me it is a major issue :)

starbow’s picture

Status: Needs work » Needs review

Ok, to fix this, in provision_mysql.drush.inc, in the function provision_mysql_drush_init()

replace:
drush_set_default('master_db_host', $db['host']);
drush_set_default('db_host', $db['host']);

with:
$host = $db['host'];
if ($db['port']) {
$host .= ':'. $db['port'];
}
drush_set_default('master_db_host', $host);
drush_set_default('db_host', $host);

starbow’s picture

Of course, it is not that simple.
The next bit I found is in provision_drupal_settings.tpl.php.
The db_host needs to be urldecoded in the $db_url, or the colon gets munged.
Here is one way to do it:

   $db_host = urldecode($_SERVER['db_host']);

  $databases['default']['default'] = array(
    'driver' => urldecode($_SERVER['db_type']),
    'database' => urldecode($_SERVER['db_name']),
    'username' => urldecode($_SERVER['db_user']),
    'password' => urldecode($_SERVER['db_passwd']),
    'host' => $db_host,
  );
  $db_url = "<?php print strtr("%db_type://%db_user:%db_passwd@%db_host/%db_name", arr\
ay(
    '%db_type' => '$_SERVER[db_type]',
    '%db_user' => '$_SERVER[db_user]',
    '%db_passwd' => '$_SERVER[db_passwd]',
    '%db_host' => '$db_host',
    '%db_name' => '$_SERVER[db_name]')); ?>";

More as I figure it out.

starbow’s picture

Ok, this is getting a little ugly. Here is the code to get backups working with the port in the host, from db_server/backup.provision.inc/drush_provision_mysql_pre_provision_backup

  $db_host = explode(':', drush_get_option('db_host'));
  $db_port = isset($db_host[1]) ? $db_host[1] : '3306'; // Default mysqld port.
  $mycnf = sprintf('[client]
host=%s
port=%s
user=%s
password=%s
', $db_host[0], $db_port, drush_get_option('db_user'), drush_get_option('db_passwd'));

And, of course, we need to do almost the same thing in db_server/provision_mysql.drush.inc/_provision_mysql_import_dump

  $db_host = explode(':', $db_host);
  $db_port = isset($db_host[1]) ? $db_host[1] : '3306'; // Default mysqld port.
  $mycnf = sprintf('[client]
host=%s
port=%s
user=%s
password=%s
', $db_host[0], $db_port, $db_user, $db_passwd);
starbow’s picture

And, of course, to clone you need backup and import, so
platform/drupal/import_6.inc

if ($parts = @parse_url($db_url)) {
  $db_host = urldecode($parts['host']);
  if ($parts['port']) {
    $db_host .= ':'. urldecode($parts['port']);
  }
  drush_set_option('db_host', $db_host, 'site');
Anonymous’s picture

Are you able to supply a proper patch so that we can test it?

Cheers!

starbow’s picture

Status: Needs review » Needs work

Just to be clear, I am not actually recommending this path. It would be better to break the db port out into it's own UI field and cached option. This is the quick and dirty approach, and it has only one advantage, and that is that it seems to be working.

adrian’s picture

This will help with that :
#836136: Simplify ports support.

adrian’s picture

This is partially implemented in HEAD now.

The front end is there, all that's remaining is adding the value to the mysql db credentials.

adrian’s picture

Version: 6.x-0.2 »
Status: Needs work » Fixed

Committed to HEAD.

you configure it on the server, and the configs will generate for it

omega8cc’s picture

Status: Fixed » Needs work

I tested it now with current head.

1. The verify task fails after I changed port to 3308 at node/2/edit (expected).
2. Then I changed the port in the MySQL server config and restarted it.
3. Now went to settings.php for hostmaster and changed port to 3308 manually.
4. Then re-verified the server and all platforms.
5. Now tried to re-verify the d6 site and the task failed.

It seems it doesn't rewrite settings.php properly (because it doesn't rewrite also drushrc.php) with the new port.

omega8cc’s picture

From IRC #aegir on freenode:

[02:10] omega8cc: Vertice: should I use something like --master_db='mysql://$USER:$PASS@$AEGIR_HOST:$DB_PORT' on hostmaster-install?
[02:45] Vertice: that's not how it works on install omega8cc
[02:45] Vertice: you need to pass --db_port sepearate
[02:45] omega8cc: --db_port=3308
[02:45] omega8cc: yeah, just trying that

So, by design it is expected to work only on install, with added --db_port= as an argument.

However it doesn't work for me.

The command sh install.sh.txt aegir.example.com --http_service_type='nginx' --db_port='3308' -d fails with:

Provision PHP configuration path /var/aegir/config/includes is writable. [1.16 sec, 6.11 MB]            [message]
Template loaded: /var/aegir/.drush/provision/platform/global_settings.tpl.php [1.16 sec, 6.11 MB]        [notice]
Generated config Global settings.php file [1.16 sec, 6.12 MB]                                           [message]
SQLSTATE[HY000] [2003] Can't connect to MySQL server on 'aegir.example.com' (111) [1.16 sec, 6.12 MB]    [error]
Drush command could not be completed. [1.16 sec, 6.12 MB]                                                 [error]
Output from failed command :                                                                              [error]
 
Fatal error: Call to a member function quote() on a non-object in
/var/aegir/.drush/provision/db/db.drush.inc on line 315
 [1.16 sec, 6.12 MB]
An error occurred at function : drush_provision_hostmaster_install [1.16 sec, 6.05 MB]                    [error]
Command dispatch complete [1.16 sec, 6.02 MB]                                                            [notice]
Peak memory usage was 6.15 MB [1.16 sec, 6.02 MB]                                                        [memory]
aegir@v246a:~$ 

The database server listens of course on the port 3308.

bwood’s picture

I took a quick look at this in alpha12 a few days ago and was going down this path:

$ diff  .drush/provision/install.hostmaster.inc .drush_orig/provision/install.hostmaster.inc
25,26d24
<   $aegir_db_host = drush_get_option('aegir_db_host', 'localhost', 'options');
<   $aegir_db_port = drush_get_option('aegir_db_port', '3306', 'options');
29c27
<   $data['master_db'] = sprintf("mysql://%s:%s@%s:%d",$aegir_db_user, $aegir_db_pass, $aegir_db_host, $aegir_db_port);
---
>   $data['master_db'] = sprintf("mysql://%s:%s@%s",$aegir_db_user, $aegir_db_pass, $aegir_host);

The reason I added 'aegir_db_host' is that without that install.hostmaster, seems to be assuming that mysql will be running locally on the webserver, which is not the case for me.

$data['master_db'] is the db url that the frontend (hostmaster) server uses (I think).

If I want to use --backend-only, does the webserver I'm setting up need $data['master_db']? (I think that $data['master_db'] might need to go in one of the drush alias files created on the backend (webserver).)

Does the backend (webserver) need to connect to the frontend (hostmaster)'s database? (I think that it probably does not need to...)

I'll be coming back to this early next week.

(I'm trying to step through the new code using eclipse + xdebug working on my ubuntu 10.04 laptop. I've got it working basically, but if there are any notes on the best way to debug drush/provision that you can point me too, let me know!)

John_Buehrer’s picture

Any luck? I also got this far in the code before seeing your post, but I still get the dreaded "Fatal error: Call to a member function quote() on a non-object", meaning the database connection didn't work.

In my use case, I only need to change the port, not the host, as MAMP picks its own port number and I don't want to change it for several reasons. I'm surprised that an assumed port number would be hardwired into an install script, especially since "db_port" already appears deep down in some included code.

(Based on the error message, it looks like there are two errors here:
1. the wrong sort of mysql db connection parameters.
2. the script itself is not recovering from error #1.

It seems the script has support to show a diagnostic about the database problem, but that logic is wrong and gives the "object-oriented" error. Can that be fixed by someone familiar with it? Then the rest of us can fix our own database connections as we see fit.)

Steven Jones’s picture

Version: » 6.x-1.x-dev
Status: Needs work » Fixed

I'm fairly certain that Aegir now supports this.

Status: Fixed » Closed (fixed)

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

cweagans’s picture

  • Commit 955d3c4 on debian, dev-dns, dev-koumbit, dev-log_directory, dev-migrate_aliases, dev-multiserver-install, dev-simplerinstaller, prod-koumbit, dev-ssl-ip-allocation-refactor, dev-1205458-move_sites_out_of_platforms, 7.x-3.x, dev-subdir-multiserver, 6.x-2.x-backports, dev-helmo-3.x by adrian:
    Support db ports other than the default (3306). We now always specify...