Problem/Motivation

One of the major Aegir WTFs for developers new to the project is the need for 2 projects whenever you want to do anything really interesting. For those of us who have been doing this for a while, it's an annoyance (at least), and complicates the release process, documentation, etc. It's also a stumbling block for newer users trying to deploy contrib components. Without something akin to Drush make for Drush extensions, there's no clean way to keep backend components in sync with their frontend counterparts.

Proposed resolution

Option 1:
Now that we have a drushrc.php for the aegir user, and with Drush's --include option, we may be able to fix that. By merging Provision directly into Hosting, we can do the following:


$options['include'] = array(
  'hosting' => '/var/aegir/hostmaster-7.x-3.x/profiles/hostmaster/modules/hosting',
);

Option 2:
We could also leave provision as a separate repo, and support merging the provision code for contrib modules.

# A list of paths that drush should include even when working outside
# the context of the hostmaster site.
$options['include'] = array (
  'tasks_extra' => '/var/aegir/hostmaster-7.x-3.x/sites/all/modules/hosting_tasks_extra/drush',
);

Remaining tasks

Merge the code for contrib modules.

Here's an example for the hosting_remote_import module.

    $ cd hosting_remote_import 
    $ git remote add remote_import http://git.drupal.org/project/remote_import.git
    $ git fetch remote_import
    warning: no common commits
    [...]
    $ git checkout -b temp-before-merge remote_import/7.x-3.x
    $ mkdir drush
    $ git ls-tree -z --name-only HEAD | xargs -0 -I {} git mv {} drush/
    $ git commit -am"Move file to drush/ folder to prepare for subtree merge."
    $ git checkout 7.x-3.x
    $ git merge -m "Add remote_import under this project, see https://www.drupal.org/node/2300537" temp-before-merge

Some example text for the project page of the old provision component.

<h3>Aegir 7.x-3.x</h3>

The 7.x code moved to <a href="https://www.drupal.org/project/hosting_git">hosting_git repo</a> under the 'drush' directory.

See for more details on how/why: #2300537: Merge Provision extensions into Hosting modules

User interface changes

API changes

Original report by @username

From my local tests, this appears to work within an existing Aegir. Installing an Aegir from scratch using this method might be more complicated, since the drushrc.php file is created when we verify the hostmaster site. That shouldn't be too hard to work around, though. Also, we should still be able to run headless servers, since /var/aegir/.drush/hosting still makes the provision commands available to Drush.

CommentFileSizeAuthor
#9 merge_provision-2300537-9.patch1.97 KBhelmo
Support from Acquia helps fund testing for Drupal Acquia logo

Comments

omega8cc’s picture

I'm afraid this may cause Catch-22 situations. What if the frontend upgrade will fail, and the paths will get out of sync? How will you handle hostmaster (failed) upgrade rollback, if Aegir backend will get 'moved on the fly' along with hostmaster codebase? Sure, having backend and frontend separate makes things a bit harder to manage, but it also makes them far easier to manage when something will fail during upgrade.

While adding drush integration in contrib modules is a standard practice, we shouldn't just look for convenience, because decoupling backend and frontend, so Drush extensions stay in the command line space and frontend in the installation profile space makes a lot of sense and feels logical, at least to me.

ergonlogic’s picture

Right now we don't delete old hostmaster platforms as part of upgrades. As a result, the code that the drushrc is pointing to before and during the upgrade will remain. So if the drushrc is left as-is until after the upgrade we should be alright in the case of a rollback. We currently only re-write the drushrc as part of verifying the hostmaster site, so as to register enabled Hosting features, which this change would replace. This only happens at the very end of an upgrade process at this point.

If writing the drushrc file is interrupted or it is otherwise corrupted, debugging the issue could be more difficult, especially if one didn't know to look for it. We would definitely have to add it to the debugging page in the manual. That said, I've only seen seen such corruption a couple times; both as the result of interrupting the re-writing of a site's settings.php with a server reboot. We could perhaps create a symlink in /var/aegir/.drush to the hosting/provision code. We could even do this temporarily during hostmaster upgrades, as a failsafe.

omega8cc’s picture

Or maybe it could even improve upgrades reliability and ability to rollback? Because right now we replace Provision *in place* first, so we can rollback automatically only the Hostmaster part.

If we merge Provision into Hostmaster (or rather into the Hosting module), we will be able (or rather forced) to rollback both the backend and frontend -- at least in theory, because in practice the rollback is managed by the currently running (which one at which point?) backend, so we can't really switch it while it runs the rollback, but if it will run the rollback, we will end up also with old Provision again, because we will no longer replace it *in place* separately from running Hostmaster upgrade, so it will become a moving target, making rollbacks in fact rather unpredictable, especially on major upgrades.

This would require some intended crash-tests to make sure we will not make things unexpectedly worse if the rollback is needed, I guess, because I'm not sure we could call it a safe rollback any longer.

ergonlogic’s picture

I've merged remote_import into hosting_remote_import using git sub-tree merge, to experiment with how that'd work. I documented the process I used here: http://cgit.drupalcode.org/sandbox-ergonlogic-2307781/tree/README.txt?h=.... It appears to have worked properly as the git history is now combined.

To see how this'd work for Aegir core, I'll create a new branch, merge Provision's history under it and re-factor our post-verify on hostmaster to add the 'include' array to the drushrc.php. With that, we'll be able to start experimenting with upgrade and rollback strategies.

Does that sound like the right approach?

ergonlogic’s picture

As things stand, upgrades to hostmaster will currently happen on the "old" platform and thus also provision code. But I'd suggest adding a hostmaster-upgrade task to the front-end that would build a new platform and (very carefully) re-write the drushrc.php to point to the new provision code prior to migrating the front-end. This should fix some of our oldest issues: #454312: self-provisionning support and #711746: allow upgrade of hostmaster sites from the frontend

helmo’s picture

The subtree merge looks good.
+1 for reducing the number of repositories.

Would it be an idea to call the new dir 'drush'? As they are tipically just drush extensions.

Or would that conflict with the default loading of drush fil?

omega8cc’s picture

This will change the current behaviour where we upgrade Hostmaster using upgraded/replaced first Provision. We will be forced to always use the old backend during the upgrade. This may cause serious problems, because we can't guarantee that different versions of backend and frontend will always cooperate without some inter-connected requirements/assumptions, like, say, compatible Drush version.

What if the upgrade will require sync-ed changes both in the backend and in the fronted, plus there will be Drush version involved which is not compatible with older backend? Are you sure it will work for situations like the upgrade from Aegir 2.x to 3.x, where we not only change the Drupal major version in the frontend, but we also switch Drush version? (yes, I know we discuss changes in 3.x here)

helmo’s picture

The current steps of our upgrade script are:

  1. update drush
  2. update provision
  3. start hosting-migrate task, which builds a new hostmaster platform and migrates the site there.

We currently do nothing with contrib provision extensions...
So an incompatible extension could already spoil the upgrade, and users have to update those themselves.

I would suggest to leave provision itself as a standalone repo, but let extensions have their code in a combined repo.

helmo’s picture

Here's a draft patch to generate an rc like #0 suggested.

It specifically adds '/drush' to the module path... this allows us to have code that should only run in hostmaster context in the module root.

I don't mind calling the dir provision if anyone feels strongly about it, this just seems more generic.

ergonlogic’s picture

+print "# A list of Aegir features and their enabled status.\n";
+print "\$options['hosting_features'] = ". var_export($hosting_features, TRUE) . ";\n\n";

I wonder whether we need this, since $options['exclude'] and $options['include'] ought to provide the exact same information. provision_hosting_feature_enabled(), which should probably be renamed provision_feature_enabled(), should just check these, no?

helmo’s picture

The advantage of keeping $options['hosting_features'] is that it's Aegir specific and not a path but a boolean.

I'm not sure exclude is being used as intended by drush ...

A list of files and directory paths to exclude from consideration when searching for drush commandfiles.", 'example-value' => '/path/dir')

My local dev has e.g. "ssl" in the exclude list, because I don't have the feature enabled. So drush would exclude any code with 'ssl' as the directory/file name. (implementation: function drush_scan_directory).

PS: now that I read it again I doubt that the '/path/dir' example is correct.

helmo’s picture

Issue summary: View changes
helmo’s picture

Issue summary: View changes
Status: Active » Needs review
helmo’s picture

@ergonlogic: the merge method we used has a drawback ....

 git clone --branch 7.x-3.x http://git.drupal.org/sandbox/ergonlogic/2307781.git
 $ git log provision/README.txt
commit 8eadd6443a27f1c41e7c12ccaf26a16e2fef4383
Author: Christopher Gervais <chris@ergonlogic.com>
Date:   Tue Jul 22 20:21:19 2014 +0000

    Add remote_import under this project.

It only shows the single merge commit, even if you add the --follow flag.

In http://stackoverflow.com/a/20974621 I found an other way:

    $ cd hosting_remote_import 
    $ git remote add remote_import http://git.drupal.org/project/remote_import.git
    $ git fetch remote_import
    warning: no common commits
    [...]
    $ git checkout -b temp-before-merge remote_import/7.x-3.x
    $ mkdir drush
    $ git ls-tree -z --name-only HEAD | xargs -0 -I {} git mv {} drush/
    $ git commit -am"Move file to drush/ folder to prepare for subtree merge."
    $ git checkout 7.x-3.x
    $ git merge -m "Add remote_import under this project, see https://www.drupal.org/node/2300537" temp-before-merge
ergonlogic’s picture

Status: Needs review » Needs work

So that preserves the history better then? I'm ok with calling the directory drush/, btw.

Have you tested installing Aegir with this change? Presumably, we'll need to change the procedure somewhat, since we aren't just dropping provision/ into /var/aegir/.drush. Do we need to run drush make first, to build the hostmaster platform, and then write an initial .drushrc with "$options['include'] = /var/aegir/hostmaster-7.x-3.x/profiles/modules/hosting/drush"?

helmo’s picture

Issue summary: View changes

Please note that this currently is only about provision extensions ... not provision itself.

I've already committed the provision change in #13, so jenkins has installed with it a few times. However as the tests don't use any provision extensions ... we have no real coverage yet.

helmo’s picture

I've now pushed this for hosting_git/provision_git: #2364135: 7.x code moved to hosting_git repo

helmo’s picture

Issue summary: View changes

Also merged provision_logs and hosting_logs: #2410347: Aegir 3.x compatibility

helmo’s picture

Status: Needs work » Fixed

Also did this for hosting_site_backup_manager in #2022809: Prepare to add this module to Aegir distribution

I see no reason to keep this issue open...

Status: Fixed » Closed (fixed)

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