1

At our university we have dev/test/live versions of our sites at urls like

  • dev.example.foo.edu
  • test.example.foo.edu
  • live.example.foo.edu (the real live url is example.foo.edu)

There are certain Drupal site variables (values in the variables table) that need to change depending on the environment (dev, test, live) where the site is running.

The first time the site is migrated to the live environment certain site variables need to magically change from their "dev" values to their "live" values.

After that initial migration we will periodically load the live database into the dev and test sites to update their content. When this happens I want certain site variables to change to their "dev" values.

I don't want the site builder to have to do anything. I want the variables to simply change to the correct values.

It's okay if the site admin wants to manually override these variables. They shouldn't have to, but there could be a need for this...

I mainly need a Drupal 7 solution--bonus if it works with Drupal 6.

Possible solutions:

Does a module exist that will do this?

I haven't found one. I've looked at

Use hook_update_N (http://api.drupal.org/api/drupal/modules%21system%21system.api.php/function/hook_update_N/7)

  • This doesn't meet the requirement that the site builder doesn't have to do anything. They would have to copy paste a update_71234() in some install file. They would also have to remember to run update.php in various situations.

Write a custom module?

This works:

/**
 * Implementation of hook_cron().
 */
function ucb_varenv_cron() {
    global $base_url;


    //if (variable_get('ucb_varenv', FALSE) === FALSE) {
        $parts = explode('.', $base_url);
        $vars = ucb_varenv_vars();
        $p1 = str_replace('http://', '', $parts[0]);
        while (list($k, $v) = each($vars[$p1])) {
            variable_set($k, $v);
        }        
        //variable_set('ucb_varenv', TRUE);
    //}


}

function ucb_varenv_vars() {
    $vars = array(
      'dev' => array(
        'cas_server' => "TEST2.example.com",
    ),
       'live' => array(
         'cas_server' => "auth.example.edu",
    ),
    );
    return $vars;
}

Hook cron seems like a clumsy approach. The commented ucb_varenv code was from and experiment where this would run one time only at hook_boot()--but that seemed like a bad idea.

The more I think about this, I wonder if there is some way to leverage strongarm to do what I need.

1
  • could just NOT including the variable table in your backup work? – Jimajamma Feb 29 '12 at 4:53
2

Assuming I've parsed this all out correctly, you should be able to achieve what you're looking for using Rules. You'll need to install core's PHP Formatter for its integration with Rules to call variable_set() as an action, though beyond that it's pretty straightforward:

  • Event: When cron maintenance tasks are performed
  • Condition: Data comparison (Parameter: Data to compare: [site:url], Data value: http://example.foo.edu/)
  • Action: Execute custom PHP code (Code: variable_set('cas_server', 'auth.example.edu');)

Mind the trailing slash in the condition URLs - it's the path to the home page, not the domain name, so the slash is required.

Of course, you could bind it to whatever event you feel is most appropriate, and duplicate the same rule for your dev and test instances with the appropriate CAS servers (going this route would also mean you could export this with Features). I've tested the above reaction rule, and it seems to work on my own D7 instance (with the URL condition set accordingly):

# After cron
[dmw@seraph aqueduct]$ drush vget cas
cas_server: "auth.example.edu"

It's been a while since I've used the old Rules, though I don't see why something similar can't work for D6.

1
  • Rules! Of course! I have this working. We will be able to trigger cron when we sync the db, so this is a decent solution. – Brian Wood Mar 1 '12 at 14:56
0

Thanks again for the Rules idea.

In the end, it was better to code conditional logic into settings.php.

I was thinking that the settings.php approach wouldn't be good because I'd loose my code when I upgrade Drupal. But since settings.php is not actually part of a Drupal release, as long as you set up your version control correctly, you can carry this code forward.

This way we don't have to worry about cron failing to run. We also don't have to maintain these rules in the future.

3
  • Clever; I hadn't considered this approach! We typically don't revision settings.php for security purposes (storing passwords and environment-specific config in VCS runs counter to best-practice). I'm interested to hear if you've found a way to mitigate this, perhaps using something like metaltoad.com/blog/…. Either way, I'm glad you found something that works for you. :> – David Watson Mar 6 '12 at 17:49
  • In my case the version control setup is being done by gotpantheon.com. The db user and pass is in my settings.php. The Pantheon guys (joshk and davidstrauss) are pretty good, so I'm sure they've considered security. – Brian Wood Mar 6 '12 at 21:28
  • Before moving to Pantheon I ran sites using Aegir. Aegir was storing the db credentials in the vhost using SetEnv dbpass foo; SetEnv dbuser bar and then evaluating those variable in settings.php. Interesting approach...not sure how much security it buys... – Brian Wood Mar 6 '12 at 21:31
0

I changed my mind again. I'm doing it in a module. See the README for why: https://github.com/ucbdrupal/ucb_envconf/tree/7.x-1.x

1
  • 1
    The link is broken and this answer doesn't give the "why". – Hugo Oct 28 '14 at 8:44

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.