Apache + Ubuntu + Varnish painless upgrades
Varnish is a reverse proxy
working with apache, with all traffic go thriugh Varnish cache first
if cache missed, Varnish will be the one to grab content from Apache
It is because Apache ignore file types
For example, deliver a jpg by Apache will load mod_php into RAM
the same applies to CSS and JS files
This will cause massive RAM footage
And Varnish cache help greatly helped these static files with less resources drain
and improve overall performance
My target is install Varnish with minimum downtime
Remember to backup the config files before continue
Install Varnish
curl http://repo.varnish-cache.org/debian/GPG-key.txt | sudo apt-key add -
echo "deb http://repo.varnish-cache.org/ubuntu/ lucid varnish-3.0" | sudo tee -a /etc/apt/sources.list
sudo apt-get update
sudo apt-get install varnish
Default Varnish will connect to localhost port 8080 for Apache
So we open port 8080 on Apache:
sudo vim /etc/apache2/ports.conf
NameVirtualHost *:80
NameVirtualHost *:8080
Listen 80
Listen 8080
To minimize downtime, apache will open both 80 and 8080 for the moment
80 for normal operations
8080 For testing out connection with Varnish
VirtualHost settings
sudo vim /etc/apache2/sites-avaiable/default
<VirtualHost *:80 *:8080>
restart Apache
sudo service apache2 restart
open a browser and go to http://localhost:8080/ test Apache port 8080
Varnish will use 256M RAM by default, change to 64M:
sudo vim /etc/default/varnish
DAEMON_OPTS="-a :6081 \
-T localhost:6082 \
-f /etc/varnish/default.vcl \
-S /etc/varnish/secret \
-s malloc,64m"
sudo /etc/init.d/varnish restart
You can see Varnish use port 6081 as default
open http://localhost:6081/ and test Varnish
Using chrome's network inspector you can see under “Response Header" "Via 1.1 varnish" as identicator
After testing success, time to use Varnish for real thing
Modify Apache:
sudo vim /etc/apache2/ports.conf
#NameVirtualHost *:80
NameVirtualHost *:8080
#Listen 80
Listen 8080
Modify Varnish:
DAEMON_OPTS="-a :80 \
-T localhost:6082 \
-f /etc/varnish/default.vcl \
-S /etc/varnish/secret \
-s malloc,64m"
restart Apache, Varnish at the same time
sudo service apache2 restart;sudo /etc/init.d/varnish restart
Taking up imagefield_crop module as maintainer
So as I had starting my own business, sometimes I am very busy, sometimes nth to do...
So I kindly pickup imagefield_crop module on drupal.org as a maintainer.
As a long time git user, and drupal.org provide great "version control" tab for every module,
maintaining a module is actually not that hard.
You pick reviewed patch and commit, review some patch if there is extra time, reply to support request etc...
Hope to contribute back to the community other than just write blogs and tutorials.
Customize Drupal commerce checkout flow
Commerce is the new born from ubercart developers For Drupal 7.x
Background information
ubercart had long been the e-commerce solution for Drupal 6.x
but it is some what different from other modules, it existed away from Drupal.org (www.ubercart.org)
So Drupal community is trying to merge back to Drupal.org and some conflicts happens
Some developers decided to start from scratch and build a new e-commerce solution for Drupal 7.x
and hence the born of commerce module
Recent updates fo commerce
Commerce module had been around for more than a year already is it is looking even more impressing ever since.
Variations
The "display node" usability problem had been replaced by the concept of "variations"
where you define a product and add "Color variations", "Size variations" etc
they will display as the same product with a dropdown for customers to select
Commerce kickstart
Commerce kickstart is a Drupal "Profile" which bundles lots of extra modules so you can have a store clicks away
Demo products and settings can also be imported so you have real life examples for terminology and setups
You can evaluate the functionality in minutes
and it is a huge step forward for starters to lower the learning curve
Checkout workflow customization
The checkout flow can be customized in "Checkout Settings"
where you can drag and drop different "Panes" to different steps
So if you know how to define "Steps" and "Panes", you can rearrange them right away
Code
The important two functions are: hook_commerce_checkout_page_info() and hook_commerce_checkout_pane_info()
where you define Steps and Panes
<?php
/**
* hook_commerce_checkout_page_info()
*/
function custom_checkout_commerce_checkout_page_info() {
$checkout_pages = array();
$checkout_pages['custom_checkout'] = array(
'title' => t('Custom Step'),
'weight' => 6,
);
return $checkout_pages;
}
/**
* hook_commerce_checkout_pane_info()
* @param string $value [description]
* @return [type] [description]
*/
function custom_checkout_commerce_checkout_pane_info($value='')
{
$checkout_panes = array();
$checkout_panes['custom_checkout'] = array(
'title' => t('Custom Checkout'),
'page' => 'custom_checkout',
'weight' => 2,
'review' => TRUE,
'callbacks' => array(
'checkout_form' => 'custom_checkout_pane_checkout_form',
),
);
return $checkout_panes;
}
?>
Easy easy!
Trying to help imagefield_crop module 7.x-1.x series
http://drupal.org/node/1882804 - coding standard
http://drupal.org/node/1867496 - minor bug
http://drupal.org/node/1415382 - rebuild coruppted patch
Custom Rules action example
The actions being used inside rules and actions in trigger is not the same
But we can still take code example from rules/modules/*.rules.inc
and you will see lots of "core - optional" module rules
Rules action example module:
<?php
/**
* hook_rules_action_info
* @return
* An array of information about the module's provided rules actions.
* The array contains a sub-array for each action, with the action name as
* the key. Actions names may only contain lowercase alpha-numeric characters
* and underscores and should be prefixed with the providing module name.
* Possible attributes for each sub-array are:
* - label: The label of the action. Start capitalized. Required.
* - group: A group for this element, used for grouping the actions in the
* interface. Should start with a capital letter and be translated.
* Required.
* - parameter: (optional) An array describing all parameter of the action
* with the parameter's name as key. Each parameter has to be
* described by a sub-array with possible attributes as described
* afterwards, whereas the name of a parameter needs to be a lowercase,
* valid PHP variable name.
* - provides: (optional) An array describing the variables the action
* provides to the evaluation state with the variable name as key. Each
* variable has to be described by a sub-array with possible attributes as
* described afterwards, whereas the name of a parameter needs to be a
* lowercase, valid PHP variable name.
* - 'named parameter': (optional) If set to TRUE, the arguments will be
* passed as a single array with the parameter names as keys. This emulates
* named parameters in PHP and is in particular useful if the number of
* parameters can vary. Defaults to FALSE.
* - base: (optional) The base for action implementation callbacks to use
* instead of the action's name. Defaults to the action name.
* - callbacks: (optional) An array which allows to set specific function
* callbacks for the action. The default for each callback is the actions
* base appended by '_' and the callback name.
* - 'access callback': (optional) A callback which has to return whether the
* currently logged in user is allowed to configure this action. See
* rules_node_integration_access() for an example callback.
* Each 'parameter' array may contain the following properties:
* - label: The label of the parameter. Start capitalized. Required.
* - type: The rules data type of the parameter, which is to be passed to the
* action. All types declared in hook_rules_data_info() may be specified, as
* well as an array of possible types. Also lists and lists of a given type
* can be specified by using the notating list<integer> as introduced by
* the entity metadata module, see hook_entity_property_info(). The special
* keyword '*' can be used when all types should be allowed. Required.
* - bundles: (optional) An array of bundle names. When the specified type is
* set to a single entity type, this may be used to restrict the allowed
* bundles.
* - description: (optional) If necessary, a further description of the
* parameter.
* - options list: (optional) A callback that returns an array of possible
* values for this parameter. The callback has to return an array as used
* by hook_options_list(). For an example implementation see
* rules_data_action_type_options().
* - save: (optional) If this is set to TRUE, the parameter will be saved by
* rules when the rules evaluation ends. This is only supported for savable
* data types. If the action returns FALSE, saving is skipped.
* - optional: (optional) May be set to TRUE, when the parameter isn't
* required.
* - 'default value': (optional) The value to pass to the action, in case the
* parameter is optional and there is no specified value.
* - 'allow null': (optional) Usually Rules will not pass any NULL values as
* argument, but abort the evaluation if a NULL value is present. If set to
* TRUE, Rules will not abort and pass the NULL value through. Defaults to
* FALSE.
* - restriction: (optional) Restrict how the argument for this parameter may
* be provided. Supported values are 'selector' and 'input'.
* - default mode: (optional) Customize the default mode for providing the
* argument value for a parameter. Supported values are 'selector' and
* 'input'. The default depends on the required data type.
* - sanitize: (optional) Allows parameters of type 'text' to demand an
* already sanitized argument. If enabled, any user specified value won't be
* sanitized itself, but replacements applied by input evaluators are as
* well as values retrieved from selected data sources.
* - translatable: (optional) If set to TRUE, the provided argument value
* of the parameter is translatable via i18n String translation. This is
* applicable for textual parameters only, i.e. parameters of type 'text',
* 'token', 'list<text>' and 'list<token>'. Defaults to FALSE.
* - ui class: (optional) Allows overriding the UI class, which is used to
* generate the configuration UI of a parameter. Defaults to the UI class of
* the specified data type.
* - cleaning callback: (optional) A callback that input evaluators may use
* to clean inserted replacements; e.g. this is used by the token evaluator.
* - wrapped: (optional) Set this to TRUE in case the data should be passed
* wrapped. This only applies to wrapped data types, e.g. entities.
* Each 'provides' array may contain the following properties:
* - label: The label of the variable. Start capitalized. Required.
* - type: The rules data type of the variable. All types declared in
* hook_rules_data_info() may be specified. Types may be parametrized e.g.
* the types node<page> or list<integer> are valid.
* - save: (optional) If this is set to TRUE, the provided variable is saved
* by rules when the rules evaluation ends. Only possible for savable data
* types. Defaults to FALSE.
*/
function rules_example_rules_action_info(){
return array(
'rules_example_extra_node_title' => array(
'group' => t('Example'),
'label' => t('Add prefix to node title'),
'parameter' => array(
//pass in parameters
'node' => array(
'type' => 'node',
'label' => t('Node'),
'description' => t('The node to add the prefix.'),
'save' => TRUE,
),
),
),
);
}
/**
* Rules action implementation
* Key defined in hook_rules_action_info
* @param Object $node node being editted
*/
function rules_example_extra_node_title($node) {
$node->title .= '[Rules action example prefix] ';
node_save($node);
}
?>
It takes time to understand all hook_rules_action_info() parameters
perhaps take some code from rules modules and edit will be easier.