Date post: | 15-Jan-2015 |
Category: |
Technology |
Upload: | fluxsauce |
View: | 2,743 times |
Download: | 1 times |
Optimize Site Deploymentswith Drush
Friday, 2011.10.14Jon Peck, Owner, FluxSauce.com
Audience: Intermediate.
Revision 1. Licensed under a Creative Commons Attribution-NonCommercial-ShareAlike 3.0 Unported License.
Who am I?
• Jon Peck • Founded web application
development firm FluxSauce • Zend Certified PHP Engineer• Web development since 1998• Used Drupal for the last three
years• Worked at ProZ.com for four
Overview
• Why should you script site deployments?• What are drush and drush make, and how can you use
them?• What is features, and does fit your needs?• What are some recommended site deployment strategies? • How can you develop your own strategy?
Why should I script site deployments?
• Reliability• Track changes over time
(including blame) • Support multiple tiers • Manage and optimize
your operations
"Aaahhh!!!", CC BY 2.0 by Evil Erin @ flickr
What is drush?
drush is a command line shell and scripting interface for Drupal.
Site installation status report using drush.
What can you use drush for?
• Manage modules • Manage users• Execute Drupal commands• Manipulate and extract site variables• Execute MySQL queries using Drupal config
Downloading and installing devel in 1.359 seconds.
What is drush make?
A standard recipe for
downloading everything you need for a site
installation."Mom's new pumpkin pie recipe with gingersnaps", CC BY-SA 2.0
by Ann Larie Valentine @ flickr
Scripting a deployment - simplest
1. Get the files (drush make) drush -y make --no-patch-txt "PATH/drush.make" FOLDER
2. Install and configure (drush) cd FOLDERdrush -y site-install --config="PATH/drushrc.ENV.php"
3. Enable modules (drush) drush -y en \ admin_menu\ ctools \...
Scripting a deployment - flexible
/projects/NAME/config - stored in repository • drush.*.php• drush.make• config.ini• install.sh • setup.sh• rebuild.sh
Drupal Deployment Skeleton (MIT license)• http://goo.gl/09JkE• https://github.com/fluxsauce/DrupalDeploySkel
What is features?
What can you use features for?
• Within your site• Using drush
What are features' limitations?
• Imperfect exports• No site variables
without third-party modules
• No theme, block support
• No logic• If you can't do it in
the GUI... "40+296 Hello?", CC BY 2.0 by Bark @ flickr
Use a custom module for complete control.
With hook_install(), you can programmatically: • Create users, roles, permissions• Create and hide blocks• Create content (nodes)• Import content types / CCK • Create vocabularies and terms• Set site variables (drush vget)
Custom module gotchas
• Clear all caches after installing your custom module drush cc all
• Custom modules used like this need a user associated drush -u 1 -y en custom_module
• Changes and updates need to go in hook_update_N within your module
Deployment strategies
• Store everything in a versioning system • Always backup both your scripts and database
first!• Tiered development strategy • Unique database credentials for each tier• When in doubt, rebuild on dev first• Instead of repeating steps, do it in code• Document the process
How can I do this?
• Get drush• Get drush_make• Define your needs.• Build and document your module toolbox• Start small, then scale up
Questions?
"Question mark in Esbjerg", CC BY-SA 2.0 by Alexander Drachmann @ flickr
Thanks!drush • http://drupal.org/project/drush
drush_make • http://drupal.org/project/drush_make
Drupal Deployment Skeleton (DDS)• http://goo.gl/09JkE (gitHub)
Drush Make Generator• http://drushmake.me
permissions_api • http://drupal.org/project/permissions_api
Traditional Development... Practice for Software Development• http://dltj.org/article/software-development-practice/
Contact• [email protected]• @FluxSauce• http://fluxsauce.com
Appendix - code examples
Use these snippets to programmatically create:• Creating a user• Roles and permissions• Manipulating blocks• Create content (nodes)• CCK Content Types• Vocabulary• Terms• Site variables• imagecache presets
Creating a user
$roles = user_roles();
$user_data = array( 'name' => 'steve', 'pass' => 'steve', 'mail' => '[email protected]', 'init' => '[email protected]', 'status' => 1, 'roles' => array(array_search('Manager', $roles) => 1),);
$user = user_save('', $user_data);
Roles and permissions
Requires permissions_api module // Administrative role$result = permissions_create_role('Manager');// Permissions$permissions_grant = array( 'access administration menu', 'administer nodes',... 'administer taxonomy',);permissions_grant_permissions('Manager', $permissions_grant);
Manipulating blocks
// Disable "User login"$sql_query = 'UPDATE {blocks} ';$sql_query .= 'SET status = 0 ';$sql_query .= 'WHERE module = "user" ';$sql_query .= 'AND region = "left" ';$sql_query .= 'AND status = 1 ';$sql_query .= 'AND delta = 0 ';$sql_query .= 'AND theme = "fourseasons" ';$sql_query .= 'LIMIT 1 '; $result = db_query($sql_query);
Create content (nodes)if (!function_exists('node_object_prepare')) { include_once(drupal_get_path('module', 'node') . '/node.pages.inc');}
// Home$node = new stdClass();$node->type = 'page';node_object_prepare($node);$node->title = 'An excellent title';$node->body = '<p>Hello, world!</p>';$node->teaser = node_teaser($node->body);$node->uid = 1;$node->format = 2; // Full HTML$node->path = 'home';$node->pathauto_perform_alias = FALSE;node_save($node);
CCK Content Types
Export the content type using the GUI and paste the content into a file in module/content_types/
$filename = drupal_get_path('module', $module_name) . '/content_types/' . $content_type . '.cck';// Build form state$form_state = array( 'values' => array( 'type_name' => '<create>', 'macro' => implode('', file($filename)), ),;drupal_execute('content_copy_import_form', $form_state);
Vocabularymodule_load_include('module', 'taxonomy', 'taxonomy');$t = get_t();
// Create the vocabulary programmatically.$vocab = array( 'name' => 'Medium', 'description' => $t('Storage and/or transmission tools used to store and deliver information or data.'), 'help' => '', 'relations' => 0, 'hierarchy' => 0, 'multiple' => 0, 'required' => 1, 'tags' => 0, 'module' => 'taxonomy', 'weight' => 0, 'nodes' => array('portfolio_item' => 1),);
taxonomy_save_vocabulary($vocab);
Terms// Get the vid of the vocabulary we just created.$vid = db_result(db_query('SELECT vid FROM {vocabulary} WHERE name = "%s"', 'Medium'));
// Create the term programmatically.$terms = array( 'Videos' => 'Full-motion visual presentations of information.',);foreach ($terms as $name => $definition) { $term = array( 'name' => $name, 'vid' => $vid, 'description' => $t($definition), ); taxonomy_save_term($term);}
Site variables
drush vget --pipe site_frontpage $variables['site_frontpage'] = 'node/1';
Then in code...
$variables = array();// Front page$variables['site_frontpage'] = 'node/1';
foreach ($variables as $name => $value) { variable_set($name, $value);}
imagecache presetsExternal file: $_presets = array();$_presets['galleria_gallery'] = array (...);return $_presets;
Module:
/** * Implementation of hook_imagecache_default_presets(). */function MODULE_imagecache_default_presets() { global $_presets; $module_name = 'MODULE'; $filename = drupal_get_path('module', $module_name) . '/defaults/imagecache_presets.inc.php'; include_once($filename); return $_presets;}